diff --git a/.github/workflows/apt-deps.txt b/.github/workflows/apt-deps.txt index 2a12d368c..c06068ab4 100644 --- a/.github/workflows/apt-deps.txt +++ b/.github/workflows/apt-deps.txt @@ -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 diff --git a/.github/workflows/generate-builds.yml b/.github/workflows/generate-builds.yml index c4523b917..5c1930ede 100644 --- a/.github/workflows/generate-builds.yml +++ b/.github/workflows/generate-builds.yml @@ -13,42 +13,60 @@ jobs: with: submodules: true - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.11 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 if: ${{ !vars.LINUX_RUNNER }} run: | sudo apt-get update 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 if: ${{ !vars.LINUX_RUNNER }} run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - wget https://www.libsdl.org/release/SDL2-2.26.1.tar.gz - tar -xzf SDL2-2.26.1.tar.gz - cd SDL2-2.26.1 - ./configure + if [ ! -d "SDL2-2.28.5" ]; then + wget https://www.libsdl.org/release/SDL2-2.28.5.tar.gz + tar -xzf SDL2-2.28.5.tar.gz + fi + cd SDL2-2.28.5 + ./configure --enable-hidapi-libusb make -j 10 sudo make install sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/ - - name: Install latest SDL_net - if: ${{ !vars.LINUX_RUNNER }} + - name: Install latest tinyxml2 run: | + sudo apt-get remove libtinyxml2-dev 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 - tar -xzf SDL2_net-2.2.0.tar.gz - cd SDL2_net-2.2.0 - ./configure - make -j 10 + 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 - sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/ - name: Generate soh.otr 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 cmake --build build-cmake --config Release --target GenerateSohOtr - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: soh.otr path: soh.otr @@ -61,9 +79,12 @@ jobs: with: submodules: true - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.11 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 if: ${{ !vars.MAC_RUNNER }} run: | @@ -85,24 +106,24 @@ jobs: if [ -d /opt/local/ ]; then echo "MacPorts already installed" else - wget https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-12-Monterey.pkg - sudo installer -pkg ./MacPorts-2.7.2-12-Monterey.pkg -target / + wget https://github.com/macports/macports-base/releases/download/v2.9.3/MacPorts-2.9.3-12-Monterey.pkg + sudo installer -pkg ./MacPorts-2.9.3-12-Monterey.pkg -target / fi echo "/opt/local/bin:/opt/local/sbin" >> $GITHUB_PATH - name: Install dependencies if: ${{ !vars.MAC_RUNNER }} run: | - brew uninstall --ignore-dependencies libpng + brew uninstall --ignore-dependencies libpng libzip sudo port install $(cat .github/workflows/macports-deps.txt) brew install ninja - name: Download soh.otr - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: soh.otr - name: Build SoH run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" + cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DBUILD_REMOTE_CONTROL=1 cmake --build build-cmake --config Release --parallel 10 mv soh.otr build-cmake/soh (cd build-cmake && cpack) @@ -110,7 +131,7 @@ jobs: mv _packages/*.dmg SoH.dmg mv README.md readme.txt - name: Upload build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: soh-mac path: | @@ -139,39 +160,101 @@ jobs: sudo apt-get update sudo apt-get install -y $(cat .github/workflows/apt-deps.txt) - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 + uses: hendrikmuhs/ccache-action@v1.2.11 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 if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }} run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - wget https://www.libsdl.org/release/SDL2-2.26.1.tar.gz - tar -xzf SDL2-2.26.1.tar.gz - cd SDL2-2.26.1 - ./configure + if [ ! -d "SDL2-2.28.5" ]; then + wget https://www.libsdl.org/release/SDL2-2.28.5.tar.gz + tar -xzf SDL2-2.28.5.tar.gz + fi + cd SDL2-2.28.5 + ./configure --enable-hidapi-libusb make -j 10 sudo make install sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/ + - name: Install latest libzip + if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) }} + run: | + sudo apt-get remove libzip-dev zipcmp zipmerge ziptool + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + if [ ! -d "libzip-1.10.1" ]; then + wget https://libzip.org/download/libzip-1.10.1.tar.gz + tar -xzvf libzip-1.10.1.tar.gz + fi + cd libzip-1.10.1 + mkdir build + cd build + cmake .. + make + sudo make install + - name: Install latest nlohmann + if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) }} + run: | + sudo apt-get remove nlohmann-json3-dev + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + if [ ! -d "json-3.11.3" ]; then + wget https://github.com/nlohmann/json/archive/refs/tags/v3.11.3.tar.gz + tar -xzvf v3.11.3.tar.gz + fi + cd json-3.11.3 + mkdir build + cd build + cmake .. + make + sudo make install + - name: Install latest tinyxml2 + if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }} + run: | + sudo apt-get remove libtinyxml2-dev + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + 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 if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }} run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - 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 + if [ ! -d "SDL2_net-2.2.0" ]; then + 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 + fi cd SDL2_net-2.2.0 ./configure make -j 10 sudo make install sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/ - name: Download soh.otr - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: soh.otr - name: Build SoH run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release + 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 (cd build-cmake && cpack -G External) @@ -181,92 +264,12 @@ jobs: CC: gcc-${{ matrix.gcc }} CXX: g++-${{ matrix.gcc }} - name: Upload build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: soh-linux-${{ matrix.archive-suffix }} path: | soh.appimage 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: needs: generate-soh-otr runs-on: ${{ (vars.WINDOWS_RUNNER && fromJSON(vars.WINDOWS_RUNNER)) || 'windows-latest' }} @@ -280,16 +283,33 @@ jobs: with: submodules: true - name: ccache - uses: dcvz/ccache-action@27b9f33213c0079872f064f6b6ba0233dfa16ba2 + uses: hendrikmuhs/ccache-action@v1.2.11 with: - key: ${{ runner.os }}-ccache - - uses: ilammy/msvc-dev-cmd@v1 + variant: sccache + 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 env: - VCPKG_ROOT: D:/a/vcpkg + VCPKG_ROOT: ${{github.workspace}}/vcpkg run: | 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 mkdir soh-windows @@ -302,12 +322,12 @@ jobs: mv ./build-windows/gamecontrollerdb.txt ./soh-windows/gamecontrollerdb.txt mv ./x64/Release/assets ./soh-windows - name: Download soh.otr - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: soh.otr path: soh-windows - name: Upload build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: soh-windows path: soh-windows diff --git a/.github/workflows/macports-deps.txt b/.github/workflows/macports-deps.txt index 02c11cc68..d15039078 100644 --- a/.github/workflows/macports-deps.txt +++ b/.github/workflows/macports-deps.txt @@ -1 +1 @@ -libsdl2 +universal libpng +universal glew +universal +libsdl2 +universal libsdl2_net +universal libpng +universal glew +universal libzip +universal nlohmann-json +universal tinyxml2 +universal \ No newline at end of file diff --git a/.github/workflows/test-builds-on-distros.yml b/.github/workflows/test-builds-on-distros.yml new file mode 100644 index 000000000..36bbc67a9 --- /dev/null +++ b/.github/workflows/test-builds-on-distros.yml @@ -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 }} diff --git a/.gitignore b/.gitignore index 3848a1bd8..09f29ab48 100644 --- a/.gitignore +++ b/.gitignore @@ -448,5 +448,5 @@ _packages */extract_assets_cmake* /build* -soh/build.c +soh/src/boot/build.c soh/properties.h diff --git a/CMake/DefaultCXX.cmake b/CMake/DefaultCXX.cmake index e87721511..6ed89d9e0 100644 --- a/CMake/DefaultCXX.cmake +++ b/CMake/DefaultCXX.cmake @@ -8,5 +8,9 @@ if(MSVC) set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc") - set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi") + 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") + endif() endif() \ No newline at end of file diff --git a/CMake/lus-cvars.cmake b/CMake/lus-cvars.cmake new file mode 100644 index 000000000..e7376cfe2 --- /dev/null +++ b/CMake/lus-cvars.cmake @@ -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") \ No newline at end of file diff --git a/CMake/soh-cvars.cmake b/CMake/soh-cvars.cmake new file mode 100644 index 000000000..e5ff8a384 --- /dev/null +++ b/CMake/soh-cvars.cmake @@ -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}" +) \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c8644af4..891d6ad26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") 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_TEAM "github.com/harbourmasters" CACHE STRING "") @@ -13,20 +15,18 @@ set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) add_compile_options($<$:/MP>) add_compile_options($<$:/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") -include(CMake/automate-vcpkg.cmake) + include(CMake/automate-vcpkg.cmake) -set(VCPKG_TRIPLET x64-windows-static) -set(VCPKG_TARGET_TRIPLET x64-windows-static) + set(VCPKG_TRIPLET x64-windows-static) + set(VCPKG_TARGET_TRIPLET x64-windows-static) -vcpkg_bootstrap() -vcpkg_install_packages(zlib bzip2 libpng sdl2 sdl2-net glew glfw3) + vcpkg_bootstrap() + 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() ################################################################################ diff --git a/OTRExporter b/OTRExporter index 04b85b95f..3cea9ee7c 160000 --- a/OTRExporter +++ b/OTRExporter @@ -1 +1 @@ -Subproject commit 04b85b95fab07a394b62dcd28a502a3040f08e0c +Subproject commit 3cea9ee7c017d842aa4d9ceeb8d3ffbf29c6effb diff --git a/README.md b/README.md index ef96bd8e4..ad80f7f2f 100644 --- a/README.md +++ b/README.md @@ -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) * [macOS](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-mac.zip) * [Linux (performance)](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-linux-performance.zip) _(requires `glibc 2.35` or newer, but will be more performant than the compatibility build.)_ -* [Linux (compatibility)](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-linux-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) * [Wii U](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-wiiu.zip) diff --git a/ZAPDTR b/ZAPDTR index eff290361..f38a9c92e 160000 --- a/ZAPDTR +++ b/ZAPDTR @@ -1 +1 @@ -Subproject commit eff29036118349e142ee8efca80fd975a2a2b6ff +Subproject commit f38a9c92eb99368c0607acf356d5651ebdc96f51 diff --git a/docs/BUILDING.md b/docs/BUILDING.md index 56ff9718f..6c9222242 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -84,41 +84,66 @@ cd "build/x64" ``` ## 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 -# Clone the repo +# Clone the repo and enter the directory git clone https://github.com/HarbourMasters/Shipwright.git cd Shipwright -# Clone the submodule libultraship + +# Clone the submodules git submodule update --init -# Copy the baserom to the OTRExporter folder -cp OTRExporter + # 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) -# 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 cmake --build build-cmake # --config Release (if you're packaging) # 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) - -# 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: ```bash # Go to build folder @@ -129,6 +154,20 @@ cpack -G ZIP 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 OTRExporter +cmake --build build-cmake --target ExtractAssetHeaders +``` + ## macOS Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake` (can be installed via homebrew, macports, etc) diff --git a/docs/MODDING.md b/docs/MODDING.md index ebd7cf071..75293b64a 100644 --- a/docs/MODDING.md +++ b/docs/MODDING.md @@ -188,4 +188,4 @@ Assuming all went well, you can now push your changes to your fork with the foll ```bash git push origin -``` \ No newline at end of file +``` diff --git a/libultraship b/libultraship index 96c8a8929..7d71a2906 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 96c8a8929c18c1bffd7d92a35a589f74cf16fc59 +Subproject commit 7d71a290657a2d3b09a83e8b33025e807f4fb38e diff --git a/scripts/linux/appimage/soh.sh.in b/scripts/linux/appimage/soh.sh.in index bfc3cfec6..71121a5ff 100644 --- a/scripts/linux/appimage/soh.sh.in +++ b/scripts/linux/appimage/soh.sh.in @@ -21,12 +21,17 @@ fi while [[ (! -e "$SHIP_HOME"/oot.otr) || (! -e "$SHIP_HOME"/oot-mq.otr) ]]; do for romfile in "$SHIP_HOME"/*.*64 do - if [[ -e $romfile ]]; then + if [[ -e "$romfile" ]] || [[ -L "$romfile" ]]; then 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" mkdir -p "$ASSETDIR"/tmp - ln -s "$romfile" "$ASSETDIR"/tmp/rom.z64 + if [[ -e "$romfile" ]]; then + 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" ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }') diff --git a/soh/CMake/DefaultCXX.cmake b/soh/CMake/DefaultCXX.cmake index 7b052b9cc..032326a13 100644 --- a/soh/CMake/DefaultCXX.cmake +++ b/soh/CMake/DefaultCXX.cmake @@ -8,5 +8,9 @@ if(MSVC) set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc") - set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi") + 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") + endif() endif() \ No newline at end of file diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 5c239ae13..f8ee476b8 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -92,10 +92,6 @@ if (NOT TARGET libultraship) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libultraship ${CMAKE_BINARY_DIR}/libultraship) endif() -if (NOT TARGET ZAPDUtils) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils) -endif() - if (NOT TARGET ZAPDLib) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD) endif() @@ -105,8 +101,8 @@ set(PROJECT_NAME soh) ################################################################################ # 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/properties.h.in ${CMAKE_CURRENT_SOURCE_DIR}/properties.h @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}/properties.h.in ${CMAKE_CURRENT_SOURCE_DIR}/properties.h @ONLY) set(Header_Files "resource.h") source_group("headers" FILES ${Header_Files}) @@ -154,7 +150,7 @@ list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/gfx.*") # 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.ccpak") -if (!BUILD_CROWD_CONTROL) +if (!BUILD_REMOTE_CONTROL) list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/crowd-control/*") endif() @@ -217,8 +213,6 @@ source_group("soh\\resource\\importer\\scenecommand" REGULAR_EXPRESSION "soh/res # src (decomp) {{{ 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(FILTER src__ EXCLUDE REGEX "src/dmadata/*") 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") 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\\buffers" REGULAR_EXPRESSION "src/buffers/*") source_group("src\\code" REGULAR_EXPRESSION "src/code/*") @@ -354,9 +347,15 @@ endif() find_package(SDL2) set(SDL2-INCLUDE ${SDL2_INCLUDE_DIRS}) -if (BUILD_CROWD_CONTROL) +if (BUILD_REMOTE_CONTROL) find_package(SDL2_net) - set(SDL2-NET-INCLUDE ${SDL_NET_INCLUDE_DIRS}) + + 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}) + endif() endif() 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/libultraship/Lib/ ${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 - ${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils ${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type ${SDL2-INCLUDE} ${SDL2-NET-INCLUDE} @@ -408,13 +405,13 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") "$<$:" "NDEBUG" ">" - "$<$:ENABLE_CROWD_CONTROL>" + "$<$:ENABLE_REMOTE_CONTROL>" "INCLUDE_GAME_PRINTF;" - "ENABLE_CROWD_CONTROL;" "UNICODE;" "_UNICODE" STORMLIB_NO_AUTO_LINK "_CRT_SECURE_NO_WARNINGS;" + NOMINMAX ) elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") target_compile_definitions(${PROJECT_NAME} PRIVATE @@ -432,6 +429,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") "UNICODE;" "_UNICODE" STORMLIB_NO_AUTO_LINK + NOMINMAX ) endif() elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS") @@ -455,7 +453,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang") "$<$:" "NDEBUG" ">" - "$<$:ENABLE_CROWD_CONTROL>" + "$<$:ENABLE_REMOTE_CONTROL>" "SPDLOG_ACTIVE_LEVEL=0;" "_CONSOLE;" "_CRT_SECURE_NO_WARNINGS;" @@ -624,6 +622,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") -Wno-parentheses -Wno-narrowing -Wno-missing-braces + -Wno-int-conversion + -Wno-implicit-int $<$: -Werror-implicit-function-declaration -Wno-incompatible-pointer-types @@ -643,15 +643,6 @@ endif() ################################################################################ # Pre build events ################################################################################ -if (CMAKE_SYSTEM_NAME STREQUAL "Windows") - add_custom_command_if( - TARGET ${PROJECT_NAME} - PRE_BUILD - COMMANDS - COMMAND $ copy /b $build.c +,, - ) -endif() - if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS") add_custom_command( TARGET ${PROJECT_NAME} @@ -670,7 +661,6 @@ endif() # Dependencies ################################################################################ add_dependencies(${PROJECT_NAME} - ZAPDUtils libultraship ) 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") set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" - "ZAPDUtils;" "ZAPDLib;" "glu32;" "SDL2::SDL2;" "SDL2::SDL2main;" - "$<$:SDL2_net::SDL2_net-static>" + "$<$:SDL2_net::SDL2_net-static>" "glfw;" "winmm;" "imm32;" @@ -699,7 +688,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32") set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" - "ZAPDUtils;" "ZAPDLib;" "glu32;" "SDL2::SDL2;" @@ -717,7 +705,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch") find_package(Threads REQUIRED) set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" - "ZAPDUtils;" SDL2::SDL2 -lglad Threads::Threads @@ -739,10 +726,9 @@ else() find_package(Threads REQUIRED) set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" - "ZAPDUtils;" "ZAPDLib;" SDL2::SDL2 - "$<$:SDL2_net::SDL2_net>" + "$<$:SDL2_net::SDL2_net>" ${CMAKE_DL_LIBS} Threads::Threads ) diff --git a/soh/SHIPOFHARKINIAN.manifest b/soh/SHIPOFHARKINIAN.manifest index 80d9f6036..6f47a937f 100644 --- a/soh/SHIPOFHARKINIAN.manifest +++ b/soh/SHIPOFHARKINIAN.manifest @@ -28,4 +28,10 @@ + + + true/pm + permonitorv2,permonitor + + diff --git a/soh/assets/.gitignore b/soh/assets/.gitignore index dce395e6f..d75078bf1 100644 --- a/soh/assets/.gitignore +++ b/soh/assets/.gitignore @@ -4,4 +4,4 @@ *.cfg *.vtx.inc *.dlist.inc -*.txt \ No newline at end of file +!*.png diff --git a/soh/assets/custom/accessibility/texts/scenes_fra.json b/soh/assets/custom/accessibility/texts/scenes_fra.json index fa36c8840..3f73410e7 100644 --- a/soh/assets/custom/accessibility/texts/scenes_fra.json +++ b/soh/assets/custom/accessibility/texts/scenes_fra.json @@ -1,5 +1,5 @@ { - "0": "Abre Mojo", + "0": "Arbre Mojo", "1": "Caverne Dodongo", "2": "Ventre de Jabu-Jabu", "3": "Temple de la Forêt", @@ -58,9 +58,9 @@ "56": "Laboratoire du Lac", "57": "", // Tente du Marathonien (No title card) "58": "Cabane du fossoyeur", - "59": "Fountaine Royale des Fées", - "60": "Fountaine des Fées", - "61": "Fountaine Royale des Fées", + "59": "Fontaine Royale des Fées", + "60": "Fontaine des Fées", + "61": "Fontaine Royale des Fées", "62": "", // Grottes (No title card) "63": "", // Tombe 1 (No title card) "64": "", // Tombe 2 (No title card) @@ -109,4 +109,4 @@ "107": "", "108": "", // Debug: SRD Room (No title card) "109": "" // Debug: Treasure Chest Warp (No title card) -} \ No newline at end of file +} diff --git a/soh/assets/custom/textures/buttons/ABtn.png b/soh/assets/custom/textures/buttons/ABtn.png index c1b06571c..031924cb9 100644 Binary files a/soh/assets/custom/textures/buttons/ABtn.png and b/soh/assets/custom/textures/buttons/ABtn.png differ diff --git a/soh/assets/custom/textures/buttons/ABtnOutline.png b/soh/assets/custom/textures/buttons/ABtnOutline.png new file mode 100644 index 000000000..b3c9d3aab Binary files /dev/null and b/soh/assets/custom/textures/buttons/ABtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/AnalogStick.png b/soh/assets/custom/textures/buttons/AnalogStick.png new file mode 100644 index 000000000..d3fec7d01 Binary files /dev/null and b/soh/assets/custom/textures/buttons/AnalogStick.png differ diff --git a/soh/assets/custom/textures/buttons/AnalogStickOutline.png b/soh/assets/custom/textures/buttons/AnalogStickOutline.png new file mode 100644 index 000000000..e4d8d7190 Binary files /dev/null and b/soh/assets/custom/textures/buttons/AnalogStickOutline.png differ diff --git a/soh/assets/custom/textures/buttons/BBtn.png b/soh/assets/custom/textures/buttons/BBtn.png index 99b1197c9..8e2fbb54b 100644 Binary files a/soh/assets/custom/textures/buttons/BBtn.png and b/soh/assets/custom/textures/buttons/BBtn.png differ diff --git a/soh/assets/custom/textures/buttons/BBtnOutline.png b/soh/assets/custom/textures/buttons/BBtnOutline.png new file mode 100644 index 000000000..fab802f3b Binary files /dev/null and b/soh/assets/custom/textures/buttons/BBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CDown.png b/soh/assets/custom/textures/buttons/CDown.png index 741188eaf..f30cec2b3 100644 Binary files a/soh/assets/custom/textures/buttons/CDown.png and b/soh/assets/custom/textures/buttons/CDown.png differ diff --git a/soh/assets/custom/textures/buttons/CDownOutline.png b/soh/assets/custom/textures/buttons/CDownOutline.png new file mode 100644 index 000000000..9324c282d Binary files /dev/null and b/soh/assets/custom/textures/buttons/CDownOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CLeft.png b/soh/assets/custom/textures/buttons/CLeft.png index 5e26a2067..43b04412f 100644 Binary files a/soh/assets/custom/textures/buttons/CLeft.png and b/soh/assets/custom/textures/buttons/CLeft.png differ diff --git a/soh/assets/custom/textures/buttons/CLeftOutline.png b/soh/assets/custom/textures/buttons/CLeftOutline.png new file mode 100644 index 000000000..c0d48f659 Binary files /dev/null and b/soh/assets/custom/textures/buttons/CLeftOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CRight.png b/soh/assets/custom/textures/buttons/CRight.png index 9e6180639..c2d1afabf 100644 Binary files a/soh/assets/custom/textures/buttons/CRight.png and b/soh/assets/custom/textures/buttons/CRight.png differ diff --git a/soh/assets/custom/textures/buttons/CRightOutline.png b/soh/assets/custom/textures/buttons/CRightOutline.png new file mode 100644 index 000000000..d450084ea Binary files /dev/null and b/soh/assets/custom/textures/buttons/CRightOutline.png differ diff --git a/soh/assets/custom/textures/buttons/CUp.png b/soh/assets/custom/textures/buttons/CUp.png index 6c0e29d2d..aca464728 100644 Binary files a/soh/assets/custom/textures/buttons/CUp.png and b/soh/assets/custom/textures/buttons/CUp.png differ diff --git a/soh/assets/custom/textures/buttons/CUpOutline.png b/soh/assets/custom/textures/buttons/CUpOutline.png new file mode 100644 index 000000000..b21cd3ae9 Binary files /dev/null and b/soh/assets/custom/textures/buttons/CUpOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadDown.png b/soh/assets/custom/textures/buttons/DPadDown.png new file mode 100644 index 000000000..cec0af1e5 Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadDown.png differ diff --git a/soh/assets/custom/textures/buttons/DPadDownOutline.png b/soh/assets/custom/textures/buttons/DPadDownOutline.png new file mode 100644 index 000000000..e8dca39b6 Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadDownOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadLeft.png b/soh/assets/custom/textures/buttons/DPadLeft.png new file mode 100644 index 000000000..2a4a09b79 Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadLeft.png differ diff --git a/soh/assets/custom/textures/buttons/DPadLeftOutline.png b/soh/assets/custom/textures/buttons/DPadLeftOutline.png new file mode 100644 index 000000000..ba3dbf4e8 Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadLeftOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadRight.png b/soh/assets/custom/textures/buttons/DPadRight.png new file mode 100644 index 000000000..e7854a219 Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadRight.png differ diff --git a/soh/assets/custom/textures/buttons/DPadRightOutline.png b/soh/assets/custom/textures/buttons/DPadRightOutline.png new file mode 100644 index 000000000..f6b4764c6 Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadRightOutline.png differ diff --git a/soh/assets/custom/textures/buttons/DPadUp.png b/soh/assets/custom/textures/buttons/DPadUp.png new file mode 100644 index 000000000..8d70d96da Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadUp.png differ diff --git a/soh/assets/custom/textures/buttons/DPadUpOutline.png b/soh/assets/custom/textures/buttons/DPadUpOutline.png new file mode 100644 index 000000000..8ad2d7959 Binary files /dev/null and b/soh/assets/custom/textures/buttons/DPadUpOutline.png differ diff --git a/soh/assets/custom/textures/buttons/InputViewerBackground.png b/soh/assets/custom/textures/buttons/InputViewerBackground.png new file mode 100644 index 000000000..091d686c0 Binary files /dev/null and b/soh/assets/custom/textures/buttons/InputViewerBackground.png differ diff --git a/soh/assets/custom/textures/buttons/LBtn.png b/soh/assets/custom/textures/buttons/LBtn.png index 2e0a8f00c..351ea383a 100644 Binary files a/soh/assets/custom/textures/buttons/LBtn.png and b/soh/assets/custom/textures/buttons/LBtn.png differ diff --git a/soh/assets/custom/textures/buttons/LBtnOutline.png b/soh/assets/custom/textures/buttons/LBtnOutline.png new file mode 100644 index 000000000..10cca9c8f Binary files /dev/null and b/soh/assets/custom/textures/buttons/LBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/RBtn.png b/soh/assets/custom/textures/buttons/RBtn.png index c255643c3..ecb96bd6c 100644 Binary files a/soh/assets/custom/textures/buttons/RBtn.png and b/soh/assets/custom/textures/buttons/RBtn.png differ diff --git a/soh/assets/custom/textures/buttons/RBtnOutline.png b/soh/assets/custom/textures/buttons/RBtnOutline.png new file mode 100644 index 000000000..afeba32eb Binary files /dev/null and b/soh/assets/custom/textures/buttons/RBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/RightStick.png b/soh/assets/custom/textures/buttons/RightStick.png new file mode 100644 index 000000000..6b8490aaf Binary files /dev/null and b/soh/assets/custom/textures/buttons/RightStick.png differ diff --git a/soh/assets/custom/textures/buttons/RightStickOutline.png b/soh/assets/custom/textures/buttons/RightStickOutline.png new file mode 100644 index 000000000..8fbd54fcc Binary files /dev/null and b/soh/assets/custom/textures/buttons/RightStickOutline.png differ diff --git a/soh/assets/custom/textures/buttons/StartBtn.png b/soh/assets/custom/textures/buttons/StartBtn.png index c3e08dc36..ec85f2619 100644 Binary files a/soh/assets/custom/textures/buttons/StartBtn.png and b/soh/assets/custom/textures/buttons/StartBtn.png differ diff --git a/soh/assets/custom/textures/buttons/StartBtnOutline.png b/soh/assets/custom/textures/buttons/StartBtnOutline.png new file mode 100644 index 000000000..a7902edbd Binary files /dev/null and b/soh/assets/custom/textures/buttons/StartBtnOutline.png differ diff --git a/soh/assets/custom/textures/buttons/ZBtn.png b/soh/assets/custom/textures/buttons/ZBtn.png index def8d9a6d..4fee52d57 100644 Binary files a/soh/assets/custom/textures/buttons/ZBtn.png and b/soh/assets/custom/textures/buttons/ZBtn.png differ diff --git a/soh/assets/custom/textures/buttons/ZBtnOutline.png b/soh/assets/custom/textures/buttons/ZBtnOutline.png new file mode 100644 index 000000000..5832ed339 Binary files /dev/null and b/soh/assets/custom/textures/buttons/ZBtnOutline.png differ diff --git a/soh/assets/sources/triforce-hunt/paths.txt b/soh/assets/sources/triforce-hunt/paths.txt new file mode 100644 index 000000000..40b397186 --- /dev/null +++ b/soh/assets/sources/triforce-hunt/paths.txt @@ -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 diff --git a/soh/assets/sources/triforce-hunt/textures/noise_tex.png b/soh/assets/sources/triforce-hunt/textures/noise_tex.png new file mode 100644 index 000000000..e4329f5d1 Binary files /dev/null and b/soh/assets/sources/triforce-hunt/textures/noise_tex.png differ diff --git a/soh/assets/sources/triforce-hunt/triforce_complete.blend b/soh/assets/sources/triforce-hunt/triforce_complete.blend new file mode 100644 index 000000000..e5e3fbd13 Binary files /dev/null and b/soh/assets/sources/triforce-hunt/triforce_complete.blend differ diff --git a/soh/assets/sources/triforce-hunt/triforce_shard_0.blend b/soh/assets/sources/triforce-hunt/triforce_shard_0.blend new file mode 100644 index 000000000..cd13e8859 Binary files /dev/null and b/soh/assets/sources/triforce-hunt/triforce_shard_0.blend differ diff --git a/soh/assets/sources/triforce-hunt/triforce_shard_1.blend b/soh/assets/sources/triforce-hunt/triforce_shard_1.blend new file mode 100644 index 000000000..aca2f0600 Binary files /dev/null and b/soh/assets/sources/triforce-hunt/triforce_shard_1.blend differ diff --git a/soh/assets/sources/triforce-hunt/triforce_shard_2.blend b/soh/assets/sources/triforce-hunt/triforce_shard_2.blend new file mode 100644 index 000000000..0ead9e5a6 Binary files /dev/null and b/soh/assets/sources/triforce-hunt/triforce_shard_2.blend differ diff --git a/soh/include/functions.h b/soh/include/functions.h index 3a1aa8ae2..08179b341 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -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 func_80095974(GraphicsContext* gfxCtx); 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, - u16 tlutCount, f32 frameX, f32 frameY); +void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode, + u16 tlutCount, f32 offsetX, f32 offsetY); void func_80096FD4(PlayState* play, Room* room); u32 func_80096FE8(PlayState* play, RoomContext* roomCtx); 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); s32 Scene_ExecuteCommands(PlayState* play, SceneCmd* sceneCmd); void TransitionActor_InitContext(GameState* state, TransitionActorContext* transiActorCtx); -void func_800994A0(PlayState* play); +void Scene_SetTransitionForNextEntrance(PlayState* play); void Scene_Draw(PlayState* play); void SkelAnime_DrawLod(PlayState* play, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, s32 dListIndex); @@ -1537,7 +1537,7 @@ void KaleidoScopeCall_Draw(PlayState* play); void func_800BC490(PlayState* play, s16 point); s32 func_800BC56C(PlayState* play, s16 arg1); 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); void Play_Destroy(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, f32 translateZ); uintptr_t SysUcode_GetUCodeBoot(void); -uintptr_t SysUcode_GetUCodeBootSize(void); -uintptr_t SysUcode_GetUCode(void); +size_t SysUcode_GetUCodeBootSize(void); +uint32_t SysUcode_GetUCode(void); uintptr_t SysUcode_GetUCodeData(void); void func_800D2E30(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 func_800FA3DC(void); u8 func_800FAD34(void); -void func_800FADF8(void); +void Audio_ResetActiveSequences(void); void func_800FAEB4(void); void GfxPrint_SetColor(GfxPrint* this, u32 r, u32 g, u32 b, u32 a); 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_GetRelY(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); f32 Math_FTanF(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_RandoRestoreSwordless(void); +//Pause Warp +void PauseWarp_HandleSelection(); +void PauseWarp_Execute(); + // #endregion #ifdef __cplusplus diff --git a/soh/include/regs.h b/soh/include/regs.h index 74b8a43df..cfbd1ae20 100644 --- a/soh/include/regs.h +++ b/soh/include/regs.h @@ -86,6 +86,8 @@ #define R_ITEM_ICON_X(i) ZREG(82 + i) #define R_ITEM_ICON_Y(i) ZREG(86 + 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_SPEED CREG(19) #define R_A_BTN_Y XREG(16) diff --git a/soh/include/tables/entrance_table.h b/soh/include/tables/entrance_table.h new file mode 100644 index 000000000..fc7cc00b2 --- /dev/null +++ b/soh/include/tables/entrance_table.h @@ -0,0 +1,1934 @@ +/** + * Entrance Table + * + * DEFINE_ENTRANCE should be used for entrances + * - Argument 1: Enum value for this entrance + * - Argument 2: Scene this entrance belongs to + * - Argument 3: Spawn number for this entrance + * - Argument 4: Toggle if bgm should continue during the transition using this entrance (true or false) + * NOTE: For non-cutscene layers, this field is only read from the `SCENE_LAYER_CHILD_DAY` layer. + * Meaning, the setting only matters for the first entry within a group of layers and that + * setting will apply to the other 3 non-cutscene layers. + * - Argument 5: Toggle if a title card should display when using this entrance (true or false) + * - Argument 6: Transition type when entering using this entrance (second half of a scene transition) + * - Argument 7: Transition type when exiting using this entrance (first half of a scene transition) + * + * WARNING: Due to how the entrance system is implemented, entries within the same group of scene layers are NOT shiftable. + * Groups of scene layers are indicated by line breaks. + * + * Only the first entrance within a group of layers is expected to be referenced in code. + * The entrance system will apply the offset on its own to access the correct entrance for a given layer. + */ +/* 0x000 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x001 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0_1, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x002 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0_2, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x003 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0_3, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x004 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x005 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0_1, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x006 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0_2, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x007 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0_3, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x008 */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x009 */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0_1, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x00A */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0_2, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x00B */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0_3, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x00C */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x00D */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0_1, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x00E */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0_2, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x00F */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0_3, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x010 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x011 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0_1, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x012 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0_2, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x013 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0_3, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x014 */ DEFINE_ENTRANCE(ENTR_UNUSED_6E, SCENE_UNUSED_6E, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x015 */ DEFINE_ENTRANCE(ENTR_UNUSED_6E_1, SCENE_UNUSED_6E, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x016 */ DEFINE_ENTRANCE(ENTR_UNUSED_6E_2, SCENE_UNUSED_6E, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x017 */ DEFINE_ENTRANCE(ENTR_UNUSED_6E_3, SCENE_UNUSED_6E, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x018 */ DEFINE_ENTRANCE(ENTR_SASATEST_0, SCENE_SASATEST, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x019 */ DEFINE_ENTRANCE(ENTR_SASATEST_0_1, SCENE_SASATEST, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x01A */ DEFINE_ENTRANCE(ENTR_SASATEST_0_2, SCENE_SASATEST, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x01B */ DEFINE_ENTRANCE(ENTR_SASATEST_0_3, SCENE_SASATEST, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x01C */ DEFINE_ENTRANCE(ENTR_SYOTES_0, SCENE_SYOTES, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x01D */ DEFINE_ENTRANCE(ENTR_SYOTES_0_1, SCENE_SYOTES, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x01E */ DEFINE_ENTRANCE(ENTR_SYOTES_0_2, SCENE_SYOTES, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x01F */ DEFINE_ENTRANCE(ENTR_SYOTES_0_3, SCENE_SYOTES, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x020 */ DEFINE_ENTRANCE(ENTR_SYOTES2_0, SCENE_SYOTES2, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x021 */ DEFINE_ENTRANCE(ENTR_SYOTES2_0_1, SCENE_SYOTES2, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x022 */ DEFINE_ENTRANCE(ENTR_SYOTES2_0_2, SCENE_SYOTES2, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x023 */ DEFINE_ENTRANCE(ENTR_SYOTES2_0_3, SCENE_SYOTES2, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x024 */ DEFINE_ENTRANCE(ENTR_TESTROOM_0, SCENE_TESTROOM, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x025 */ DEFINE_ENTRANCE(ENTR_TESTROOM_0_1, SCENE_TESTROOM, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x026 */ DEFINE_ENTRANCE(ENTR_TESTROOM_0_2, SCENE_TESTROOM, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x027 */ DEFINE_ENTRANCE(ENTR_TESTROOM_0_3, SCENE_TESTROOM, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x028 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x029 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0_1, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x02A */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0_2, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x02B */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0_3, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x02C */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0_4, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x02D */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x02E */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0_1, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x02F */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0_2, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x030 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0_3, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x031 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0_4, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x032 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0_5, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x033 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_DAY_0, SCENE_MARKET_ENTRANCE_DAY, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x034 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NIGHT_0_1, SCENE_MARKET_ENTRANCE_NIGHT, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x035 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_0_2, SCENE_MARKET_ENTRANCE_RUINS, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x036 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_0_3, SCENE_MARKET_ENTRANCE_RUINS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x037 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x038 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0_1, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x039 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0_2, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x03A */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0_3, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x03B */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_0, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x03C */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_0_1, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x03D */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_0_2, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x03E */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_0_3, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x03F */ DEFINE_ENTRANCE(ENTR_GROTTOS_0, SCENE_GROTTOS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x040 */ DEFINE_ENTRANCE(ENTR_GROTTOS_0_1, SCENE_GROTTOS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x041 */ DEFINE_ENTRANCE(ENTR_GROTTOS_0_2, SCENE_GROTTOS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x042 */ DEFINE_ENTRANCE(ENTR_GROTTOS_0_3, SCENE_GROTTOS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x043 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_0, SCENE_LAKESIDE_LABORATORY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x044 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_0_1, SCENE_LAKESIDE_LABORATORY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x045 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_0_2, SCENE_LAKESIDE_LABORATORY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x046 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_0_3, SCENE_LAKESIDE_LABORATORY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x047 */ DEFINE_ENTRANCE(ENTR_SUTARU_0, SCENE_SUTARU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x048 */ DEFINE_ENTRANCE(ENTR_SUTARU_0_1, SCENE_SUTARU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x049 */ DEFINE_ENTRANCE(ENTR_SUTARU_0_2, SCENE_SUTARU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x04A */ DEFINE_ENTRANCE(ENTR_SUTARU_0_3, SCENE_SUTARU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x04B */ DEFINE_ENTRANCE(ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x04C */ DEFINE_ENTRANCE(ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0_1, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x04D */ DEFINE_ENTRANCE(ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0_2, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x04E */ DEFINE_ENTRANCE(ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0_3, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) + +/* 0x04F */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x050 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0_1, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x051 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0_2, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x052 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0_3, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x053 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x054 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_1, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x055 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_2, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x056 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_3, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x057 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_4, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x058 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_5, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x059 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_6, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x05A */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_7, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x05B */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_8, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x05C */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_9, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x05D */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_10, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x05E */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_11, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_INSTANT, TRANS_TYPE_INSTANT) +/* 0x05F */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_12, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x060 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_13, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x061 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_14, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x062 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_15, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x063 */ DEFINE_ENTRANCE(ENTR_TREASURE_BOX_SHOP_0, SCENE_TREASURE_BOX_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x064 */ DEFINE_ENTRANCE(ENTR_TREASURE_BOX_SHOP_0_1, SCENE_TREASURE_BOX_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x065 */ DEFINE_ENTRANCE(ENTR_TREASURE_BOX_SHOP_0_2, SCENE_TREASURE_BOX_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x066 */ DEFINE_ENTRANCE(ENTR_TREASURE_BOX_SHOP_0_3, SCENE_TREASURE_BOX_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x067 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_3, SCENE_BACK_ALLEY_DAY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x068 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_3_1, SCENE_BACK_ALLEY_NIGHT, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x069 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_3_2, SCENE_BACK_ALLEY_DAY, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x06A */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_3_3, SCENE_BACK_ALLEY_NIGHT, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x06B */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_0, SCENE_CHAMBER_OF_THE_SAGES, 0, false, true, TRANS_TYPE_FADE_WHITE_SLOW, TRANS_TYPE_FADE_WHITE_SLOW) +/* 0x06C */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_0_1, SCENE_CHAMBER_OF_THE_SAGES, 0, false, true, TRANS_TYPE_FADE_WHITE_SLOW, TRANS_TYPE_FADE_WHITE_SLOW) +/* 0x06D */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_0_2, SCENE_CHAMBER_OF_THE_SAGES, 0, false, true, TRANS_TYPE_FADE_WHITE_SLOW, TRANS_TYPE_FADE_WHITE_SLOW) +/* 0x06E */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_0_3, SCENE_CHAMBER_OF_THE_SAGES, 0, false, true, TRANS_TYPE_FADE_WHITE_SLOW, TRANS_TYPE_FADE_WHITE_SLOW) +/* 0x06F */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_0_4, SCENE_CHAMBER_OF_THE_SAGES, 0, false, true, TRANS_TYPE_FADE_WHITE_CS_DELAYED, TRANS_TYPE_FADE_BLACK) +/* 0x070 */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_0_5, SCENE_CHAMBER_OF_THE_SAGES, 0, false, true, TRANS_TYPE_FADE_WHITE_CS_DELAYED, TRANS_TYPE_FADE_BLACK) +/* 0x071 */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_0_6, SCENE_CHAMBER_OF_THE_SAGES, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x072 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_GRANNY_0, SCENE_POTION_SHOP_GRANNY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x073 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_GRANNY_0_1, SCENE_POTION_SHOP_GRANNY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x074 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_GRANNY_0_2, SCENE_POTION_SHOP_GRANNY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x075 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_GRANNY_0_3, SCENE_POTION_SHOP_GRANNY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x076 */ DEFINE_ENTRANCE(ENTR_HAIRAL_NIWA2_0, SCENE_HAIRAL_NIWA2, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST)) +/* 0x077 */ DEFINE_ENTRANCE(ENTR_HAIRAL_NIWA2_0_1, SCENE_HAIRAL_NIWA2, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST)) +/* 0x078 */ DEFINE_ENTRANCE(ENTR_HAIRAL_NIWA2_0_2, SCENE_HAIRAL_NIWA2, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST)) +/* 0x079 */ DEFINE_ENTRANCE(ENTR_HAIRAL_NIWA2_0_3, SCENE_HAIRAL_NIWA2, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST)) + +/* 0x07A */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_DAY_0, SCENE_CASTLE_COURTYARD_GUARDS_DAY, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_FADE_BLACK_FAST) +/* 0x07B */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_NIGHT_0_1, SCENE_CASTLE_COURTYARD_GUARDS_NIGHT, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_FADE_BLACK_FAST) +/* 0x07C */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_DAY_0_2, SCENE_CASTLE_COURTYARD_GUARDS_DAY, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_FADE_BLACK_FAST) +/* 0x07D */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_NIGHT_0_3, SCENE_CASTLE_COURTYARD_GUARDS_NIGHT, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_FAST), TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x07E */ DEFINE_ENTRANCE(ENTR_MARKET_GUARD_HOUSE_0, SCENE_MARKET_GUARD_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x07F */ DEFINE_ENTRANCE(ENTR_MARKET_GUARD_HOUSE_0_1, SCENE_MARKET_GUARD_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x080 */ DEFINE_ENTRANCE(ENTR_MARKET_GUARD_HOUSE_0_2, SCENE_MARKET_GUARD_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x081 */ DEFINE_ENTRANCE(ENTR_MARKET_GUARD_HOUSE_0_3, SCENE_MARKET_GUARD_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x082 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x083 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_1, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x084 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_2, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x085 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_3, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x086 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_4, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x087 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_5, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x088 */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x089 */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_1, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x08A */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_2, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x08B */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_3, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x08C */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_4, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x08D */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x08E */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_1, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x08F */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_2, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x090 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_3, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x091 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_4, SCENE_SPIRIT_TEMPLE_BOSS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x092 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_5, SCENE_SPIRIT_TEMPLE_BOSS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x093 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_6, SCENE_SPIRIT_TEMPLE_BOSS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x094 */ DEFINE_ENTRANCE(ENTR_TEST01_0, SCENE_TEST01, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x095 */ DEFINE_ENTRANCE(ENTR_TEST01_0_1, SCENE_TEST01, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x096 */ DEFINE_ENTRANCE(ENTR_TEST01_0_2, SCENE_TEST01, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x097 */ DEFINE_ENTRANCE(ENTR_TEST01_0_3, SCENE_TEST01, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x098 */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x099 */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0_1, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x09A */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0_2, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x09B */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0_3, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x09C */ DEFINE_ENTRANCE(ENTR_TWINS_HOUSE_0, SCENE_TWINS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x09D */ DEFINE_ENTRANCE(ENTR_TWINS_HOUSE_0_1, SCENE_TWINS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x09E */ DEFINE_ENTRANCE(ENTR_TWINS_HOUSE_0_2, SCENE_TWINS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x09F */ DEFINE_ENTRANCE(ENTR_TWINS_HOUSE_0_3, SCENE_TWINS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x0A0 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0A1 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_1, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0A2 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_2, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0A3 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_3, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0A4 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_4, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x0A5 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_5, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FILL_WHITE) +/* 0x0A6 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_6, SCENE_CUTSCENE_MAP, 0, true, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x0A7 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_7, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_INSTANT, TRANS_TYPE_INSTANT) +/* 0x0A8 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_8, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0A9 */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_9, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0AA */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_10, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0AB */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_11, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0AC */ DEFINE_ENTRANCE(ENTR_CUTSCENE_MAP_0_12, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x0AD */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_0, SCENE_BACK_ALLEY_DAY, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0AE */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_0_1, SCENE_BACK_ALLEY_NIGHT, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0AF */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_0_2, SCENE_BACK_ALLEY_DAY, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0B0 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_0_3, SCENE_BACK_ALLEY_NIGHT, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x0B1 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_0, SCENE_MARKET_DAY, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0B2 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_0_1, SCENE_MARKET_NIGHT, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0B3 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_0_2, SCENE_MARKET_RUINS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0B4 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_0_3, SCENE_MARKET_RUINS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0B5 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_0_4, SCENE_MARKET_DAY, 0, false, true, TRANS_TYPE_WIPE_FAST, TRANS_TYPE_WIPE_FAST) + +/* 0x0B6 */ DEFINE_ENTRANCE(ENTR_DEPTH_TEST_0, SCENE_DEPTH_TEST, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x0B7 */ DEFINE_ENTRANCE(ENTR_BAZAAR_0, SCENE_BAZAAR, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x0B8 */ DEFINE_ENTRANCE(ENTR_BAZAAR_0_1, SCENE_BAZAAR, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x0B9 */ DEFINE_ENTRANCE(ENTR_BAZAAR_0_2, SCENE_BAZAAR, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x0BA */ DEFINE_ENTRANCE(ENTR_BAZAAR_0_3, SCENE_BAZAAR, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x0BB */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0BC */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_1, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0BD */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_2, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0BE */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_3, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0BF */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_4, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x0C0 */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_5, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_CS_BLACK_FILL, TRANS_TYPE_CS_BLACK_FILL) + +/* 0x0C1 */ DEFINE_ENTRANCE(ENTR_KOKIRI_SHOP_0, SCENE_KOKIRI_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0C2 */ DEFINE_ENTRANCE(ENTR_KOKIRI_SHOP_0_1, SCENE_KOKIRI_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0C3 */ DEFINE_ENTRANCE(ENTR_KOKIRI_SHOP_0_2, SCENE_KOKIRI_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0C4 */ DEFINE_ENTRANCE(ENTR_KOKIRI_SHOP_0_3, SCENE_KOKIRI_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x0C5 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0C6 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1_1, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0C7 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1_2, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0C8 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1_3, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x0C9 */ DEFINE_ENTRANCE(ENTR_KNOW_IT_ALL_BROS_HOUSE_0, SCENE_KNOW_IT_ALL_BROS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0CA */ DEFINE_ENTRANCE(ENTR_KNOW_IT_ALL_BROS_HOUSE_0_1, SCENE_KNOW_IT_ALL_BROS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0CB */ DEFINE_ENTRANCE(ENTR_KNOW_IT_ALL_BROS_HOUSE_0_2, SCENE_KNOW_IT_ALL_BROS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0CC */ DEFINE_ENTRANCE(ENTR_KNOW_IT_ALL_BROS_HOUSE_0_3, SCENE_KNOW_IT_ALL_BROS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x0CD */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0CE */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_1, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0CF */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_2, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0D0 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_3, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0D1 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_4, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x0D2 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_5, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW)) +/* 0x0D3 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_6, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW)) +/* 0x0D4 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_7, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_SLOW)) +/* 0x0D5 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_8, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0D6 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_9, SCENE_HYRULE_FIELD, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0D7 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_10, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_BLACK, TCS_SLOW)) +/* 0x0D8 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_11, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0D9 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_12, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_WHITE, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_WHITE, TCS_SLOW)) +/* 0x0DA */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_13, SCENE_HYRULE_FIELD, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x0DB */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0DC */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_1, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0DD */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_2, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0DE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_3, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0DF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_4, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x0E0 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_5, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW)) +/* 0x0E1 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_6, SCENE_KAKARIKO_VILLAGE, 0, true, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW)) +/* 0x0E2 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_7, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW)) +/* 0x0E3 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_8, SCENE_KAKARIKO_VILLAGE, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x0E4 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0E5 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_1, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0E6 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_2, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0E7 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_3, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0E8 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_4, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x0E9 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_5, SCENE_GRAVEYARD, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x0EA */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0EB */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0_1, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0EC */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0_2, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0ED */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0_3, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x0EE */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0EF */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_1, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0F0 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_2, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0F1 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_3, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0F2 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_4, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x0F3 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_5, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x0F4 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_6, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x0F5 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_7, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FADE_WHITE_CS_DELAYED, TRANS_TYPE_FILL_WHITE) +/* 0x0F6 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_8, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x0F7 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_9, SCENE_KOKIRI_FOREST, 0, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x0F8 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_10, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0F9 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_11, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0FA */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_12, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0FB */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_13, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x0FC */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0FD */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_1, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0FE */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_2, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0FF */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_3, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x100 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_4, SCENE_SACRED_FOREST_MEADOW, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x101 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_5, SCENE_SACRED_FOREST_MEADOW, 0, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) + +/* 0x102 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x103 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_1, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x104 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_2, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x105 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_3, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x106 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_4, SCENE_LAKE_HYLIA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x107 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_5, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x108 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x109 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_1, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x10A */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_2, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x10B */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_3, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x10C */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_4, SCENE_ZORAS_DOMAIN, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x10D */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_5, SCENE_ZORAS_DOMAIN, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x10E */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x10F */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_1, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x110 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_2, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x111 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_3, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x112 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_4, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE_CS_DELAYED, TRANS_TYPE_WIPE) +/* 0x113 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_5, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x114 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_6, SCENE_ZORAS_FOUNTAIN, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x115 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_7, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x116 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_8, SCENE_ZORAS_FOUNTAIN, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x117 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x118 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_1, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x119 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_2, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x11A */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_3, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x11B */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_4, SCENE_GERUDO_VALLEY, 0, true, true, TRANS_TYPE_FILL_BROWN, TRANS_TYPE_FILL_WHITE) +/* 0x11C */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_5, SCENE_GERUDO_VALLEY, 0, true, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x11D */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_6, SCENE_GERUDO_VALLEY, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x11E */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x11F */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_1, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x120 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_2, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x121 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_3, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x122 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_4, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x123 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x124 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_1, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x125 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_2, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x126 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_3, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x127 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_4, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x128 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_5, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) + +/* 0x129 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x12A */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_1, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x12B */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_2, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x12C */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_3, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x12D */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_4, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW)) +/* 0x12E */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_5, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x12F */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_6, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x130 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x131 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0_1, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x132 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0_2, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x133 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0_3, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) + +/* 0x134 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x135 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_1_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x136 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_1_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x137 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_1_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x138 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_0, SCENE_HYRULE_CASTLE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x139 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_0_1, SCENE_HYRULE_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x13A */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_0_2, SCENE_OUTSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x13B */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_0_3, SCENE_OUTSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x13C */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_0_4, SCENE_OUTSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x13D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x13E */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_1, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x13F */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_2, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x140 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_3, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x141 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_4, SCENE_DEATH_MOUNTAIN_TRAIL, 0, true, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x142 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_5, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x143 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_6, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x144 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_7, SCENE_DEATH_MOUNTAIN_TRAIL, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x145 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_8, SCENE_DEATH_MOUNTAIN_TRAIL, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x146 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_9, SCENE_DEATH_MOUNTAIN_TRAIL, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x147 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x148 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_1, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x149 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_2, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x14A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_3, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x14B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_4, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x14C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_5, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x14D */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x14E */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_1, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x14F */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_2, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x150 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_3, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x151 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_4, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x152 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_5, SCENE_GORON_CITY, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x153 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_3, SCENE_ZORAS_DOMAIN, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) +/* 0x154 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_3_1, SCENE_ZORAS_DOMAIN, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) +/* 0x155 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_3_2, SCENE_ZORAS_DOMAIN, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) +/* 0x156 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_3_3, SCENE_ZORAS_DOMAIN, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) + +/* 0x157 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x158 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_1, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x159 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_2, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x15A */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_3, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x15B */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_4, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x15C */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_5, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST)) +/* 0x15D */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_6, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x15E */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_7, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x15F */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_8, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x160 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_9, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x161 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_10, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x162 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_11, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x163 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_12, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x164 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_13, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x165 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x166 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0_1, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x167 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0_2, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x168 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0_3, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x169 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x16A */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0_1, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x16B */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0_2, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x16C */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0_3, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x16D */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_1, SCENE_SHOOTING_GALLERY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x16E */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_1_1, SCENE_SHOOTING_GALLERY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x16F */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_1_2, SCENE_SHOOTING_GALLERY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x170 */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_1_3, SCENE_SHOOTING_GALLERY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x171 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_0, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x172 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_NIGHT_0_1, SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x173 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_0_2, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x174 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_0_3, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x175 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x176 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1_1, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x177 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1_2, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x178 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1_3, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x179 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x17A */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x17B */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x17C */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x17D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x17E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1_1, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x17F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1_2, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x180 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1_3, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x181 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x182 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2_1, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x183 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2_2, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x184 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2_3, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x185 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x186 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3_1, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x187 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3_2, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x188 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3_3, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x189 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x18A */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4_1, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x18B */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4_2, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x18C */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4_3, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x18D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x18E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5_1, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x18F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5_2, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x190 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5_3, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x191 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x192 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1_1, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x193 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1_2, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x194 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1_3, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x195 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x196 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2_1, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x197 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2_2, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x198 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2_3, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x199 */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_1, SCENE_ZORAS_RIVER, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x19A */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_1_1, SCENE_ZORAS_RIVER, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x19B */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_1_2, SCENE_ZORAS_RIVER, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x19C */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_1_3, SCENE_ZORAS_RIVER, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x19D */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x19E */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2_1, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x19F */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2_2, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1A0 */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2_3, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1A1 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1A2 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1_1, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1A3 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1_2, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1A4 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1_3, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1A5 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_1, SCENE_GERUDO_VALLEY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1A6 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_1_1, SCENE_GERUDO_VALLEY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1A7 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_1_2, SCENE_GERUDO_VALLEY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1A8 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_1_3, SCENE_GERUDO_VALLEY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1A9 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1AA */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1_1, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1AB */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1_2, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1AC */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1_3, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1AD */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_2, SCENE_LOST_WOODS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1AE */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_2_1, SCENE_LOST_WOODS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1AF */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_2_2, SCENE_LOST_WOODS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1B0 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_2_3, SCENE_LOST_WOODS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1B1 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_3, SCENE_LOST_WOODS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1B2 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_3_1, SCENE_LOST_WOODS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1B3 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_3_2, SCENE_LOST_WOODS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1B4 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_3_3, SCENE_LOST_WOODS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1B5 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1B6 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_2_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1B7 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_2_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1B8 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_2_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1B9 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1BA */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1_1, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1BB */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1_2, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1BC */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1_3, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1BD */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1BE */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2_1, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1BF */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2_2, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1C0 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2_3, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1C1 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1C2 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1_1, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1C3 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1_2, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1C4 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1_3, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1C5 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_1, SCENE_LAKESIDE_LABORATORY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x1C6 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_1_1, SCENE_LAKESIDE_LABORATORY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x1C7 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_1_2, SCENE_LAKESIDE_LABORATORY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x1C8 */ DEFINE_ENTRANCE(ENTR_LAKESIDE_LABORATORY_1_3, SCENE_LAKESIDE_LABORATORY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x1C9 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_5, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1CA */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_5_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1CB */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_5_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1CC */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_5_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1CD */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_8, SCENE_MARKET_DAY, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1CE */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_8_1, SCENE_MARKET_NIGHT, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1CF */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_8_2, SCENE_MARKET_RUINS, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D0 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_8_3, SCENE_MARKET_RUINS, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x1D1 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_9, SCENE_MARKET_DAY, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D2 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_9_1, SCENE_MARKET_NIGHT, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D3 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_9_2, SCENE_MARKET_RUINS, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D4 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_9_3, SCENE_MARKET_RUINS, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x1D5 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_10, SCENE_MARKET_DAY, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D6 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_10_1, SCENE_MARKET_NIGHT, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D7 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_10_2, SCENE_MARKET_RUINS, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D8 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_10_3, SCENE_MARKET_RUINS, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x1D9 */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_3, SCENE_ZORAS_RIVER, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1DA */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_3_1, SCENE_ZORAS_RIVER, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1DB */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_3_2, SCENE_ZORAS_RIVER, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1DC */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_3_3, SCENE_ZORAS_RIVER, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1DD */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x1DE */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4_1, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x1DF */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4_2, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x1E0 */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4_3, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) + +/* 0x1E1 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1E2 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1_1, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1E3 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1_2, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1E4 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1_3, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1E5 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_2, SCENE_DESERT_COLOSSUS, 2, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1E6 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_2_1, SCENE_DESERT_COLOSSUS, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1E7 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_2_2, SCENE_DESERT_COLOSSUS, 2, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1E8 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_2_3, SCENE_DESERT_COLOSSUS, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1E9 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_3, SCENE_DESERT_COLOSSUS, 3, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1EA */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_3_1, SCENE_DESERT_COLOSSUS, 3, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1EB */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_3_2, SCENE_DESERT_COLOSSUS, 3, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1EC */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_3_3, SCENE_DESERT_COLOSSUS, 3, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1ED */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_4, SCENE_DESERT_COLOSSUS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1EE */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_4_1, SCENE_DESERT_COLOSSUS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1EF */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_4_2, SCENE_DESERT_COLOSSUS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1F0 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_4_3, SCENE_DESERT_COLOSSUS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1F1 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1F2 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5_1, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1F3 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5_2, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1F4 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5_3, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1F5 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_6, SCENE_DESERT_COLOSSUS, 6, true, false, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x1F6 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_6_1, SCENE_DESERT_COLOSSUS, 6, true, false, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x1F7 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_6_2, SCENE_DESERT_COLOSSUS, 6, true, false, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x1F8 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_6_3, SCENE_DESERT_COLOSSUS, 6, true, false, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) + +/* 0x1F9 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1FA */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6_1, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1FB */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6_2, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1FC */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6_3, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x1FD */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1FE */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7_1, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1FF */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7_2, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x200 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7_3, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x201 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x202 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3_1, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x203 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3_2, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x204 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3_3, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x205 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x206 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1_1, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x207 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1_2, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x208 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1_3, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x209 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x20A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1_1, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x20B */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1_2, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x20C */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1_3, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x20D */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x20E */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2_1, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x20F */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2_2, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x210 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2_3, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x211 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x212 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3_1, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x213 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3_2, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x214 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3_3, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x215 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) +/* 0x216 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1_1, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x217 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1_2, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) +/* 0x218 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1_3, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x219 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x21A */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1_1, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x21B */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1_2, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x21C */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1_3, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x21D */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLUE, TRANS_TYPE_FADE_BLUE) +/* 0x21E */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2_1, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x21F */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2_2, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLUE, TRANS_TYPE_FADE_BLUE) +/* 0x220 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2_3, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x221 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x222 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1_1, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x223 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1_2, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x224 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1_3, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x225 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x226 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2_1, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x227 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2_2, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x228 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2_3, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x229 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_2, SCENE_GERUDO_VALLEY, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x22A */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_2_1, SCENE_GERUDO_VALLEY, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x22B */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_2_2, SCENE_GERUDO_VALLEY, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x22C */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_2_3, SCENE_GERUDO_VALLEY, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x22D */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x22E */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3_1, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x22F */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3_2, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x230 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3_3, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x231 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_1, SCENE_GERUDOS_FORTRESS, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x232 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_1_1, SCENE_GERUDOS_FORTRESS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x233 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_1_2, SCENE_GERUDOS_FORTRESS, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x234 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_1_3, SCENE_GERUDOS_FORTRESS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x235 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_2, SCENE_GERUDOS_FORTRESS, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x236 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_2_1, SCENE_GERUDOS_FORTRESS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x237 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_2_2, SCENE_GERUDOS_FORTRESS, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x238 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_2_3, SCENE_GERUDOS_FORTRESS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x239 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_3, SCENE_GERUDOS_FORTRESS, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x23A */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_3_1, SCENE_GERUDOS_FORTRESS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x23B */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_3_2, SCENE_GERUDOS_FORTRESS, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x23C */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_3_3, SCENE_GERUDOS_FORTRESS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x23D */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_1, SCENE_HYRULE_CASTLE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x23E */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_1_1, SCENE_HYRULE_CASTLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x23F */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_1_2, SCENE_OUTSIDE_GANONS_CASTLE, 1, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x240 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_1_3, SCENE_OUTSIDE_GANONS_CASTLE, 1, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x241 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_1_4, SCENE_HYRULE_CASTLE, 1, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) + +/* 0x242 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x243 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3_1, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x244 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3_2, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x245 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3_3, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x246 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x247 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1_1, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x248 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1_2, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x249 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1_3, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x24A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x24B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2_1, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x24C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2_2, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x24D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2_3, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x24E */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x24F */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1_1, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x250 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1_2, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x251 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1_3, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x252 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x253 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1_1, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x254 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1_2, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x255 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1_3, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x256 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x257 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_3_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x258 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_3_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x259 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_3_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x25A */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_1, SCENE_MARKET_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x25B */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_1_1, SCENE_MARKET_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x25C */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_1_2, SCENE_MARKET_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x25D */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_1_3, SCENE_MARKET_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x25E */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_2, SCENE_MARKET_DAY, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x25F */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_2_1, SCENE_MARKET_NIGHT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x260 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_2_2, SCENE_MARKET_RUINS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x261 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_2_3, SCENE_MARKET_RUINS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x262 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_3, SCENE_MARKET_DAY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x263 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_3_1, SCENE_MARKET_NIGHT, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x264 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_3_2, SCENE_MARKET_RUINS, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x265 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_3_3, SCENE_MARKET_RUINS, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x266 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x267 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4_1, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x268 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4_2, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x269 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4_3, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x26A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x26B */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5_1, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x26C */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5_2, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x26D */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5_3, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x26E */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_DAY_2, SCENE_MARKET_ENTRANCE_DAY, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x26F */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NIGHT_2_1, SCENE_MARKET_ENTRANCE_NIGHT, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x270 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_2_2, SCENE_MARKET_ENTRANCE_RUINS, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x271 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_2_3, SCENE_MARKET_ENTRANCE_RUINS, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x272 */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_1, SCENE_LINKS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x273 */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_1_1, SCENE_LINKS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x274 */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_1_2, SCENE_LINKS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x275 */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_1_3, SCENE_LINKS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x276 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_DAY_1, SCENE_MARKET_ENTRANCE_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x277 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NIGHT_1_1, SCENE_MARKET_ENTRANCE_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x278 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_1_2, SCENE_MARKET_ENTRANCE_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x279 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_1_3, SCENE_MARKET_ENTRANCE_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x27A */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_8, SCENE_HYRULE_FIELD, 8, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x27B */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_8_1, SCENE_HYRULE_FIELD, 8, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x27C */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_8_2, SCENE_HYRULE_FIELD, 8, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x27D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_8_3, SCENE_HYRULE_FIELD, 8, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x27E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x27F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9_1, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x280 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9_2, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x281 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9_3, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x282 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_10, SCENE_HYRULE_FIELD, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x283 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_10_1, SCENE_HYRULE_FIELD, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x284 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_10_2, SCENE_HYRULE_FIELD, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x285 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_10_3, SCENE_HYRULE_FIELD, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x286 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x287 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6_1, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x288 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6_2, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x289 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6_3, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x28A */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_11, SCENE_HYRULE_FIELD, 11, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x28B */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_11_1, SCENE_HYRULE_FIELD, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x28C */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_11_2, SCENE_HYRULE_FIELD, 11, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x28D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_11_3, SCENE_HYRULE_FIELD, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x28E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_12, SCENE_HYRULE_FIELD, 12, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x28F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_12_1, SCENE_HYRULE_FIELD, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x290 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_12_2, SCENE_HYRULE_FIELD, 12, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x291 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_12_3, SCENE_HYRULE_FIELD, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x292 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_13, SCENE_HYRULE_FIELD, 13, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x293 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_13_1, SCENE_HYRULE_FIELD, 13, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x294 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_13_2, SCENE_HYRULE_FIELD, 13, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x295 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_13_3, SCENE_HYRULE_FIELD, 13, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x296 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_DAY_1, SCENE_CASTLE_COURTYARD_GUARDS_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x297 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_NIGHT_1_1, SCENE_CASTLE_COURTYARD_GUARDS_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x298 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_DAY_1_2, SCENE_CASTLE_COURTYARD_GUARDS_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x299 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_GUARDS_NIGHT_1_3, SCENE_CASTLE_COURTYARD_GUARDS_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x29A */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_1, SCENE_BACK_ALLEY_DAY, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x29B */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_1_1, SCENE_BACK_ALLEY_NIGHT, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x29C */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_1_2, SCENE_BACK_ALLEY_DAY, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x29D */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_1_3, SCENE_BACK_ALLEY_NIGHT, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x29E */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_4, SCENE_MARKET_DAY, 4, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x29F */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_4_1, SCENE_MARKET_NIGHT, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2A0 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_4_2, SCENE_MARKET_RUINS, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2A1 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_4_3, SCENE_MARKET_RUINS, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2A2 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_5, SCENE_MARKET_DAY, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x2A3 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_5_1, SCENE_MARKET_NIGHT, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x2A4 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_5_2, SCENE_MARKET_RUINS, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x2A5 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_5_3, SCENE_MARKET_RUINS, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x2A6 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2A7 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4_1, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2A8 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4_2, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2A9 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4_3, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2AA */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_4, SCENE_GERUDOS_FORTRESS, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2AB */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_4_1, SCENE_GERUDOS_FORTRESS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2AC */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_4_2, SCENE_GERUDOS_FORTRESS, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2AD */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_4_3, SCENE_GERUDOS_FORTRESS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2AE */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_1, SCENE_LON_LON_RANCH, 1, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2AF */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_1_1, SCENE_LON_LON_RANCH, 1, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B0 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_1_2, SCENE_LON_LON_RANCH, 1, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2B1 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_1_3, SCENE_LON_LON_RANCH, 1, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2B2 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B3 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1_1, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B4 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1_2, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B5 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1_3, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2B6 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_2, SCENE_SHADOW_TEMPLE, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B7 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_2_1, SCENE_SHADOW_TEMPLE, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B8 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_2_2, SCENE_SHADOW_TEMPLE, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B9 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_2_3, SCENE_SHADOW_TEMPLE, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2BA */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_5, SCENE_GERUDOS_FORTRESS, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2BB */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_5_1, SCENE_GERUDOS_FORTRESS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2BC */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_5_2, SCENE_GERUDOS_FORTRESS, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2BD */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_5_3, SCENE_GERUDOS_FORTRESS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2BE */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_6, SCENE_GERUDOS_FORTRESS, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2BF */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_6_1, SCENE_GERUDOS_FORTRESS, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2C0 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_6_2, SCENE_GERUDOS_FORTRESS, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2C1 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_6_3, SCENE_GERUDOS_FORTRESS, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2C2 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_7, SCENE_GERUDOS_FORTRESS, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2C3 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_7_1, SCENE_GERUDOS_FORTRESS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2C4 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_7_2, SCENE_GERUDOS_FORTRESS, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2C5 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_7_3, SCENE_GERUDOS_FORTRESS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2C6 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_8, SCENE_GERUDOS_FORTRESS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2C7 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_8_1, SCENE_GERUDOS_FORTRESS, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2C8 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_8_2, SCENE_GERUDOS_FORTRESS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2C9 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_8_3, SCENE_GERUDOS_FORTRESS, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2CA */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_2, SCENE_TEMPLE_OF_TIME, 2, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x2CB */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_2_1, SCENE_TEMPLE_OF_TIME, 2, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x2CC */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_2_2, SCENE_TEMPLE_OF_TIME, 2, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) +/* 0x2CD */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_2_3, SCENE_TEMPLE_OF_TIME, 2, false, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) + +/* 0x2CE */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_1, SCENE_CHAMBER_OF_THE_SAGES, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2CF */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_1_1, SCENE_CHAMBER_OF_THE_SAGES, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2D0 */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_1_2, SCENE_CHAMBER_OF_THE_SAGES, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2D1 */ DEFINE_ENTRANCE(ENTR_CHAMBER_OF_THE_SAGES_1_3, SCENE_CHAMBER_OF_THE_SAGES, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2D2 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_9, SCENE_GERUDOS_FORTRESS, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2D3 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_9_1, SCENE_GERUDOS_FORTRESS, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2D4 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_9_2, SCENE_GERUDOS_FORTRESS, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2D5 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_9_3, SCENE_GERUDOS_FORTRESS, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2D6 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_10, SCENE_GERUDOS_FORTRESS, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2D7 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_10_1, SCENE_GERUDOS_FORTRESS, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2D8 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_10_2, SCENE_GERUDOS_FORTRESS, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2D9 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_10_3, SCENE_GERUDOS_FORTRESS, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2DA */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_11, SCENE_GERUDOS_FORTRESS, 11, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2DB */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_11_1, SCENE_GERUDOS_FORTRESS, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2DC */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_11_2, SCENE_GERUDOS_FORTRESS, 11, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2DD */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_11_3, SCENE_GERUDOS_FORTRESS, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2DE */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_12, SCENE_GERUDOS_FORTRESS, 12, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2DF */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_12_1, SCENE_GERUDOS_FORTRESS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2E0 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_12_2, SCENE_GERUDOS_FORTRESS, 12, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2E1 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_12_3, SCENE_GERUDOS_FORTRESS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2E2 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_2, SCENE_LON_LON_RANCH, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2E3 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_2_1, SCENE_LON_LON_RANCH, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2E4 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_2_2, SCENE_LON_LON_RANCH, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2E5 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_2_3, SCENE_LON_LON_RANCH, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2E6 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_3, SCENE_LON_LON_RANCH, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2E7 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_3_1, SCENE_LON_LON_RANCH, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2E8 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_3_2, SCENE_LON_LON_RANCH, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x2E9 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_3_3, SCENE_LON_LON_RANCH, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +// Labeled as "Test Area" in Map Select +/* 0x2EA */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2EB */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_1, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2EC */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_2, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2ED */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_3, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2EE */ DEFINE_ENTRANCE(ENTR_TEST_SACRED_FOREST_MEADOW_0_4, SCENE_SACRED_FOREST_MEADOW, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2EF */ DEFINE_ENTRANCE(ENTR_TEST_CUTSCENE_MAP_0_5, SCENE_CUTSCENE_MAP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F0 */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_6, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F1 */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_7, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F2 */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_8, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F3 */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_9, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F4 */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_10, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2F5 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F6 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1_1, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F7 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1_2, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F8 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1_3, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x2F9 */ DEFINE_ENTRANCE(ENTR_STABLE_0, SCENE_STABLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x2FA */ DEFINE_ENTRANCE(ENTR_STABLE_0_1, SCENE_STABLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x2FB */ DEFINE_ENTRANCE(ENTR_STABLE_0_2, SCENE_STABLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x2FC */ DEFINE_ENTRANCE(ENTR_STABLE_0_3, SCENE_STABLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x2FD */ DEFINE_ENTRANCE(ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0, SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x2FE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0_1, SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x2FF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0_2, SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x300 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0_3, SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x301 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x302 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0_1, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x303 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0_2, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x304 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0_3, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x305 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x306 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0_1, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x307 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0_2, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x308 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0_3, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x309 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x30A */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6_1, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x30B */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6_2, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x30C */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6_3, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x30D */ DEFINE_ENTRANCE(ENTR_GRAVEKEEPERS_HUT_0, SCENE_GRAVEKEEPERS_HUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x30E */ DEFINE_ENTRANCE(ENTR_GRAVEKEEPERS_HUT_0_1, SCENE_GRAVEKEEPERS_HUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x30F */ DEFINE_ENTRANCE(ENTR_GRAVEKEEPERS_HUT_0_2, SCENE_GRAVEKEEPERS_HUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x310 */ DEFINE_ENTRANCE(ENTR_GRAVEKEEPERS_HUT_0_3, SCENE_GRAVEKEEPERS_HUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x311 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_14, SCENE_HYRULE_FIELD, 14, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x312 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_14_1, SCENE_HYRULE_FIELD, 14, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x313 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_14_2, SCENE_HYRULE_FIELD, 14, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x314 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_14_3, SCENE_HYRULE_FIELD, 14, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x315 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x316 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x317 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x318 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x319 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_4, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x31A */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_5, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x31B */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_6, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x31C */ DEFINE_ENTRANCE(ENTR_REDEAD_GRAVE_0, SCENE_REDEAD_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x31D */ DEFINE_ENTRANCE(ENTR_REDEAD_GRAVE_0_1, SCENE_REDEAD_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x31E */ DEFINE_ENTRANCE(ENTR_REDEAD_GRAVE_0_2, SCENE_REDEAD_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x31F */ DEFINE_ENTRANCE(ENTR_REDEAD_GRAVE_0_3, SCENE_REDEAD_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) + +/* 0x320 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_3, SCENE_TEMPLE_OF_TIME, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x321 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_3_1, SCENE_TEMPLE_OF_TIME, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x322 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_3_2, SCENE_TEMPLE_OF_TIME, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x323 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_3_3, SCENE_TEMPLE_OF_TIME, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x324 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_4, SCENE_TEMPLE_OF_TIME, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x325 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_4_1, SCENE_TEMPLE_OF_TIME, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x326 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_4_2, SCENE_TEMPLE_OF_TIME, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x327 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_4_3, SCENE_TEMPLE_OF_TIME, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x328 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x329 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4_1, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x32A */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4_2, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x32B */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4_3, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) + +/* 0x32C */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x32D */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_2_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x32E */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_2_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x32F */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_2_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x330 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x331 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_3_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x332 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_3_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x333 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_3_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x334 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_4, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x335 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_4_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x336 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_4_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x337 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_4_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x338 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_7, SCENE_KOKIRI_FOREST, 7, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x339 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_7_1, SCENE_KOKIRI_FOREST, 7, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x33A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_7_2, SCENE_KOKIRI_FOREST, 7, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x33B */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_7_3, SCENE_KOKIRI_FOREST, 7, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x33C */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x33D */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8_1, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x33E */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8_2, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x33F */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8_3, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x340 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_2, SCENE_HYRULE_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x341 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_2_1, SCENE_HYRULE_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x342 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_2_2, SCENE_OUTSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x343 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_2_3, SCENE_OUTSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x344 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_2_4, SCENE_HYRULE_CASTLE, 2, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) + +/* 0x345 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x346 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5_1, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x347 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5_2, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x348 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5_3, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x349 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x34A */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6_1, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x34B */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6_2, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x34C */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6_3, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x34D */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x34E */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7_1, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x34F */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7_2, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x350 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7_3, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x351 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x352 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8_1, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x353 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8_2, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x354 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8_3, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x355 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x356 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2_1, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x357 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2_2, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x358 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2_3, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x359 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x35A */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3_1, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x35B */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3_2, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x35C */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3_3, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x35D */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x35E */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4_1, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x35F */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4_2, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x360 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4_3, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x361 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x362 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5_1, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x363 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5_2, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x364 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5_3, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x365 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x366 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1_1, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x367 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1_2, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x368 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1_3, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) + +/* 0x369 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_2, SCENE_HAUNTED_WASTELAND, 2, false, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x36A */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_2_1, SCENE_HAUNTED_WASTELAND, 2, false, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x36B */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_2_2, SCENE_HAUNTED_WASTELAND, 2, false, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x36C */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_2_3, SCENE_HAUNTED_WASTELAND, 2, false, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) + +/* 0x36D */ DEFINE_ENTRANCE(ENTR_FAIRYS_FOUNTAIN_0, SCENE_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x36E */ DEFINE_ENTRANCE(ENTR_FAIRYS_FOUNTAIN_0_1, SCENE_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x36F */ DEFINE_ENTRANCE(ENTR_FAIRYS_FOUNTAIN_0_2, SCENE_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x370 */ DEFINE_ENTRANCE(ENTR_FAIRYS_FOUNTAIN_0_3, SCENE_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x371 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x372 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x373 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x374 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_3, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x375 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_4, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x376 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_5, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x377 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_6, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x378 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x379 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4_1, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x37A */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4_2, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x37B */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4_3, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x37C */ DEFINE_ENTRANCE(ENTR_GORON_SHOP_0, SCENE_GORON_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x37D */ DEFINE_ENTRANCE(ENTR_GORON_SHOP_0_1, SCENE_GORON_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x37E */ DEFINE_ENTRANCE(ENTR_GORON_SHOP_0_2, SCENE_GORON_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x37F */ DEFINE_ENTRANCE(ENTR_GORON_SHOP_0_3, SCENE_GORON_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x380 */ DEFINE_ENTRANCE(ENTR_ZORA_SHOP_0, SCENE_ZORA_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x381 */ DEFINE_ENTRANCE(ENTR_ZORA_SHOP_0_1, SCENE_ZORA_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x382 */ DEFINE_ENTRANCE(ENTR_ZORA_SHOP_0_2, SCENE_ZORA_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x383 */ DEFINE_ENTRANCE(ENTR_ZORA_SHOP_0_3, SCENE_ZORA_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x384 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0, SCENE_POTION_SHOP_KAKARIKO, 0, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x385 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0_1, SCENE_POTION_SHOP_KAKARIKO, 0, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x386 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0_2, SCENE_POTION_SHOP_KAKARIKO, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x387 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0_3, SCENE_POTION_SHOP_KAKARIKO, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x388 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_MARKET_0, SCENE_POTION_SHOP_MARKET, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x389 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_MARKET_0_1, SCENE_POTION_SHOP_MARKET, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x38A */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_MARKET_0_2, SCENE_POTION_SHOP_MARKET, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x38B */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_MARKET_0_3, SCENE_POTION_SHOP_MARKET, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x38C */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_4, SCENE_BACK_ALLEY_DAY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x38D */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_4_1, SCENE_BACK_ALLEY_NIGHT, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x38E */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_4_2, SCENE_BACK_ALLEY_DAY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x38F */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_4_3, SCENE_BACK_ALLEY_NIGHT, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x390 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_0, SCENE_BOMBCHU_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x391 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_0_1, SCENE_BOMBCHU_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x392 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_0_2, SCENE_BOMBCHU_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x393 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_0_3, SCENE_BOMBCHU_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x394 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x395 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5_1, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x396 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5_2, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x397 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5_3, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x398 */ DEFINE_ENTRANCE(ENTR_DOG_LADY_HOUSE_0, SCENE_DOG_LADY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x399 */ DEFINE_ENTRANCE(ENTR_DOG_LADY_HOUSE_0_1, SCENE_DOG_LADY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x39A */ DEFINE_ENTRANCE(ENTR_DOG_LADY_HOUSE_0_2, SCENE_DOG_LADY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x39B */ DEFINE_ENTRANCE(ENTR_DOG_LADY_HOUSE_0_3, SCENE_DOG_LADY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x39C */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x39D */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0_1, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x39E */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0_2, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x39F */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0_3, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x3A0 */ DEFINE_ENTRANCE(ENTR_CARPENTERS_TENT_0, SCENE_CARPENTERS_TENT, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x3A1 */ DEFINE_ENTRANCE(ENTR_CARPENTERS_TENT_0_1, SCENE_CARPENTERS_TENT, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x3A2 */ DEFINE_ENTRANCE(ENTR_CARPENTERS_TENT_0_2, SCENE_CARPENTERS_TENT, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x3A3 */ DEFINE_ENTRANCE(ENTR_CARPENTERS_TENT_0_3, SCENE_CARPENTERS_TENT, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x3A4 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_13, SCENE_GERUDOS_FORTRESS, 13, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3A5 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_13_1, SCENE_GERUDOS_FORTRESS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3A6 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_13_2, SCENE_GERUDOS_FORTRESS, 13, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3A7 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_13_3, SCENE_GERUDOS_FORTRESS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3A8 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x3A9 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14_1, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x3AA */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14_2, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x3AB */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14_3, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x3AC */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x3AD */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15_1, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x3AE */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15_2, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x3AF */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15_3, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) + +/* 0x3B0 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_16, SCENE_GERUDOS_FORTRESS, 16, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3B1 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_16_1, SCENE_GERUDOS_FORTRESS, 16, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3B2 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_16_2, SCENE_GERUDOS_FORTRESS, 16, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3B3 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_16_3, SCENE_GERUDOS_FORTRESS, 16, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3B4 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_17, SCENE_GERUDOS_FORTRESS, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3B5 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_17_1, SCENE_GERUDOS_FORTRESS, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3B6 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_17_2, SCENE_GERUDOS_FORTRESS, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3B7 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_17_3, SCENE_GERUDOS_FORTRESS, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3B8 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_6, SCENE_MARKET_DAY, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3B9 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_6_1, SCENE_MARKET_NIGHT, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3BA */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_6_2, SCENE_MARKET_RUINS, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3BB */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_6_3, SCENE_MARKET_RUINS, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x3BC */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_7, SCENE_MARKET_DAY, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3BD */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_7_1, SCENE_MARKET_NIGHT, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3BE */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_7_2, SCENE_MARKET_RUINS, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3BF */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_7_3, SCENE_MARKET_RUINS, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x3C0 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_2, SCENE_BACK_ALLEY_DAY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3C1 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_2_1, SCENE_BACK_ALLEY_NIGHT, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3C2 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_2_2, SCENE_BACK_ALLEY_DAY, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3C3 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_2_3, SCENE_BACK_ALLEY_NIGHT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3C4 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3C5 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2_1, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3C6 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2_2, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3C7 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2_3, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3C8 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_3, SCENE_LAKE_HYLIA, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3C9 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_3_1, SCENE_LAKE_HYLIA, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3CA */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_3_2, SCENE_LAKE_HYLIA, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3CB */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_3_3, SCENE_LAKE_HYLIA, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x3CC */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3CD */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4_1, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3CE */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4_2, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3CF */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4_3, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x3D0 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3D1 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4_1, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3D2 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4_2, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3D3 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4_3, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x3D4 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3D5 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3_1, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3D6 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3_2, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3D7 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3_3, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3D8 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_4, SCENE_ZORAS_FOUNTAIN, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3D9 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_4_1, SCENE_ZORAS_FOUNTAIN, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3DA */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_4_2, SCENE_ZORAS_FOUNTAIN, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3DB */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_4_3, SCENE_ZORAS_FOUNTAIN, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3DC */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_4, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3DD */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_4_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3DE */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_4_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3DF */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_4_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3E0 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_5, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3E1 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_5_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3E2 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_5_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3E3 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_5_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3E4 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_6, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3E5 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_6_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3E6 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_6_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3E7 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_6_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3E8 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_1, SCENE_POTION_SHOP_KAKARIKO, 1, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x3E9 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_1_1, SCENE_POTION_SHOP_KAKARIKO, 1, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x3EA */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_1_2, SCENE_POTION_SHOP_KAKARIKO, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x3EB */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_1_3, SCENE_POTION_SHOP_KAKARIKO, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x3EC */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2, SCENE_POTION_SHOP_KAKARIKO, 2, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x3ED */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2_1, SCENE_POTION_SHOP_KAKARIKO, 2, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x3EE */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2_2, SCENE_POTION_SHOP_KAKARIKO, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x3EF */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2_3, SCENE_POTION_SHOP_KAKARIKO, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x3F0 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_2, SCENE_SPIRIT_TEMPLE, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3F1 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_2_1, SCENE_SPIRIT_TEMPLE, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3F2 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_2_2, SCENE_SPIRIT_TEMPLE, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3F3 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_2_3, SCENE_SPIRIT_TEMPLE, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3F4 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_3, SCENE_SPIRIT_TEMPLE, 3, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3F5 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_3_1, SCENE_SPIRIT_TEMPLE, 3, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3F6 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_3_2, SCENE_SPIRIT_TEMPLE, 3, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3F7 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_3_3, SCENE_SPIRIT_TEMPLE, 3, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3F8 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_4, SCENE_SPIRIT_TEMPLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3F9 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_4_1, SCENE_SPIRIT_TEMPLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3FA */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_4_2, SCENE_SPIRIT_TEMPLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3FB */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_4_3, SCENE_SPIRIT_TEMPLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x3FC */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3FD */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2_1, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3FE */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2_2, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3FF */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2_3, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x400 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x401 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_1, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x402 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_2, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x403 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_3, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x404 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_4, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x405 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_5, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x406 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_6, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x407 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x408 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1_1, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x409 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1_2, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x40A */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1_3, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x40B */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x40C */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0_1, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x40D */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0_2, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x40E */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0_3, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x40F */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x410 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0_1, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x411 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0_2, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x412 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0_3, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x413 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x414 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0_1, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x415 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0_2, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x416 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0_3, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x417 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x418 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0_1, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x419 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0_2, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x41A */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0_3, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x41B */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_0, SCENE_GANONS_TOWER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x41C */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_0_1, SCENE_GANONS_TOWER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x41D */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_0_2, SCENE_GANONS_TOWER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x41E */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_0_3, SCENE_GANONS_TOWER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x41F */ DEFINE_ENTRANCE(ENTR_GANONDORF_BOSS_0, SCENE_GANONDORF_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x420 */ DEFINE_ENTRANCE(ENTR_GANONDORF_BOSS_0_1, SCENE_GANONDORF_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x421 */ DEFINE_ENTRANCE(ENTR_GANONDORF_BOSS_0_2, SCENE_GANONDORF_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x422 */ DEFINE_ENTRANCE(ENTR_GANONDORF_BOSS_0_3, SCENE_GANONDORF_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x423 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_BLACK) +/* 0x424 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1_1, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x425 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1_2, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_BLACK) +/* 0x426 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1_3, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x427 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_1, SCENE_GANONS_TOWER, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x428 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_1_1, SCENE_GANONS_TOWER, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x429 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_1_2, SCENE_GANONS_TOWER, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x42A */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_1_3, SCENE_GANONS_TOWER, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x42B */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_2, SCENE_GANONS_TOWER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x42C */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_2_1, SCENE_GANONS_TOWER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x42D */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_2_2, SCENE_GANONS_TOWER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x42E */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_2_3, SCENE_GANONS_TOWER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x42F */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x430 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5_1, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x431 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5_2, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x432 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5_3, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x433 */ DEFINE_ENTRANCE(ENTR_MIDOS_HOUSE_0, SCENE_MIDOS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x434 */ DEFINE_ENTRANCE(ENTR_MIDOS_HOUSE_0_1, SCENE_MIDOS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x435 */ DEFINE_ENTRANCE(ENTR_MIDOS_HOUSE_0_2, SCENE_MIDOS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x436 */ DEFINE_ENTRANCE(ENTR_MIDOS_HOUSE_0_3, SCENE_MIDOS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x437 */ DEFINE_ENTRANCE(ENTR_SARIAS_HOUSE_0, SCENE_SARIAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x438 */ DEFINE_ENTRANCE(ENTR_SARIAS_HOUSE_0_1, SCENE_SARIAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x439 */ DEFINE_ENTRANCE(ENTR_SARIAS_HOUSE_0_2, SCENE_SARIAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x43A */ DEFINE_ENTRANCE(ENTR_SARIAS_HOUSE_0_3, SCENE_SARIAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x43B */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x43C */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0_1, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x43D */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0_2, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x43E */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0_3, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x43F */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x440 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x441 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x442 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x443 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x444 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9_1, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x445 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9_2, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x446 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9_3, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x447 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x448 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10_1, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x449 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10_2, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x44A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10_3, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x44B */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x44C */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9_1, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x44D */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9_2, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x44E */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9_3, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x44F */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x450 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0_1, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x451 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0_2, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x452 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0_3, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) + +/* 0x453 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x454 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1_1, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x455 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1_2, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x456 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1_3, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x457 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x458 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11_1, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x459 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11_2, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x45A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11_3, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x45B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x45C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4_1, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x45D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4_2, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x45E */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4_3, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x45F */ DEFINE_ENTRANCE(ENTR_FISHING_POND_0, SCENE_FISHING_POND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x460 */ DEFINE_ENTRANCE(ENTR_FISHING_POND_0_1, SCENE_FISHING_POND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x461 */ DEFINE_ENTRANCE(ENTR_FISHING_POND_0_2, SCENE_FISHING_POND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x462 */ DEFINE_ENTRANCE(ENTR_FISHING_POND_0_3, SCENE_FISHING_POND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x463 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x464 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10_1, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x465 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10_2, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x466 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10_3, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x467 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x468 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_1, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x469 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_2, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x46A */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_3, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x46B */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_4, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x46C */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_5, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x46D */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_6, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x46E */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_7, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x46F */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_8, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x470 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_9, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x471 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_10, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x472 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_1, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x473 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_NIGHT_1_1, SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x474 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_1_2, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x475 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_1_3, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x476 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_15, SCENE_HYRULE_FIELD, 15, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x477 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_15_1, SCENE_HYRULE_FIELD, 15, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x478 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_15_2, SCENE_HYRULE_FIELD, 15, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x479 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_15_3, SCENE_HYRULE_FIELD, 15, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x47A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x47B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5_1, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x47C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5_2, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x47D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5_3, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x47E */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_4, SCENE_HYRULE_CASTLE, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x47F */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_4_1, SCENE_HYRULE_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x480 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_4_2, SCENE_OUTSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x481 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_4_3, SCENE_OUTSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x482 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x483 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3_1, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x484 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3_2, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x485 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3_3, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x486 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_0, SCENE_THIEVES_HIDEOUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x487 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_0_1, SCENE_THIEVES_HIDEOUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x488 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_0_2, SCENE_THIEVES_HIDEOUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x489 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_0_3, SCENE_THIEVES_HIDEOUT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x48A */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_1, SCENE_THIEVES_HIDEOUT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x48B */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_1_1, SCENE_THIEVES_HIDEOUT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x48C */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_1_2, SCENE_THIEVES_HIDEOUT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x48D */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_1_3, SCENE_THIEVES_HIDEOUT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x48E */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_2, SCENE_THIEVES_HIDEOUT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x48F */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_2_1, SCENE_THIEVES_HIDEOUT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x490 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_2_2, SCENE_THIEVES_HIDEOUT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x491 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_2_3, SCENE_THIEVES_HIDEOUT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x492 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_3, SCENE_THIEVES_HIDEOUT, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x493 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_3_1, SCENE_THIEVES_HIDEOUT, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x494 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_3_2, SCENE_THIEVES_HIDEOUT, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x495 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_3_3, SCENE_THIEVES_HIDEOUT, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x496 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_4, SCENE_THIEVES_HIDEOUT, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x497 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_4_1, SCENE_THIEVES_HIDEOUT, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x498 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_4_2, SCENE_THIEVES_HIDEOUT, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x499 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_4_3, SCENE_THIEVES_HIDEOUT, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x49A */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_5, SCENE_THIEVES_HIDEOUT, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x49B */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_5_1, SCENE_THIEVES_HIDEOUT, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x49C */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_5_2, SCENE_THIEVES_HIDEOUT, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x49D */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_5_3, SCENE_THIEVES_HIDEOUT, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x49E */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_6, SCENE_THIEVES_HIDEOUT, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x49F */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_6_1, SCENE_THIEVES_HIDEOUT, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A0 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_6_2, SCENE_THIEVES_HIDEOUT, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A1 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_6_3, SCENE_THIEVES_HIDEOUT, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4A2 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_7, SCENE_THIEVES_HIDEOUT, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A3 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_7_1, SCENE_THIEVES_HIDEOUT, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A4 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_7_2, SCENE_THIEVES_HIDEOUT, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A5 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_7_3, SCENE_THIEVES_HIDEOUT, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4A6 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_8, SCENE_THIEVES_HIDEOUT, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A7 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_8_1, SCENE_THIEVES_HIDEOUT, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A8 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_8_2, SCENE_THIEVES_HIDEOUT, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4A9 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_8_3, SCENE_THIEVES_HIDEOUT, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4AA */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_9, SCENE_THIEVES_HIDEOUT, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4AB */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_9_1, SCENE_THIEVES_HIDEOUT, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4AC */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_9_2, SCENE_THIEVES_HIDEOUT, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4AD */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_9_3, SCENE_THIEVES_HIDEOUT, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4AE */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_10, SCENE_THIEVES_HIDEOUT, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4AF */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_10_1, SCENE_THIEVES_HIDEOUT, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B0 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_10_2, SCENE_THIEVES_HIDEOUT, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B1 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_10_3, SCENE_THIEVES_HIDEOUT, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4B2 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_11, SCENE_THIEVES_HIDEOUT, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B3 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_11_1, SCENE_THIEVES_HIDEOUT, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B4 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_11_2, SCENE_THIEVES_HIDEOUT, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B5 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_11_3, SCENE_THIEVES_HIDEOUT, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4B6 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_7, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B7 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_7_1, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B8 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_7_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4B9 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_7_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4BA */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4BB */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_1_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4BC */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_1_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4BD */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_1_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4BE */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4BF */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C0 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C1 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4C2 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C3 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C4 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C5 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4C6 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_4, SCENE_LOST_WOODS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C7 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_4_1, SCENE_LOST_WOODS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C8 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_4_2, SCENE_LOST_WOODS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C9 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_4_3, SCENE_LOST_WOODS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4CA */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_6, SCENE_LON_LON_RANCH, 6, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x4CB */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_6_1, SCENE_LON_LON_RANCH, 6, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x4CC */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_6_2, SCENE_LON_LON_RANCH, 6, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x4CD */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_6_3, SCENE_LON_LON_RANCH, 6, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) + +/* 0x4CE */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_7, SCENE_LON_LON_RANCH, 7, false, false, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST)) +/* 0x4CF */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_7_1, SCENE_LON_LON_RANCH, 7, false, false, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST)) +/* 0x4D0 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_7_2, SCENE_LON_LON_RANCH, 7, false, false, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST)) +/* 0x4D1 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_7_3, SCENE_LON_LON_RANCH, 7, false, false, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_WHITE, TCS_FAST)) + +/* 0x4D2 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_5, SCENE_LOST_WOODS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4D3 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_5_1, SCENE_LOST_WOODS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4D4 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_5_2, SCENE_LOST_WOODS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4D5 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_5_3, SCENE_LOST_WOODS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4D6 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4D7 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6_1, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4D8 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6_2, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4D9 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6_3, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) + +/* 0x4DA */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4DB */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7_1, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4DC */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7_2, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4DD */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7_3, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) + +/* 0x4DE */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4DF */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8_1, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4E0 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8_2, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4E1 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8_3, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4E2 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4E3 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3_1, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4E4 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3_2, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4E5 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3_3, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) + +/* 0x4E6 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_5, SCENE_LAKE_HYLIA, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4E7 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_5_1, SCENE_LAKE_HYLIA, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4E8 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_5_2, SCENE_LAKE_HYLIA, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4E9 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_5_3, SCENE_LAKE_HYLIA, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4EA */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_3, SCENE_SHADOW_TEMPLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4EB */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_3_1, SCENE_SHADOW_TEMPLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4EC */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_3_2, SCENE_SHADOW_TEMPLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4ED */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_3_3, SCENE_SHADOW_TEMPLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4EE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x4EF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11_1, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x4F0 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11_2, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x4F1 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11_3, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x4F2 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4F3 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_3_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4F4 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_3_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4F5 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_3_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4F6 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4F7 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4_1, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4F8 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4_2, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4F9 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4_3, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x4FA */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_3, SCENE_HYRULE_CASTLE, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x4FB */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_3_1, SCENE_HYRULE_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4FC */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_3_2, SCENE_OUTSIDE_GANONS_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4FD */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_3_3, SCENE_OUTSIDE_GANONS_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4FE */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_3_4, SCENE_HYRULE_CASTLE, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) + +/* 0x4FF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x500 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12_1, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x501 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12_2, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x502 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12_3, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x503 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_2, SCENE_WINDMILL_AND_DAMPES_GRAVE, 2, true, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x504 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_2_1, SCENE_WINDMILL_AND_DAMPES_GRAVE, 2, true, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x505 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_2_2, SCENE_WINDMILL_AND_DAMPES_GRAVE, 2, true, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x506 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_2_3, SCENE_WINDMILL_AND_DAMPES_GRAVE, 2, true, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x507 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_BOWLING_ALLEY_0, SCENE_BOMBCHU_BOWLING_ALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x508 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_BOWLING_ALLEY_0_1, SCENE_BOMBCHU_BOWLING_ALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x509 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_BOWLING_ALLEY_0_2, SCENE_BOMBCHU_BOWLING_ALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x50A */ DEFINE_ENTRANCE(ENTR_BOMBCHU_BOWLING_ALLEY_0_3, SCENE_BOMBCHU_BOWLING_ALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x50B */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x50C */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6_1, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x50D */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6_2, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x50E */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6_3, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x50F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_16, SCENE_HYRULE_FIELD, 16, false, true, TRANS_TYPE_INSTANT, TRANS_TYPE_INSTANT) +/* 0x510 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_16_1, SCENE_HYRULE_FIELD, 16, false, true, TRANS_TYPE_INSTANT, TRANS_TYPE_INSTANT) +/* 0x511 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_16_2, SCENE_HYRULE_FIELD, 16, false, true, TRANS_TYPE_INSTANT, TRANS_TYPE_INSTANT) +/* 0x512 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_16_3, SCENE_HYRULE_FIELD, 16, false, true, TRANS_TYPE_INSTANT, TRANS_TYPE_INSTANT) + +/* 0x513 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_13, SCENE_KAKARIKO_VILLAGE, 13, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x514 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_13_1, SCENE_KAKARIKO_VILLAGE, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x515 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_13_2, SCENE_KAKARIKO_VILLAGE, 13, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x516 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_13_3, SCENE_KAKARIKO_VILLAGE, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x517 */ DEFINE_ENTRANCE(ENTR_GANON_BOSS_0, SCENE_GANON_BOSS, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x518 */ DEFINE_ENTRANCE(ENTR_GANON_BOSS_0_1, SCENE_GANON_BOSS, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x519 */ DEFINE_ENTRANCE(ENTR_GANON_BOSS_0_2, SCENE_GANON_BOSS, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x51A */ DEFINE_ENTRANCE(ENTR_GANON_BOSS_0_3, SCENE_GANON_BOSS, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x51B */ DEFINE_ENTRANCE(ENTR_GANON_BOSS_0_4, SCENE_GANON_BOSS, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x51C */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_6, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x51D */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_6_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x51E */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_6_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x51F */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_6_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 6, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x520 */ DEFINE_ENTRANCE(ENTR_BESITU_0, SCENE_BESITU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x521 */ DEFINE_ENTRANCE(ENTR_BESITU_0_1, SCENE_BESITU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x522 */ DEFINE_ENTRANCE(ENTR_BESITU_0_2, SCENE_BESITU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x523 */ DEFINE_ENTRANCE(ENTR_BESITU_0_3, SCENE_BESITU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x524 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_7, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x525 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_7_1, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x526 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_7_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x527 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_7_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 7, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x528 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_1, SCENE_BOMBCHU_SHOP, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x529 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_1_1, SCENE_BOMBCHU_SHOP, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x52A */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_1_2, SCENE_BOMBCHU_SHOP, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x52B */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_1_3, SCENE_BOMBCHU_SHOP, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x52C */ DEFINE_ENTRANCE(ENTR_BAZAAR_1, SCENE_BAZAAR, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x52D */ DEFINE_ENTRANCE(ENTR_BAZAAR_1_1, SCENE_BAZAAR, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x52E */ DEFINE_ENTRANCE(ENTR_BAZAAR_1_2, SCENE_BAZAAR, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x52F */ DEFINE_ENTRANCE(ENTR_BAZAAR_1_3, SCENE_BAZAAR, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x530 */ DEFINE_ENTRANCE(ENTR_HAPPY_MASK_SHOP_0, SCENE_HAPPY_MASK_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x531 */ DEFINE_ENTRANCE(ENTR_HAPPY_MASK_SHOP_0_1, SCENE_HAPPY_MASK_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x532 */ DEFINE_ENTRANCE(ENTR_HAPPY_MASK_SHOP_0_2, SCENE_HAPPY_MASK_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x533 */ DEFINE_ENTRANCE(ENTR_HAPPY_MASK_SHOP_0_3, SCENE_HAPPY_MASK_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x534 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_1, SCENE_INSIDE_GANONS_CASTLE, 1, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x535 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_1_1, SCENE_INSIDE_GANONS_CASTLE, 1, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x536 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_1_2, SCENE_INSIDE_GANONS_CASTLE, 1, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x537 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_1_3, SCENE_INSIDE_GANONS_CASTLE, 1, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x538 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_2, SCENE_INSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x539 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_2_1, SCENE_INSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x53A */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_2_2, SCENE_INSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x53B */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_2_3, SCENE_INSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x53C */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_3, SCENE_INSIDE_GANONS_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x53D */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_3_1, SCENE_INSIDE_GANONS_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x53E */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_3_2, SCENE_INSIDE_GANONS_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x53F */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_3_3, SCENE_INSIDE_GANONS_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x540 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_4, SCENE_INSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x541 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_4_1, SCENE_INSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x542 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_4_2, SCENE_INSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x543 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_4_3, SCENE_INSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x544 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_5, SCENE_INSIDE_GANONS_CASTLE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x545 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_5_1, SCENE_INSIDE_GANONS_CASTLE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x546 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_5_2, SCENE_INSIDE_GANONS_CASTLE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x547 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_5_3, SCENE_INSIDE_GANONS_CASTLE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x548 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_6, SCENE_INSIDE_GANONS_CASTLE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x549 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_6_1, SCENE_INSIDE_GANONS_CASTLE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x54A */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_6_2, SCENE_INSIDE_GANONS_CASTLE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x54B */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_6_3, SCENE_INSIDE_GANONS_CASTLE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x54C */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_7, SCENE_INSIDE_GANONS_CASTLE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x54D */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_7_1, SCENE_INSIDE_GANONS_CASTLE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x54E */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_7_2, SCENE_INSIDE_GANONS_CASTLE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x54F */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_7_3, SCENE_INSIDE_GANONS_CASTLE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x550 */ DEFINE_ENTRANCE(ENTR_HOUSE_OF_SKULLTULA_0, SCENE_HOUSE_OF_SKULLTULA, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x551 */ DEFINE_ENTRANCE(ENTR_HOUSE_OF_SKULLTULA_0_1, SCENE_HOUSE_OF_SKULLTULA, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x552 */ DEFINE_ENTRANCE(ENTR_HOUSE_OF_SKULLTULA_0_2, SCENE_HOUSE_OF_SKULLTULA, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x553 */ DEFINE_ENTRANCE(ENTR_HOUSE_OF_SKULLTULA_0_3, SCENE_HOUSE_OF_SKULLTULA, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x554 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x555 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14_1, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x556 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14_2, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x557 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14_3, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x558 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_8, SCENE_LON_LON_RANCH, 8, false, false, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x559 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_8_1, SCENE_LON_LON_RANCH, 8, false, false, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x55A */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_8_2, SCENE_LON_LON_RANCH, 8, false, false, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x55B */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_8_3, SCENE_LON_LON_RANCH, 8, false, false, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x55C */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_9, SCENE_LON_LON_RANCH, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x55D */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_9_1, SCENE_LON_LON_RANCH, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x55E */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_9_2, SCENE_LON_LON_RANCH, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x55F */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_9_3, SCENE_LON_LON_RANCH, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x560 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x561 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7_1, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x562 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7_2, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x563 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7_3, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) + +/* 0x564 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x565 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5_1, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x566 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5_2, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x567 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5_3, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x568 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x569 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7_1, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x56A */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7_2, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x56B */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7_3, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x56C */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_COLLAPSE_0, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x56D */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_COLLAPSE_0_1, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x56E */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_COLLAPSE_0_2, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x56F */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_COLLAPSE_0_3, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x570 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_12, SCENE_THIEVES_HIDEOUT, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x571 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_12_1, SCENE_THIEVES_HIDEOUT, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x572 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_12_2, SCENE_THIEVES_HIDEOUT, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x573 */ DEFINE_ENTRANCE(ENTR_THIEVES_HIDEOUT_12_3, SCENE_THIEVES_HIDEOUT, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x574 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_1, SCENE_ROYAL_FAMILYS_TOMB, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x575 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_1_1, SCENE_ROYAL_FAMILYS_TOMB, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x576 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_1_2, SCENE_ROYAL_FAMILYS_TOMB, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x577 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_1_3, SCENE_ROYAL_FAMILYS_TOMB, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x578 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x579 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x57A */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x57B */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1_3, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x57C */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x57D */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7_1, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x57E */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7_2, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x57F */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7_3, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x580 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x581 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8_1, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x582 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8_2, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x583 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8_3, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x584 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_2, SCENE_FOREST_TEMPLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x585 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_2_1, SCENE_FOREST_TEMPLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x586 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_2_2, SCENE_FOREST_TEMPLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x587 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_2_3, SCENE_FOREST_TEMPLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x588 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x589 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x58A */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x58B */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2_3, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x58C */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_5, SCENE_TEMPLE_OF_TIME, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x58D */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_5_1, SCENE_TEMPLE_OF_TIME, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x58E */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_5_2, SCENE_TEMPLE_OF_TIME, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x58F */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_5_3, SCENE_TEMPLE_OF_TIME, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x590 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_6, SCENE_TEMPLE_OF_TIME, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x591 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_6_1, SCENE_TEMPLE_OF_TIME, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x592 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_6_2, SCENE_TEMPLE_OF_TIME, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x593 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_6_3, SCENE_TEMPLE_OF_TIME, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x594 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_17, SCENE_HYRULE_FIELD, 17, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x595 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_17_1, SCENE_HYRULE_FIELD, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x596 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_17_2, SCENE_HYRULE_FIELD, 17, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x597 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_17_3, SCENE_HYRULE_FIELD, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x598 */ DEFINE_ENTRANCE(ENTR_GROTTOS_1, SCENE_GROTTOS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x599 */ DEFINE_ENTRANCE(ENTR_GROTTOS_1_1, SCENE_GROTTOS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x59A */ DEFINE_ENTRANCE(ENTR_GROTTOS_1_2, SCENE_GROTTOS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x59B */ DEFINE_ENTRANCE(ENTR_GROTTOS_1_3, SCENE_GROTTOS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x59C */ DEFINE_ENTRANCE(ENTR_GROTTOS_2, SCENE_GROTTOS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x59D */ DEFINE_ENTRANCE(ENTR_GROTTOS_2_1, SCENE_GROTTOS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x59E */ DEFINE_ENTRANCE(ENTR_GROTTOS_2_2, SCENE_GROTTOS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x59F */ DEFINE_ENTRANCE(ENTR_GROTTOS_2_3, SCENE_GROTTOS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5A0 */ DEFINE_ENTRANCE(ENTR_GROTTOS_3, SCENE_GROTTOS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5A1 */ DEFINE_ENTRANCE(ENTR_GROTTOS_3_1, SCENE_GROTTOS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5A2 */ DEFINE_ENTRANCE(ENTR_GROTTOS_3_2, SCENE_GROTTOS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5A3 */ DEFINE_ENTRANCE(ENTR_GROTTOS_3_3, SCENE_GROTTOS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5A4 */ DEFINE_ENTRANCE(ENTR_GROTTOS_4, SCENE_GROTTOS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5A5 */ DEFINE_ENTRANCE(ENTR_GROTTOS_4_1, SCENE_GROTTOS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5A6 */ DEFINE_ENTRANCE(ENTR_GROTTOS_4_2, SCENE_GROTTOS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5A7 */ DEFINE_ENTRANCE(ENTR_GROTTOS_4_3, SCENE_GROTTOS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5A8 */ DEFINE_ENTRANCE(ENTR_GROTTOS_5, SCENE_GROTTOS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_WHITE) +/* 0x5A9 */ DEFINE_ENTRANCE(ENTR_GROTTOS_5_1, SCENE_GROTTOS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_WHITE) +/* 0x5AA */ DEFINE_ENTRANCE(ENTR_GROTTOS_5_2, SCENE_GROTTOS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_WHITE) +/* 0x5AB */ DEFINE_ENTRANCE(ENTR_GROTTOS_5_3, SCENE_GROTTOS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_WHITE) + +/* 0x5AC */ DEFINE_ENTRANCE(ENTR_GROTTOS_6, SCENE_GROTTOS, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5AD */ DEFINE_ENTRANCE(ENTR_GROTTOS_6_1, SCENE_GROTTOS, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5AE */ DEFINE_ENTRANCE(ENTR_GROTTOS_6_2, SCENE_GROTTOS, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5AF */ DEFINE_ENTRANCE(ENTR_GROTTOS_6_3, SCENE_GROTTOS, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5B0 */ DEFINE_ENTRANCE(ENTR_GROTTOS_7, SCENE_GROTTOS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5B1 */ DEFINE_ENTRANCE(ENTR_GROTTOS_7_1, SCENE_GROTTOS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5B2 */ DEFINE_ENTRANCE(ENTR_GROTTOS_7_2, SCENE_GROTTOS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5B3 */ DEFINE_ENTRANCE(ENTR_GROTTOS_7_3, SCENE_GROTTOS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5B4 */ DEFINE_ENTRANCE(ENTR_GROTTOS_8, SCENE_GROTTOS, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5B5 */ DEFINE_ENTRANCE(ENTR_GROTTOS_8_1, SCENE_GROTTOS, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5B6 */ DEFINE_ENTRANCE(ENTR_GROTTOS_8_2, SCENE_GROTTOS, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5B7 */ DEFINE_ENTRANCE(ENTR_GROTTOS_8_3, SCENE_GROTTOS, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5B8 */ DEFINE_ENTRANCE(ENTR_GROTTOS_9, SCENE_GROTTOS, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5B9 */ DEFINE_ENTRANCE(ENTR_GROTTOS_9_1, SCENE_GROTTOS, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5BA */ DEFINE_ENTRANCE(ENTR_GROTTOS_9_2, SCENE_GROTTOS, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5BB */ DEFINE_ENTRANCE(ENTR_GROTTOS_9_3, SCENE_GROTTOS, 9, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5BC */ DEFINE_ENTRANCE(ENTR_GROTTOS_10, SCENE_GROTTOS, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5BD */ DEFINE_ENTRANCE(ENTR_GROTTOS_10_1, SCENE_GROTTOS, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5BE */ DEFINE_ENTRANCE(ENTR_GROTTOS_10_2, SCENE_GROTTOS, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5BF */ DEFINE_ENTRANCE(ENTR_GROTTOS_10_3, SCENE_GROTTOS, 10, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5C0 */ DEFINE_ENTRANCE(ENTR_GROTTOS_11, SCENE_GROTTOS, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5C1 */ DEFINE_ENTRANCE(ENTR_GROTTOS_11_1, SCENE_GROTTOS, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5C2 */ DEFINE_ENTRANCE(ENTR_GROTTOS_11_2, SCENE_GROTTOS, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5C3 */ DEFINE_ENTRANCE(ENTR_GROTTOS_11_3, SCENE_GROTTOS, 11, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5C4 */ DEFINE_ENTRANCE(ENTR_GROTTOS_12, SCENE_GROTTOS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5C5 */ DEFINE_ENTRANCE(ENTR_GROTTOS_12_1, SCENE_GROTTOS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5C6 */ DEFINE_ENTRANCE(ENTR_GROTTOS_12_2, SCENE_GROTTOS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5C7 */ DEFINE_ENTRANCE(ENTR_GROTTOS_12_3, SCENE_GROTTOS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5C8 */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5C9 */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1_1, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5CA */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1_2, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5CB */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1_3, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x5CC */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_1, SCENE_BOTTOM_OF_THE_WELL, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x5CD */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_1_1, SCENE_BOTTOM_OF_THE_WELL, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x5CE */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_1_2, SCENE_BOTTOM_OF_THE_WELL, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x5CF */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_1_3, SCENE_BOTTOM_OF_THE_WELL, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) + +/* 0x5D0 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5D1 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1_1, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5D2 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1_2, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5D3 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1_3, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x5D4 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x5D5 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10_1, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x5D6 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10_2, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x5D7 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10_3, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x5D8 */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_1, SCENE_ICE_CAVERN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5D9 */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_1_1, SCENE_ICE_CAVERN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5DA */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_1_2, SCENE_ICE_CAVERN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5DB */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_1_3, SCENE_ICE_CAVERN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5DC */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x5DD */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15_1, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5DE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15_2, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x5DF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15_3, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5E0 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5E1 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9_1, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5E2 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9_2, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5E3 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9_3, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5E4 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_2, SCENE_LON_LON_BUILDINGS, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5E5 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_2_1, SCENE_LON_LON_BUILDINGS, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5E6 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_2_2, SCENE_LON_LON_BUILDINGS, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5E7 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_2_3, SCENE_LON_LON_BUILDINGS, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) + +/* 0x5E8 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_12, SCENE_KOKIRI_FOREST, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x5E9 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_12_1, SCENE_KOKIRI_FOREST, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x5EA */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_12_2, SCENE_KOKIRI_FOREST, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x5EB */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_12_3, SCENE_KOKIRI_FOREST, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) + +/* 0x5EC */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_2, SCENE_SPIRIT_TEMPLE_BOSS, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5ED */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_2_1, SCENE_SPIRIT_TEMPLE_BOSS, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5EE */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_2_2, SCENE_SPIRIT_TEMPLE_BOSS, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5EF */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_2_3, SCENE_SPIRIT_TEMPLE_BOSS, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5F0 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_1, SCENE_CASTLE_COURTYARD_ZELDA, 1, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x5F1 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_1_1, SCENE_CASTLE_COURTYARD_ZELDA, 1, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5F2 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_1_2, SCENE_CASTLE_COURTYARD_ZELDA, 1, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x5F3 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_1_3, SCENE_CASTLE_COURTYARD_ZELDA, 1, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5F4 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5F5 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7_1, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5F6 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7_2, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5F7 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7_3, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5F8 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_18, SCENE_GERUDOS_FORTRESS, 18, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5F9 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_18_1, SCENE_GERUDOS_FORTRESS, 18, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5FA */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_18_2, SCENE_GERUDOS_FORTRESS, 18, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5FB */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_18_3, SCENE_GERUDOS_FORTRESS, 18, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x5FC */ DEFINE_ENTRANCE(ENTR_GROTTOS_13, SCENE_GROTTOS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5FD */ DEFINE_ENTRANCE(ENTR_GROTTOS_13_1, SCENE_GROTTOS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5FE */ DEFINE_ENTRANCE(ENTR_GROTTOS_13_2, SCENE_GROTTOS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5FF */ DEFINE_ENTRANCE(ENTR_GROTTOS_13_3, SCENE_GROTTOS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x600 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) +/* 0x601 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2_1, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x602 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2_2, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) +/* 0x603 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2_3, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x604 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x605 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8_1, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x606 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8_2, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x607 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8_3, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) + +/* 0x608 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x609 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3_1, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x60A */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3_2, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x60B */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3_3, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x60C */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x60D */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9_1, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x60E */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9_2, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x60F */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9_3, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) + +/* 0x610 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x611 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8_1, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x612 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8_2, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x613 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8_3, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) \ No newline at end of file diff --git a/soh/include/variables.h b/soh/include/variables.h index 2bad8335c..9fd6b7247 100644 --- a/soh/include/variables.h +++ b/soh/include/variables.h @@ -107,7 +107,7 @@ extern "C" extern s16 gLinkObjectIds[2]; extern u32 gObjectTableSize; extern RomFile gObjectTable[OBJECT_ID_MAX]; - extern EntranceInfo gEntranceTable[1556]; + extern EntranceInfo gEntranceTable[ENTR_MAX]; extern SceneTableEntry gSceneTable[SCENE_ID_MAX]; extern u16 gSramSlotOffsets[]; // 4 16-colors palettes @@ -224,7 +224,7 @@ extern "C" extern u16 gAudioSfxSwapSource[10]; extern u16 gAudioSfxSwapTarget[10]; extern u8 gAudioSfxSwapMode[10]; - extern unk_D_8016E750 D_8016E750[4]; + extern ActiveSequence gActiveSeqs[4]; extern AudioContext gAudioContext; extern void(*D_801755D0)(void); diff --git a/soh/include/z64.h b/soh/include/z64.h index f790dddc7..bad2e1ca7 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -1122,6 +1122,82 @@ typedef struct { /* 0x4C */ u32 unk_4C; } 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 { union { TransitionFade fade; @@ -1384,14 +1460,14 @@ typedef struct PlayState { /* 0x11E0C */ ElfMessage* cUpElfMsgs; /* 0x11E10 */ void* specialEffects; /* 0x11E14 */ u8 skyboxId; - /* 0x11E15 */ s8 sceneLoadFlag; // "fade_direction" + /* 0x11E15 */ s8 transitionTrigger; // "fade_direction" /* 0x11E16 */ s16 unk_11E16; /* 0x11E18 */ s16 unk_11E18; /* 0x11E1A */ s16 nextEntranceIndex; /* 0x11E1C */ char unk_11E1C[0x40]; /* 0x11E5C */ s8 shootingGalleryStatus; /* 0x11E5D */ s8 bombchuBowlingStatus; // "bombchu_game_flag" - /* 0x11E5E */ u8 fadeTransition; + /* 0x11E5E */ u8 transitionType; /* 0x11E60 */ CollisionCheckContext colChkCtx; /* 0x120FC */ u16 envFlags[20]; /* 0x12124 */ PreRender pauseBgPreRender; @@ -1513,6 +1589,20 @@ typedef struct { uint16_t bossRushArrowOffset; } 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 { DPM_UNK = 0, DPM_PLAYER = 1, diff --git a/soh/include/z64audio.h b/soh/include/z64audio.h index a7587ea2c..81775feba 100644 --- a/soh/include/z64audio.h +++ b/soh/include/z64audio.h @@ -970,43 +970,43 @@ typedef struct { } AudioContextInitSizes; // size = 0xC typedef struct { - /* 0x00 */ f32 unk_00; - /* 0x04 */ f32 unk_04; - /* 0x08 */ f32 unk_08; - /* 0x0C */ u16 unk_0C; - /* 0x10 */ f32 unk_10; - /* 0x14 */ f32 unk_14; - /* 0x18 */ f32 unk_18; - /* 0x1C */ u16 unk_1C; -} unk_50_s; // size = 0x20 + /* 0x00 */ f32 volCur; + /* 0x04 */ f32 volTarget; + /* 0x08 */ f32 volStep; + /* 0x0C */ u16 volTimer; + /* 0x10 */ f32 freqScaleCur; + /* 0x14 */ f32 freqScaleTarget; + /* 0x18 */ f32 freqScaleStep; + /* 0x1C */ u16 freqScaleTimer; +} ActiveSequenceChannelData; // size = 0x20 typedef struct { /* 0x000 */ f32 volCur; /* 0x004 */ f32 volTarget; - /* 0x008 */ f32 unk_08; - /* 0x00C */ u16 unk_0C; - /* 0x00E */ u8 volScales[0x4]; + /* 0x008 */ f32 volStep; + /* 0x00C */ u16 volTimer; + /* 0x00E */ u8 volScales[4]; /* 0x012 */ u8 volFadeTimer; /* 0x013 */ u8 fadeVolUpdate; - /* 0x014 */ u32 unk_14; - /* 0x018 */ u16 unk_18; - /* 0x01C */ f32 unk_1C; - /* 0x020 */ f32 unk_20; - /* 0x024 */ f32 unk_24; - /* 0x028 */ u16 unk_28; - /* 0x02C */ u32 unk_2C[8]; - /* 0x04C */ u8 unk_4C; - /* 0x04D */ u8 unk_4D; - /* 0x04E */ u8 unk_4E; - /* 0x050 */ unk_50_s unk_50[0x10]; - /* 0x250 */ u16 unk_250; - /* 0x252 */ u16 unk_252; - /* 0x254 */ u16 unk_254; - /* 0x256 */ u16 unk_256; - /* 0x258 */ u16 unk_258; - /* 0x25C */ u32 unk_25C; - /* 0x260 */ u8 unk_260; -} unk_D_8016E750; // size = 0x264 + /* 0x014 */ u32 tempoCmd; + /* 0x018 */ u16 tempoOriginal; // stores the original tempo before modifying it (to reset back to) + /* 0x01C */ f32 tempoCur; + /* 0x020 */ f32 tempoTarget; + /* 0x024 */ f32 tempoStep; + /* 0x028 */ u16 tempoTimer; + /* 0x02C */ u32 setupCmd[8]; // a queue of cmds to execute once the player is disabled + /* 0x04C */ u8 setupCmdTimer; // only execute setup commands when the timer is at 0. + /* 0x04D */ u8 setupCmdNum; // number of setup commands requested once the player is disabled + /* 0x04E */ u8 setupFadeTimer; + /* 0x050 */ ActiveSequenceChannelData channelData[16]; + /* 0x250 */ u16 freqScaleChannelFlags; + /* 0x252 */ u16 volChannelFlags; + /* 0x254 */ u16 seqId; // active seqId currently playing. Resets when sequence stops + /* 0x256 */ u16 prevSeqId; // last seqId played on a player. Does not reset when sequence stops + /* 0x258 */ u16 channelPortMask; + /* 0x25C */ u32 startSeqCmd; // This name comes from MM + /* 0x260 */ u8 isWaitingForFonts; // This name comes from MM +} ActiveSequence; // size = 0x264 typedef enum { /* 0 */ BANK_PLAYER, diff --git a/soh/include/z64environment.h b/soh/include/z64environment.h index b2badccd3..8cb69ddc4 100644 --- a/soh/include/z64environment.h +++ b/soh/include/z64environment.h @@ -30,6 +30,14 @@ typedef enum { /* 13 */ SKYBOX_DMA_PAL2_START } SkyboxDmaState; +typedef enum { + /* 0 */ SANDSTORM_OFF, + /* 1 */ SANDSTORM_FILL, + /* 2 */ SANDSTORM_UNFILL, + /* 3 */ SANDSTORM_ACTIVE, + /* 4 */ SANDSTORM_DISSIPATE +} SandstormState; + typedef struct { /* 0x00 */ u8 state; /* 0x01 */ u8 flashRed; diff --git a/soh/include/z64player.h b/soh/include/z64player.h index ff30cc170..d03b64da5 100644 --- a/soh/include/z64player.h +++ b/soh/include/z64player.h @@ -132,16 +132,6 @@ typedef enum { /* 0x40 */ PLAYER_IA_MASK_GERUDO, /* 0x41 */ PLAYER_IA_MASK_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 } PlayerItemAction; @@ -355,7 +345,7 @@ typedef enum { #define PLAYER_LIMB_BUF_COUNT LIMB_BUF_COUNT(PLAYER_LIMB_MAX) typedef struct { - /* 0x00 */ f32 unk_00; + /* 0x00 */ f32 ceilingCheckHeight; /* 0x04 */ f32 unk_04; /* 0x08 */ f32 unk_08; /* 0x0C */ f32 unk_0C; @@ -369,7 +359,7 @@ typedef struct { /* 0x2C */ f32 unk_2C; /* 0x30 */ f32 unk_30; /* 0x34 */ f32 unk_34; - /* 0x38 */ f32 unk_38; + /* 0x38 */ f32 wallCheckRadius; /* 0x3C */ f32 unk_3C; /* 0x40 */ f32 unk_40; /* 0x44 */ Vec3s unk_44; @@ -494,185 +484,192 @@ 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_HOOKSHOT_TRAVELLING (1 << 7) //Travelling to target -typedef void (*PlayerFunc674)(struct Player*, struct PlayState*); -typedef s32 (*PlayerFunc82C)(struct Player*, struct PlayState*); +typedef void (*PlayerActionFunc)(struct Player*, struct PlayState*); +typedef s32 (*UpperActionFunc)(struct Player*, struct PlayState*); typedef void (*PlayerFuncA74)(struct PlayState*, struct Player*); typedef struct Player { - /* 0x0000 */ Actor actor; - /* 0x014C */ s8 currentTunic; // current tunic from `PlayerTunic` - /* 0x014D */ s8 currentSwordItemId; - /* 0x014E */ s8 currentShield; // current shield from `PlayerShield` - /* 0x014F */ s8 currentBoots; // current boots from `PlayerBoots` - /* 0x0150 */ s8 heldItemButton; // Button index for the item currently used - /* 0x0151 */ s8 heldItemAction; // Item action for the item currently used - /* 0x0152 */ u8 heldItemId; // Item id for the item currently used - /* 0x0153 */ s8 prevBoots; // previous boots from `PlayerBoots` - /* 0x0154 */ s8 itemAction; // the difference between this and heldItemAction is unclear - /* 0x0155 */ char unk_155[0x003]; - /* 0x0158 */ u8 modelGroup; - /* 0x0159 */ u8 nextModelGroup; - /* 0x015A */ s8 unk_15A; - /* 0x015B */ u8 modelAnimType; - /* 0x015C */ u8 leftHandType; - /* 0x015D */ u8 rightHandType; - /* 0x015E */ u8 sheathType; - /* 0x015F */ u8 currentMask; // current mask equipped from `PlayerMask` - /* 0x0160 */ Gfx** rightHandDLists; - /* 0x0164 */ Gfx** leftHandDLists; - /* 0x0168 */ Gfx** sheathDLists; - /* 0x016C */ Gfx** waistDLists; - /* 0x0170 */ u8 giObjectLoading; + /* 0x0000 */ Actor actor; + /* 0x014C */ s8 currentTunic; // current tunic from `PlayerTunic` + /* 0x014D */ s8 currentSwordItemId; + /* 0x014E */ s8 currentShield; // current shield from `PlayerShield` + /* 0x014F */ s8 currentBoots; // current boots from `PlayerBoots` + /* 0x0150 */ s8 heldItemButton; // Button index for the item currently used + /* 0x0151 */ s8 heldItemAction; // Item action for the item currently used + /* 0x0152 */ u8 heldItemId; // Item id for the item currently used + /* 0x0153 */ s8 prevBoots; // previous boots from `PlayerBoots` + /* 0x0154 */ s8 itemAction; // the difference between this and heldItemAction is unclear + /* 0x0155 */ char unk_155[0x003]; + /* 0x0158 */ u8 modelGroup; + /* 0x0159 */ u8 nextModelGroup; + /* 0x015A */ s8 itemChangeType; + /* 0x015B */ u8 modelAnimType; + /* 0x015C */ u8 leftHandType; + /* 0x015D */ u8 rightHandType; + /* 0x015E */ u8 sheathType; + /* 0x015F */ u8 currentMask; // current mask equipped from `PlayerMask` + /* 0x0160 */ Gfx** rightHandDLists; + /* 0x0164 */ Gfx** leftHandDLists; + /* 0x0168 */ Gfx** sheathDLists; + /* 0x016C */ Gfx** waistDLists; + /* 0x0170 */ u8 giObjectLoading; /* 0x0174 */ DmaRequest giObjectDmaRequest; /* 0x0194 */ OSMesgQueue giObjectLoadQueue; - /* 0x01AC */ OSMesg giObjectLoadMsg; - /* 0x01B0 */ void* giObjectSegment; // also used for title card textures - /* 0x01B4 */ SkelAnime skelAnime; - /* 0x01F8 */ Vec3s jointTable[PLAYER_LIMB_BUF_COUNT]; - /* 0x0288 */ Vec3s morphTable[PLAYER_LIMB_BUF_COUNT]; - /* 0x0318 */ Vec3s blendTable[PLAYER_LIMB_BUF_COUNT]; - /* 0x03A8 */ s16 unk_3A8[2]; - /* 0x03AC */ Actor* heldActor; - /* 0x03B0 */ Vec3f leftHandPos; - /* 0x03BC */ Vec3s unk_3BC; - /* 0x03C4 */ Actor* unk_3C4; - /* 0x03C8 */ Vec3f unk_3C8; - /* 0x03D4 */ char unk_3D4[0x058]; - /* 0x042C */ s8 doorType; - /* 0x042D */ s8 doorDirection; - /* 0x042E */ s16 doorTimer; - /* 0x0430 */ Actor* doorActor; - /* 0x0434 */ s16 getItemId; // Upstream TODO: Document why this is s16 while it's s8 upstream - /* 0x0436 */ u16 getItemDirection; - /* 0x0438 */ Actor* interactRangeActor; - /* 0x043C */ s8 mountSide; - /* 0x043D */ char unk_43D[0x003]; - /* 0x0440 */ Actor* rideActor; - /* 0x0444 */ u8 csMode; - /* 0x0445 */ u8 prevCsMode; - /* 0x0446 */ u8 unk_446; - /* 0x0447 */ u8 unk_447; - /* 0x0448 */ Actor* unk_448; - /* 0x044C */ char unk_44C[0x004]; - /* 0x0450 */ Vec3f unk_450; - /* 0x045C */ Vec3f unk_45C; - /* 0x0468 */ char unk_468[0x002]; - /* 0x046A */ s16 doorBgCamIndex; - /* 0x046C */ s16 subCamId; - /* 0x046E */ char unk_46E[0x02A]; + /* 0x01AC */ OSMesg giObjectLoadMsg; + /* 0x01B0 */ void* giObjectSegment; // also used for title card textures + /* 0x01B4 */ SkelAnime skelAnime; + /* 0x01F8 */ Vec3s jointTable[PLAYER_LIMB_BUF_COUNT]; + /* 0x0288 */ Vec3s morphTable[PLAYER_LIMB_BUF_COUNT]; + /* 0x0318 */ Vec3s blendTable[PLAYER_LIMB_BUF_COUNT]; + /* 0x03A8 */ s16 unk_3A8[2]; + /* 0x03AC */ Actor* heldActor; + /* 0x03B0 */ Vec3f leftHandPos; + /* 0x03BC */ Vec3s unk_3BC; + /* 0x03C4 */ Actor* unk_3C4; + /* 0x03C8 */ Vec3f unk_3C8; + /* 0x03D4 */ char unk_3D4[0x058]; + /* 0x042C */ s8 doorType; + /* 0x042D */ s8 doorDirection; + /* 0x042E */ s16 doorTimer; + /* 0x0430 */ Actor* doorActor; + /* 0x0434 */ s16 getItemId; // Upstream TODO: Document why this is s16 while it's s8 upstream + /* 0x0436 */ u16 getItemDirection; + /* 0x0438 */ Actor* interactRangeActor; + /* 0x043C */ s8 mountSide; + /* 0x043D */ char unk_43D[0x003]; + /* 0x0440 */ Actor* rideActor; + /* 0x0444 */ u8 csAction; + /* 0x0445 */ u8 prevCsAction; + /* 0x0446 */ u8 cueId; + /* 0x0447 */ u8 unk_447; + /* 0x0448 */ Actor* csActor; // Actor involved in a `csAction`. Typically the actor that invoked the cutscene. + /* 0x044C */ char unk_44C[0x004]; + /* 0x0450 */ Vec3f unk_450; + /* 0x045C */ Vec3f unk_45C; + /* 0x0468 */ char unk_468[0x002]; + /* 0x046A */ s16 doorBgCamIndex; + /* 0x046C */ s16 subCamId; + /* 0x046E */ char unk_46E[0x02A]; /* 0x0498 */ ColliderCylinder cylinder; /* 0x04E4 */ ColliderQuad meleeWeaponQuads[2]; /* 0x05E4 */ ColliderQuad shieldQuad; - /* 0x0664 */ Actor* unk_664; - /* 0x0668 */ char unk_668[0x004]; - /* 0x066C */ s32 unk_66C; - /* 0x0670 */ s32 meleeWeaponEffectIndex; - /* 0x0674 */ PlayerFunc674 func_674; + /* 0x0664 */ Actor* unk_664; + /* 0x0668 */ char unk_668[0x004]; + /* 0x066C */ s32 unk_66C; + /* 0x0670 */ s32 meleeWeaponEffectIndex; + /* 0x0674 */ PlayerActionFunc actionFunc; /* 0x0678 */ PlayerAgeProperties* ageProperties; - /* 0x067C */ u32 stateFlags1; - /* 0x0680 */ u32 stateFlags2; - /* 0x0684 */ Actor* unk_684; - /* 0x0688 */ Actor* boomerangActor; - /* 0x068C */ Actor* naviActor; - /* 0x0690 */ s16 naviTextId; - /* 0x0692 */ u8 stateFlags3; - /* 0x0693 */ s8 exchangeItemId; - /* 0x0694 */ Actor* targetActor; - /* 0x0698 */ f32 targetActorDistance; - /* 0x069C */ char unk_69C[0x004]; - /* 0x06A0 */ f32 unk_6A0; - /* 0x06A4 */ f32 unk_6A4; - /* 0x06A8 */ Actor* unk_6A8; - /* 0x06AC */ s8 unk_6AC; - /* 0x06AD */ u8 unk_6AD; - /* 0x06AE */ u16 unk_6AE; - /* 0x06B0 */ s16 unk_6B0; - /* 0x06B2 */ char unk_6B4[0x004]; - /* 0x06B6 */ s16 unk_6B6; - /* 0x06B8 */ s16 unk_6B8; - /* 0x06BA */ s16 unk_6BA; - /* 0x06BC */ s16 unk_6BC; - /* 0x06BE */ s16 unk_6BE; - /* 0x06C0 */ s16 unk_6C0; - /* 0x06C2 */ s16 unk_6C2; - /* 0x06C4 */ f32 unk_6C4; - /* 0x06C8 */ SkelAnime skelAnime2; - /* 0x070C */ Vec3s jointTable2[PLAYER_LIMB_BUF_COUNT]; - /* 0x079C */ Vec3s morphTable2[PLAYER_LIMB_BUF_COUNT]; - /* 0x082C */ PlayerFunc82C func_82C; - /* 0x0830 */ f32 unk_830; - /* 0x0834 */ s16 unk_834; - /* 0x0836 */ s8 unk_836; - /* 0x0837 */ u8 unk_837; - /* 0x0838 */ f32 linearVelocity; - /* 0x083C */ s16 currentYaw; - /* 0x083E */ s16 targetYaw; - /* 0x0840 */ u16 unk_840; - /* 0x0842 */ s8 meleeWeaponAnimation; - /* 0x0843 */ s8 meleeWeaponState; - /* 0x0844 */ s8 unk_844; - /* 0x0845 */ u8 unk_845; - /* 0x0846 */ u8 unk_846; - /* 0x0847 */ s8 unk_847[4]; - /* 0x084B */ s8 unk_84B[4]; - /* 0x084F */ s8 unk_84F; - /* 0x0850 */ s16 unk_850; // multipurpose timer - /* 0x0854 */ f32 unk_854; - /* 0x0858 */ f32 unk_858; - /* 0x085C */ f32 unk_85C; // stick length among other things - /* 0x0860 */ s16 unk_860; // stick flame timer among other things - /* 0x0862 */ s16 unk_862; // get item draw ID + 1 - /* 0x0864 */ f32 unk_864; - /* 0x0868 */ f32 unk_868; - /* 0x086C */ f32 unk_86C; - /* 0x0870 */ f32 unk_870; - /* 0x0874 */ f32 unk_874; - /* 0x0878 */ f32 unk_878; - /* 0x087C */ s16 unk_87C; - /* 0x087E */ s16 unk_87E; - /* 0x0880 */ f32 unk_880; - /* 0x0884 */ f32 wallHeight; // height used to determine whether link can climb or grab a ledge at the top - /* 0x0888 */ f32 wallDistance; // distance to the colliding wall plane - /* 0x088C */ u8 unk_88C; - /* 0x088D */ u8 unk_88D; - /* 0x088E */ u8 unk_88E; - /* 0x088F */ u8 unk_88F; - /* 0x0890 */ u8 unk_890; - /* 0x0891 */ u8 shockTimer; - /* 0x0892 */ u8 unk_892; - /* 0x0893 */ u8 hoverBootsTimer; - /* 0x0894 */ s16 fallStartHeight; // last truncated Y position before falling - /* 0x0896 */ s16 fallDistance; // truncated Y distance the player has fallen so far (positive is down) - /* 0x0898 */ s16 unk_898; - /* 0x089A */ s16 unk_89A; - /* 0x089C */ s16 unk_89C; - /* 0x089E */ u16 unk_89E; - /* 0x08A0 */ u8 unk_8A0; - /* 0x08A1 */ u8 unk_8A1; - /* 0x08A2 */ s16 unk_8A2; - /* 0x08A4 */ f32 unk_8A4; - /* 0x08A8 */ f32 unk_8A8; - /* 0x08AC */ f32 windSpeed; // Pushing player, examples include water currents, floor conveyors, climbing sloped surfaces // Upstream TODO: pushedSpeed - /* 0x08B0 */ s16 windDirection; // Yaw direction of player being pushed // Upstream TODO: pushedYaw + /* 0x067C */ u32 stateFlags1; + /* 0x0680 */ u32 stateFlags2; + /* 0x0684 */ Actor* unk_684; + /* 0x0688 */ Actor* boomerangActor; + /* 0x068C */ Actor* naviActor; + /* 0x0690 */ s16 naviTextId; + /* 0x0692 */ u8 stateFlags3; + /* 0x0693 */ s8 exchangeItemId; + /* 0x0694 */ Actor* targetActor; + /* 0x0698 */ f32 targetActorDistance; + /* 0x069C */ char unk_69C[0x004]; + /* 0x06A0 */ f32 unk_6A0; + /* 0x06A4 */ f32 closestSecretDistSq; + /* 0x06A8 */ Actor* unk_6A8; + /* 0x06AC */ s8 unk_6AC; + /* 0x06AD */ u8 unk_6AD; + /* 0x06AE */ u16 unk_6AE; + /* 0x06B0 */ s16 unk_6B0; + /* 0x06B2 */ char unk_6B4[0x004]; + /* 0x06B6 */ s16 unk_6B6; + /* 0x06B8 */ s16 unk_6B8; + /* 0x06BA */ s16 unk_6BA; + /* 0x06BC */ s16 unk_6BC; + /* 0x06BE */ s16 unk_6BE; + /* 0x06C0 */ s16 unk_6C0; + /* 0x06C2 */ s16 unk_6C2; + /* 0x06C4 */ f32 unk_6C4; + /* 0x06C8 */ SkelAnime upperSkelAnime; + /* 0x070C */ Vec3s upperJointTable[PLAYER_LIMB_BUF_COUNT]; + /* 0x079C */ Vec3s upperMorphTable[PLAYER_LIMB_BUF_COUNT]; + /* 0x082C */ UpperActionFunc upperActionFunc; + /* 0x0830 */ f32 upperAnimBlendWeight; + /* 0x0834 */ s16 unk_834; + /* 0x0836 */ s8 unk_836; + /* 0x0837 */ u8 unk_837; + /* 0x0838 */ f32 linearVelocity; + /* 0x083C */ s16 yaw; // General yaw value, used both for world and shape rotation. Current or target value depending on context. + /* 0x083E */ s16 zTargetYaw; // yaw relating to Z targeting/"parallel" mode + /* 0x0840 */ u16 underwaterTimer; + /* 0x0842 */ s8 meleeWeaponAnimation; + /* 0x0843 */ s8 meleeWeaponState; + /* 0x0844 */ s8 unk_844; + /* 0x0845 */ u8 unk_845; + /* 0x0846 */ u8 unk_846; + /* 0x0847 */ s8 unk_847[4]; + /* 0x084B */ s8 unk_84B[4]; + + /* 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; + /* 0x0858 */ f32 unk_858; + /* 0x085C */ f32 unk_85C; // stick length among other things + /* 0x0860 */ s16 unk_860; // stick flame timer among other things + /* 0x0862 */ s16 unk_862; // get item draw ID + 1 + /* 0x0864 */ f32 unk_864; + /* 0x0868 */ f32 unk_868; + /* 0x086C */ f32 unk_86C; + /* 0x0870 */ f32 unk_870; + /* 0x0874 */ f32 unk_874; + /* 0x0878 */ f32 unk_878; + /* 0x087C */ s16 unk_87C; + /* 0x087E */ s16 unk_87E; + /* 0x0880 */ f32 unk_880; + /* 0x0884 */ f32 yDistToLedge; // y distance to ground above an interact wall. LEDGE_DIST_MAX if no ground is found + /* 0x0888 */ f32 distToInteractWall; // xyz distance to the interact wall + /* 0x088C */ u8 ledgeClimbType; + /* 0x088D */ u8 ledgeClimbDelayTimer; + /* 0x088E */ u8 unk_88E; + /* 0x088F */ u8 unk_88F; + /* 0x0890 */ u8 unk_890; + /* 0x0891 */ u8 bodyShockTimer; + /* 0x0892 */ u8 unk_892; + /* 0x0893 */ u8 hoverBootsTimer; + /* 0x0894 */ s16 fallStartHeight; // last truncated Y position before falling + /* 0x0896 */ s16 fallDistance; // truncated Y distance the player has fallen so far (positive is down) + /* 0x0898 */ s16 floorPitch; // angle of the floor slope in the direction of current world yaw (positive for ascending slope) + /* 0x089A */ s16 floorPitchAlt; // the calculation for this value is bugged and doesn't represent anything meaningful + /* 0x089C */ s16 unk_89C; + /* 0x089E */ u16 floorSfxOffset; + /* 0x08A0 */ u8 unk_8A0; + /* 0x08A1 */ u8 unk_8A1; + /* 0x08A2 */ s16 unk_8A2; + /* 0x08A4 */ f32 unk_8A4; + /* 0x08A8 */ f32 unk_8A8; + /* 0x08AC */ f32 pushedSpeed; // Pushing player, examples include water currents, floor conveyors, climbing sloped surfaces + /* 0x08B0 */ s16 pushedYaw; // Yaw direction of player being pushed /* 0x08B4 */ WeaponInfo meleeWeaponInfo[3]; - /* 0x0908 */ Vec3f bodyPartsPos[PLAYER_BODYPART_MAX]; - /* 0x09E0 */ MtxF mf_9E0; - /* 0x0A20 */ MtxF shieldMf; - /* 0x0A60 */ u8 isBurning; - /* 0x0A61 */ u8 flameTimers[PLAYER_BODYPART_MAX]; // one flame per body part - /* 0x0A73 */ u8 unk_A73; + /* 0x0908 */ Vec3f bodyPartsPos[PLAYER_BODYPART_MAX]; + /* 0x09E0 */ MtxF mf_9E0; + /* 0x0A20 */ MtxF shieldMf; + /* 0x0A60 */ u8 bodyIsBurning; + /* 0x0A61 */ u8 bodyFlameTimers[PLAYER_BODYPART_MAX]; // one flame per body part + /* 0x0A73 */ u8 unk_A73; /* 0x0A74 */ PlayerFuncA74 func_A74; - /* 0x0A78 */ s8 invincibilityTimer; // prevents damage when nonzero (positive = visible, counts towards zero each frame) - /* 0x0A79 */ u8 unk_A79; - /* 0x0A7A */ u8 unk_A7A; - /* 0x0A7B */ u8 unk_A7B; - /* 0x0A7C */ f32 unk_A7C; - /* 0x0A80 */ s16 unk_A80; - /* 0x0A82 */ u16 unk_A82; - /* 0x0A84 */ s16 unk_A84; - /* 0x0A86 */ s8 unk_A86; - /* 0x0A87 */ u8 unk_A87; - /* 0x0A88 */ Vec3f unk_A88; // previous body part 0 position + /* 0x0A78 */ s8 invincibilityTimer; // prevents damage when nonzero (positive = visible, counts towards zero each frame) + /* 0x0A79 */ u8 floorTypeTimer; // counts up every frame the current floor type is the same as the last frame + /* 0x0A7A */ u8 floorProperty; + /* 0x0A7B */ u8 prevFloorType; + /* 0x0A7C */ f32 prevControlStickMagnitude; + /* 0x0A80 */ s16 prevControlStickAngle; + /* 0x0A82 */ u16 prevFloorSfxOffset; + /* 0x0A84 */ s16 unk_A84; + /* 0x0A86 */ s8 unk_A86; + /* 0x0A87 */ u8 unk_A87; + /* 0x0A88 */ Vec3f unk_A88; // previous body part 0 position // #region SOH [General] // Upstream TODO: Rename these to be more obviously SoH specific /* */ PendingFlag pendingFlag; @@ -680,7 +677,7 @@ typedef struct Player { // #endregion // #region SOH [Enhancements] // Upstream TODO: Rename this to make it more obvious it is apart of an enhancement - /* */ u8 boomerangQuickRecall; // Has the player pressed the boomerang button while it's in the air still? + /* */ u8 boomerangQuickRecall; // Has the player pressed the boomerang button while it's in the air still? // #endregion u8 ivanFloating; u8 ivanDamageMultiplier; diff --git a/soh/include/z64scene.h b/soh/include/z64scene.h index 361e5f3c8..1c2267a05 100644 --- a/soh/include/z64scene.h +++ b/soh/include/z64scene.h @@ -314,8 +314,34 @@ enum SceneID { /* 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 +// 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 { /* 0 */ SDC_DEFAULT, /* 1 */ SDC_HYRULE_FIELD, diff --git a/soh/include/z64transition.h b/soh/include/z64transition.h index 30b1246f5..5a59e958b 100644 --- a/soh/include/z64transition.h +++ b/soh/include/z64transition.h @@ -50,11 +50,16 @@ typedef struct { /* 0x004 */ Color_RGBA8_u32 envColor; /* 0x008 */ s32 texX; /* 0x00C */ s32 texY; - /* 0x010 */ s32 step; - /* 0x014 */ u8 unk_14; - /* 0x015 */ u8 typeColor; - /* 0x016 */ u8 speed; - /* 0x017 */ u8 effect; + // /* 0x010 */ s32 step; + // /* 0x014 */ u8 unk_14; + // /* 0x015 */ u8 typeColor; + // /* 0x016 */ u8 speed; + // /* 0x017 */ u8 effect; + /* 0x010 */ s32 speed; + /* 0x014 */ u8 direction; + /* 0x015 */ u8 colorType; + /* 0x016 */ u8 speedType; + /* 0x017 */ u8 appearanceType; /* 0x018 */ u8 isDone; /* 0x019 */ u8 frame; /* 0x01A */ u16 normal; diff --git a/soh/macosx/Info.plist.in b/soh/macosx/Info.plist.in index dd0a49e8f..61316a18f 100644 --- a/soh/macosx/Info.plist.in +++ b/soh/macosx/Info.plist.in @@ -33,5 +33,10 @@ public.app-category.games LSMinimumSystemVersion 10.15 + LSArchitecturePriority + + arm64 + x86_64 + diff --git a/soh/macosx/soh-macos.sh.in b/soh/macosx/soh-macos.sh.in index 217496cf1..b90bd22e1 100755 --- a/soh/macosx/soh-macos.sh.in +++ b/soh/macosx/soh-macos.sh.in @@ -14,11 +14,6 @@ if [ ! -e "$SHIP_HOME"/mods ]; then touch "$SHIP_HOME"/mods/custom_otr_files_go_here.txt fi -arch_name="$(uname -m)" -launch_arch="arm64" -if [ "${arch_name}" = "x86_64" ] && [ "$(sysctl -in sysctl.proc_translated)" != "1" ]; then - launch_arch="x86_64" -fi +"$RESPATH"/soh-macos -arch -${launch_arch} "$RESPATH"/soh-macos exit diff --git a/soh/src/boot/properties.h.in b/soh/properties.h.in similarity index 100% rename from soh/src/boot/properties.h.in rename to soh/properties.h.in diff --git a/soh/soh/ActorDB.cpp b/soh/soh/ActorDB.cpp index a66048b32..ea8450ac4 100644 --- a/soh/soh/ActorDB.cpp +++ b/soh/soh/ActorDB.cpp @@ -74,7 +74,7 @@ static std::unordered_map actorDescriptions = { { ACTOR_EN_BUBBLE, "Shabom" }, { ACTOR_DOOR_SHUTTER, "Shutter Door" }, { ACTOR_EN_DODOJR, "Baby Dodongo" }, - { ACTOR_EN_BDFIRE, "Empty" }, + { ACTOR_EN_BDFIRE, "King Dodongo's Fire Breath" }, { ACTOR_EN_BOOM, "Boomerang" }, { ACTOR_EN_TORCH2, "Dark Link" }, { ACTOR_EN_BILI, "Biri" }, @@ -132,7 +132,7 @@ static std::unordered_map actorDescriptions = { { ACTOR_BG_TOKI_HIKARI, "Windows (Temple of Time)" }, { ACTOR_EN_YUKABYUN, "Flying Floor Tile" }, { 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_HIDAN_KOUSI, "Sliding Metal Gate" }, { ACTOR_DOOR_TOKI, "Door of Time Collision" }, @@ -548,6 +548,10 @@ int ActorDB::RetrieveId(const std::string& name) { return entry->second; } +int ActorDB::GetEntryCount() { + return db.size(); +} + ActorDB::Entry::Entry() { entry.name = nullptr; entry.desc = nullptr; diff --git a/soh/soh/ActorDB.h b/soh/soh/ActorDB.h index afb033a2f..8bcbb3f6a 100644 --- a/soh/soh/ActorDB.h +++ b/soh/soh/ActorDB.h @@ -64,6 +64,7 @@ public: static void AddBuiltInCustomActors(); + int GetEntryCount(); private: 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); diff --git a/soh/soh/Enhancements/audio/AudioCollection.cpp b/soh/soh/Enhancements/audio/AudioCollection.cpp index 9da742f91..dadcbf2ac 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.cpp +++ b/soh/soh/Enhancements/audio/AudioCollection.cpp @@ -2,9 +2,10 @@ #include "sequence.h" #include "sfx.h" #include -#include +#include #include #include +#include #include #include @@ -330,11 +331,13 @@ AudioCollection::AudioCollection() { } 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) { - return "gAudioEditor.ReplacedSequences." + sfxKey + ".locked"; + auto prefix = std::string(CVAR_AUDIO("ReplacedSequences.")); + return prefix + sfxKey + ".locked"; } 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 // play the normal track as usual. 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; } } @@ -381,19 +384,19 @@ uint16_t AudioCollection::GetReplacementSequence(uint16_t seqId) { } 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); includedSequences.erase(seqInfo); CVarSetInteger(cvarKey.c_str(), 1); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } 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); excludedSequences.erase(seqInfo); CVarClear(cvarKey.c_str()); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } void AudioCollection::InitializeShufflePool() { @@ -401,7 +404,7 @@ void AudioCollection::InitializeShufflePool() { for (auto& [seqId, seqInfo] : sequenceMap) { 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)) { excludedSequences.insert(&seqInfo); } else { diff --git a/soh/soh/Enhancements/audio/AudioCollection.h b/soh/soh/Enhancements/audio/AudioCollection.h index 1d53777e7..f3fd964bc 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.h +++ b/soh/soh/Enhancements/audio/AudioCollection.h @@ -1,3 +1,4 @@ +#pragma once #ifdef __cplusplus #include #include diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 8b0615a83..3b0c2bb12 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -9,9 +9,10 @@ #include #include "../randomizer/3drando/random.hpp" #include "../../OTRGlobals.h" -#include +#include #include "../../UIWidgets.hpp" #include "AudioCollection.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" Vec3f pos = { 0.0f, 0.0f, 0.0f }; f32 freqScale = 1.0f; @@ -78,7 +79,12 @@ void UpdateCurrentBGM(u16 seqKey, SeqType seqType) { void RandomizeGroup(SeqType type) { std::vector 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 while (values.size() < AuthenticCountBySequenceType(type)) { for (const auto& seqData : AudioCollection::Instance->GetIncludedSequences()) { @@ -123,23 +129,51 @@ void ResetGroup(const std::map& map, SeqType type) { } } +void LockGroup(const std::map& 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& 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) { const std::string cvarKey = AudioCollection::Instance->GetCvarKey(sfxKey); const std::string hiddenKey = "##" + cvarKey; const std::string stopButton = ICON_FA_STOP + 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())) { func_800F5C2C(); - CVarSetInteger("gAudioEditor.Playing", 0); + CVarSetInteger(CVAR_AUDIO("Playing"), 0); } UIWidgets::Tooltip("Stop Preview"); } else { if (ImGui::Button(previewButton.c_str())) { - if (CVarGetInteger("gAudioEditor.Playing", 0) != 0) { + if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) != 0) { func_800F5C2C(); - CVarSetInteger("gAudioEditor.Playing", 0); + CVarSetInteger(CVAR_AUDIO("Playing"), 0); } else { if (sequenceType == SEQ_SFX || sequenceType == SEQ_VOICE) { Audio_PlaySoundGeneral(sequenceId, &pos, 4, &freqScale, &freqScale, &reverbAdd); @@ -149,7 +183,7 @@ void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequence } else { // TODO: Cant do both here, so have to click preview button twice 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 resetAllButton = "Reset 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())) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); ResetGroup(map, 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(); @@ -178,7 +214,29 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); 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); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -223,7 +281,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { if (ImGui::Selectable(seqData.label.c_str())) { CVarSetInteger(cvarKey.c_str(), value); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); UpdateCurrentBGM(defaultValue, type); } @@ -243,7 +301,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { if (ImGui::Button(resetButton.c_str())) { CVarClear(cvarKey.c_str()); CVarClear(cvarLockKey.c_str()); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); UpdateCurrentBGM(defaultValue, seqData.category); } UIWidgets::Tooltip("Reset to default"); @@ -264,7 +322,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { if (locked) { CVarClear(cvarLockKey.c_str()); } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); UpdateCurrentBGM(defaultValue, type); } } @@ -277,7 +335,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { } else { CVarSetInteger(cvarLockKey.c_str(), 1); } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } UIWidgets::Tooltip(locked ? "Sound locked" : "Sound unlocked"); } @@ -350,6 +408,19 @@ void DrawTypeChip(SeqType type) { ImGui::EndDisabled(); } + +void AudioEditorRegisterOnSceneInitHook() { + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnNewScene"), 0)) { + AudioEditor_RandomizeAll(); + } + }); +} + +void AudioEditor::InitElement() { + AudioEditorRegisterOnSceneInitHook(); +} + void AudioEditor::DrawElement() { AudioCollection::Instance->InitializeShufflePool(); @@ -359,6 +430,28 @@ void AudioEditor::DrawElement() { 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::BeginTabItem("Background Music")) { Draw_SfxTab("backgroundMusic", SEQ_BGM_WORLD); @@ -399,18 +492,18 @@ void AudioEditor::DrawElement() { ImGui::TableNextColumn(); if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) { ImGui::PushItemWidth(-FLT_MIN); - UIWidgets::EnhancementCheckbox("Disable Enemy Proximity Music", "gEnemyBGMDisable"); + UIWidgets::EnhancementCheckbox("Disable Enemy Proximity Music", CVAR_AUDIO("EnemyBGMDisable")); UIWidgets::InsertHelpHoverText( "Disables the music change when getting close to enemies. Useful for hearing " "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( "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 " "the volume changing provides. If toggling this while in the Lost Woods, reload " "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( "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)." @@ -418,24 +511,28 @@ void AudioEditor::DrawElement() { ImGui::SameLine(); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); UIWidgets::EnhancementSliderInt("Overlay Duration: %d seconds", "##SeqNameOverlayDuration", - "gSeqNameOverlayDuration", 1, 10, "", 5); + CVAR_AUDIO("SeqNameOverlayDuration"), 1, 10, "", 5); ImGui::PopItemWidth(); ImGui::NewLine(); ImGui::PopItemWidth(); - UIWidgets::EnhancementSliderFloat("Link's voice pitch multiplier: %f", "##linkVoiceFreqMultiplier", - "gLinkVoiceFreqMultiplier", 0.4, 2.5, "", 1.0, false, false); + UIWidgets::EnhancementSliderFloat("Link's voice pitch multiplier: %.1f %%", "##linkVoiceFreqMultiplier", + CVAR_AUDIO("LinkVoiceFreqMultiplier"), 0.4, 2.5, "", 1.0, true, true); ImGui::SameLine(); const std::string resetButton = "Reset##linkVoiceFreqMultiplier"; if (ImGui::Button(resetButton.c_str())) { - CVarSetFloat("gLinkVoiceFreqMultiplier", 1.0f); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f); + 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::PushItemWidth(-FLT_MIN); UIWidgets::PaddedSeparator(); 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 " "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 " @@ -613,7 +710,14 @@ void AudioEditor_RandomizeAll() { 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(); } @@ -622,6 +726,29 @@ void AudioEditor_ResetAll() { ResetGroup(AudioCollection::Instance->GetAllSequences(), type); } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); 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(); +} diff --git a/soh/soh/Enhancements/audio/AudioEditor.h b/soh/soh/Enhancements/audio/AudioEditor.h index dc058371d..93ae3c440 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.h +++ b/soh/soh/Enhancements/audio/AudioEditor.h @@ -4,20 +4,28 @@ #ifdef __cplusplus #include -#include +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include +#include "AudioCollection.h" -class AudioEditor : public LUS::GuiWindow { +class AudioEditor : public Ship::GuiWindow { public: - using LUS::GuiWindow::GuiWindow; + using GuiWindow::GuiWindow; void DrawElement() override; - void InitElement() override {}; + void InitElement() override; void UpdateElement() override {}; ~AudioEditor() {}; }; void AudioEditor_RandomizeAll(); +void AudioEditor_RandomizeGroup(SeqType group); void AudioEditor_ResetAll(); +void AudioEditor_ResetGroup(SeqType group); +void AudioEditor_LockAll(); +void AudioEditor_UnlockAll(); extern "C" { #endif diff --git a/soh/soh/Enhancements/bootcommands.c b/soh/soh/Enhancements/bootcommands.c index 385a544a6..16ad651fc 100644 --- a/soh/soh/Enhancements/bootcommands.c +++ b/soh/soh/Enhancements/bootcommands.c @@ -9,6 +9,7 @@ #include #include #include +#include "soh/OTRGlobals.h" uint8_t gLoadFileSelect = 0, gSkipLogoTest = 0; @@ -21,15 +22,15 @@ static BootCommand sCommands[] = { { "--skiplogo", BootCommands_Command_SkipLogo void BootCommands_Init() { // Clears vars to prevent randomizer menu from being disabled - CVarClear("gRandoGenerating"); // Clear when a crash happened during rando seed generation - CVarClear("gNewSeedGenerated"); - CVarClear("gOnFileSelectNameEntry"); // Clear when soh is killed on the file name entry page - CVarClear("gBetterDebugWarpScreenMQMode"); - CVarClear("gBetterDebugWarpScreenMQModeScene"); - CVarClear("gCheatEasyPauseBufferLastInputs"); - CVarClear("gCheatEasyPauseBufferTimer"); + CVarClear(CVAR_GENERAL("RandoGenerating")); // Clear when a crash happened during rando seed generation + CVarClear(CVAR_GENERAL("NewSeedGenerated")); + CVarClear(CVAR_GENERAL("OnFileSelectNameEntry")); // Clear when soh is killed on the file name entry page + CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQMode")); + CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQModeScene")); + CVarClear(CVAR_GENERAL("CheatEasyPauseBufferLastInputs")); + CVarClear(CVAR_GENERAL("CheatEasyPauseBufferTimer")); #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 } diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index e9d94c503..63414f88c 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -175,33 +175,33 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { // Gohma & Phantom Ganon if (warpPosX == -100 && warpPosZ == -170) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { - play->nextEntranceIndex = 0x040F; + play->nextEntranceIndex = ENTR_DEKU_TREE_BOSS_0; } else { - play->nextEntranceIndex = 0x000C; + play->nextEntranceIndex = ENTR_FOREST_TEMPLE_BOSS_0; } // King Dodongo & Volvagia } else if (warpPosX == 100 && warpPosZ == -170) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { - play->nextEntranceIndex = 0x040B; + play->nextEntranceIndex = ENTR_DODONGOS_CAVERN_BOSS_0; } else { - play->nextEntranceIndex = 0x0305; + play->nextEntranceIndex = ENTR_FIRE_TEMPLE_BOSS_0; } // Barinade & Morb } else if (warpPosX == 199 && warpPosZ == 0) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { - play->nextEntranceIndex = 0x0301; + play->nextEntranceIndex = ENTR_JABU_JABU_BOSS_0; } else { - play->nextEntranceIndex = 0x0417; + play->nextEntranceIndex = ENTR_WATER_TEMPLE_BOSS_0; } // Twinrova } else if (warpPosX == 100 && warpPosZ == 170) { - play->nextEntranceIndex = 0x05EC; + play->nextEntranceIndex = ENTR_SPIRIT_TEMPLE_BOSS_2; // Bongo Bongo } else if (warpPosX == -100 && warpPosZ == 170) { - play->nextEntranceIndex = 0x0413; + play->nextEntranceIndex = ENTR_SHADOW_TEMPLE_BOSS_0; // Ganondork } 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. } else { @@ -216,10 +216,10 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { BossRush_SetEquipment(LINK_AGE_ADULT); // Warp to credits. } 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; - play->sceneLoadFlag = 0x14; - play->fadeTransition = 3; + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE; } } } @@ -293,7 +293,7 @@ void BossRush_InitSave() { gSaveContext.questId = QUEST_BOSSRUSH; gSaveContext.isBossRushPaused = 1; - gSaveContext.entranceIndex = 107; + gSaveContext.entranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; gSaveContext.cutsceneIndex = 0x8000; gSaveContext.isMagicAcquired = 1; diff --git a/soh/soh/Enhancements/controls/GameControlEditor.cpp b/soh/soh/Enhancements/controls/GameControlEditor.cpp deleted file mode 100644 index 976912b63..000000000 --- a/soh/soh/Enhancements/controls/GameControlEditor.cpp +++ /dev/null @@ -1,413 +0,0 @@ -#include "GameControlEditor.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#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> buttons; - static std::unordered_map 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::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); - } -} diff --git a/soh/soh/Enhancements/controls/GameControlEditor.h b/soh/soh/Enhancements/controls/GameControlEditor.h deleted file mode 100644 index 7cf306741..000000000 --- a/soh/soh/Enhancements/controls/GameControlEditor.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -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 diff --git a/soh/soh/Enhancements/controls/InputViewer.cpp b/soh/soh/Enhancements/controls/InputViewer.cpp new file mode 100644 index 000000000..93727b5fa --- /dev/null +++ b/soh/soh/Enhancements/controls/InputViewer.cpp @@ -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 +#include +#include + +#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(); + } +} \ No newline at end of file diff --git a/soh/soh/Enhancements/controls/InputViewer.h b/soh/soh/Enhancements/controls/InputViewer.h new file mode 100644 index 000000000..3e1e9c987 --- /dev/null +++ b/soh/soh/Enhancements/controls/InputViewer.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#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(); +}; diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp new file mode 100644 index 000000000..667d96c18 --- /dev/null +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -0,0 +1,2256 @@ +#include "SohInputEditorWindow.h" +#include +#include "soh/OTRGlobals.h" +#include "../../UIWidgets.hpp" +#include "z64.h" +#ifndef __WIIU__ +#include "controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h" +#endif + +#define SCALE_IMGUI_SIZE(value) ((value / 13.0f) * ImGui::GetFontSize()) + +SohInputEditorWindow::~SohInputEditorWindow() { +} + +void SohInputEditorWindow::InitElement() { + mGameInputBlockTimer = INT32_MAX; + mMappingInputBlockTimer = INT32_MAX; + mRumbleTimer = INT32_MAX; + mRumbleMappingToTest = nullptr; + mInputEditorPopupOpen = false; + + mButtonsBitmasks = { BTN_A, BTN_B, BTN_START, BTN_L, BTN_R, BTN_Z, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT }; + mDpadBitmasks = { BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; + mModifierButtonsBitmasks = { BTN_MODIFIER1, BTN_MODIFIER2 }; + + 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"); +} + +#define INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID 95237929 +void SohInputEditorWindow::UpdateElement() { + if (mRumbleTimer != INT32_MAX) { + mRumbleTimer--; + if (mRumbleMappingToTest != nullptr) { + mRumbleMappingToTest->StartRumble(); + } + if (mRumbleTimer <= 0) { + if (mRumbleMappingToTest != nullptr) { + mRumbleMappingToTest->StopRumble(); + } + mRumbleTimer = INT32_MAX; + mRumbleMappingToTest = nullptr; + } + } + + if (mInputEditorPopupOpen && ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopupId)) { + Ship::Context::GetInstance()->GetControlDeck()->BlockGameInput(INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID); + + // continue to block input for a third of a second after getting the mapping + mGameInputBlockTimer = ImGui::GetIO().Framerate / 3; + + if (mMappingInputBlockTimer != INT32_MAX) { + mMappingInputBlockTimer--; + if (mMappingInputBlockTimer <= 0) { + mMappingInputBlockTimer = INT32_MAX; + } + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->BlockImGuiGamepadNavigation(); + } else { + if (mGameInputBlockTimer != INT32_MAX) { + mGameInputBlockTimer--; + if (mGameInputBlockTimer <= 0) { + Ship::Context::GetInstance()->GetControlDeck()->UnblockGameInput( + INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID); + mGameInputBlockTimer = INT32_MAX; + } + } + + if (Ship::Context::GetInstance()->GetWindow()->GetGui()->ImGuiGamepadNavigationEnabled()) { + mMappingInputBlockTimer = ImGui::GetIO().Framerate / 3; + } else { + mMappingInputBlockTimer = INT32_MAX; + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->UnblockImGuiGamepadNavigation(); + } +} + +void SohInputEditorWindow::DrawAnalogPreview(const char* label, ImVec2 stick, float deadzone, bool gyro) { + ImGui::BeginChild(label, ImVec2(gyro ? SCALE_IMGUI_SIZE(78) : SCALE_IMGUI_SIZE(96), SCALE_IMGUI_SIZE(85)), false); + ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + gyro ? SCALE_IMGUI_SIZE(10) : SCALE_IMGUI_SIZE(18), + ImGui::GetCursorPos().y + gyro ? SCALE_IMGUI_SIZE(10) : 0)); + ImDrawList* drawList = ImGui::GetWindowDrawList(); + + const ImVec2 cursorScreenPosition = ImGui::GetCursorScreenPos(); + + // Draw the border box + float borderSquareLeft = cursorScreenPosition.x + SCALE_IMGUI_SIZE(2.0f); + float borderSquareTop = cursorScreenPosition.y + SCALE_IMGUI_SIZE(2.0f); + float borderSquareSize = SCALE_IMGUI_SIZE(65.0f); + drawList->AddRect(ImVec2(borderSquareLeft, borderSquareTop), + ImVec2(borderSquareLeft + borderSquareSize, borderSquareTop + borderSquareSize), + ImColor(100, 100, 100, 255), 0.0f, 0, 1.5f); + + // Draw the gate background + float cardinalRadius = SCALE_IMGUI_SIZE(22.5f); + float diagonalRadius = SCALE_IMGUI_SIZE(22.5f * (69.0f / 85.0f)); + + ImVec2 joystickCenterpoint = ImVec2(cursorScreenPosition.x + cardinalRadius + SCALE_IMGUI_SIZE(12), + cursorScreenPosition.y + cardinalRadius + SCALE_IMGUI_SIZE(11)); + drawList->AddQuadFilled(joystickCenterpoint, + ImVec2(joystickCenterpoint.x - diagonalRadius, joystickCenterpoint.y + diagonalRadius), + ImVec2(joystickCenterpoint.x, joystickCenterpoint.y + cardinalRadius), + ImVec2(joystickCenterpoint.x + diagonalRadius, joystickCenterpoint.y + diagonalRadius), + ImColor(130, 130, 130, 255)); + drawList->AddQuadFilled(joystickCenterpoint, + ImVec2(joystickCenterpoint.x + diagonalRadius, joystickCenterpoint.y + diagonalRadius), + ImVec2(joystickCenterpoint.x + cardinalRadius, joystickCenterpoint.y), + ImVec2(joystickCenterpoint.x + diagonalRadius, joystickCenterpoint.y - diagonalRadius), + ImColor(130, 130, 130, 255)); + drawList->AddQuadFilled(joystickCenterpoint, + ImVec2(joystickCenterpoint.x + diagonalRadius, joystickCenterpoint.y - diagonalRadius), + ImVec2(joystickCenterpoint.x, joystickCenterpoint.y - cardinalRadius), + ImVec2(joystickCenterpoint.x - diagonalRadius, joystickCenterpoint.y - diagonalRadius), + ImColor(130, 130, 130, 255)); + drawList->AddQuadFilled(joystickCenterpoint, + ImVec2(joystickCenterpoint.x - diagonalRadius, joystickCenterpoint.y - diagonalRadius), + ImVec2(joystickCenterpoint.x - cardinalRadius, joystickCenterpoint.y), + ImVec2(joystickCenterpoint.x - diagonalRadius, joystickCenterpoint.y + diagonalRadius), + ImColor(130, 130, 130, 255)); + + // Draw the joystick position indicator + ImVec2 joystickIndicatorDistanceFromCenter = ImVec2(0, 0); + if ((stick.x * stick.x + stick.y * stick.y) > (deadzone * deadzone)) { + joystickIndicatorDistanceFromCenter = + ImVec2((stick.x * (cardinalRadius / 85.0f)), -(stick.y * (cardinalRadius / 85.0f))); + } + float indicatorRadius = SCALE_IMGUI_SIZE(5.0f); + drawList->AddCircleFilled(ImVec2(joystickCenterpoint.x + joystickIndicatorDistanceFromCenter.x, + joystickCenterpoint.y + joystickIndicatorDistanceFromCenter.y), + indicatorRadius, ImColor(34, 51, 76, 255), 7); + + if (!gyro) { + ImGui::SetCursorPos( + ImVec2(ImGui::GetCursorPos().x - SCALE_IMGUI_SIZE(8), ImGui::GetCursorPos().y + SCALE_IMGUI_SIZE(72))); + ImGui::Text("X:%3d, Y:%3d", static_cast(stick.x), static_cast(stick.y)); + } + ImGui::EndChild(); +} + +#define CHIP_COLOR_N64_GREY ImVec4(0.4f, 0.4f, 0.4f, 1.0f) +#define CHIP_COLOR_N64_BLUE ImVec4(0.176f, 0.176f, 0.5f, 1.0f) +#define CHIP_COLOR_N64_GREEN ImVec4(0.0f, 0.294f, 0.0f, 1.0f) +#define CHIP_COLOR_N64_YELLOW ImVec4(0.5f, 0.314f, 0.0f, 1.0f) +#define CHIP_COLOR_N64_RED ImVec4(0.392f, 0.0f, 0.0f, 1.0f) + +#define BUTTON_COLOR_KEYBOARD_BEIGE ImVec4(0.651f, 0.482f, 0.357f, 0.5f) +#define BUTTON_COLOR_KEYBOARD_BEIGE_HOVERED ImVec4(0.651f, 0.482f, 0.357f, 1.0f) + +#define BUTTON_COLOR_GAMEPAD_BLUE ImVec4(0.0f, 0.255f, 0.976f, 0.5f) +#define BUTTON_COLOR_GAMEPAD_BLUE_HOVERED ImVec4(0.0f, 0.255f, 0.976f, 1.0f) + +#define BUTTON_COLOR_GAMEPAD_RED ImVec4(0.976f, 0.0f, 0.094f, 0.5f) +#define BUTTON_COLOR_GAMEPAD_RED_HOVERED ImVec4(0.976f, 0.0f, 0.094f, 1.0f) + +#define BUTTON_COLOR_GAMEPAD_ORANGE ImVec4(0.976f, 0.376f, 0.0f, 0.5f) +#define BUTTON_COLOR_GAMEPAD_ORANGE_HOVERED ImVec4(0.976f, 0.376f, 0.0f, 1.0f) + +#define BUTTON_COLOR_GAMEPAD_GREEN ImVec4(0.0f, 0.5f, 0.0f, 0.5f) +#define BUTTON_COLOR_GAMEPAD_GREEN_HOVERED ImVec4(0.0f, 0.5f, 0.0f, 1.0f) + +#define BUTTON_COLOR_GAMEPAD_PURPLE ImVec4(0.431f, 0.369f, 0.706f, 0.5f) +#define BUTTON_COLOR_GAMEPAD_PURPLE_HOVERED ImVec4(0.431f, 0.369f, 0.706f, 1.0f) + +void SohInputEditorWindow::GetButtonColorsForLUSDeviceIndex(Ship::ShipDeviceIndex lusIndex, ImVec4& buttonColor, + ImVec4& buttonHoveredColor) { + switch (lusIndex) { + case Ship::ShipDeviceIndex::Keyboard: + buttonColor = BUTTON_COLOR_KEYBOARD_BEIGE; + buttonHoveredColor = BUTTON_COLOR_KEYBOARD_BEIGE_HOVERED; + break; + case Ship::ShipDeviceIndex::Blue: + buttonColor = BUTTON_COLOR_GAMEPAD_BLUE; + buttonHoveredColor = BUTTON_COLOR_GAMEPAD_BLUE_HOVERED; + break; + case Ship::ShipDeviceIndex::Red: + buttonColor = BUTTON_COLOR_GAMEPAD_RED; + buttonHoveredColor = BUTTON_COLOR_GAMEPAD_RED_HOVERED; + break; + case Ship::ShipDeviceIndex::Orange: + buttonColor = BUTTON_COLOR_GAMEPAD_ORANGE; + buttonHoveredColor = BUTTON_COLOR_GAMEPAD_ORANGE_HOVERED; + break; + case Ship::ShipDeviceIndex::Green: + buttonColor = BUTTON_COLOR_GAMEPAD_GREEN; + buttonHoveredColor = BUTTON_COLOR_GAMEPAD_GREEN_HOVERED; + break; + default: + buttonColor = BUTTON_COLOR_GAMEPAD_PURPLE; + buttonHoveredColor = BUTTON_COLOR_GAMEPAD_PURPLE_HOVERED; + } +} + +void SohInputEditorWindow::DrawInputChip(const char* buttonName, ImVec4 color = CHIP_COLOR_N64_GREY) { + ImGui::BeginDisabled(); + ImGui::PushStyleColor(ImGuiCol_Button, color); + ImGui::Button(buttonName, ImVec2(SCALE_IMGUI_SIZE(50.0f), 0)); + ImGui::PopStyleColor(); + ImGui::EndDisabled(); +} + +void SohInputEditorWindow::DrawButtonLineAddMappingButton(uint8_t port, uint16_t bitmask) { + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + auto popupId = StringHelper::Sprintf("addButtonMappingPopup##%d-%d", port, bitmask); + if (ImGui::Button(StringHelper::Sprintf("%s###addButtonMappingButton%d-%d", ICON_FA_PLUS, port, bitmask).c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), 0.0f))) { + ImGui::OpenPopup(popupId.c_str()); + }; + ImGui::PopStyleVar(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Press any button,\nmove any axis,\nor press any key\nto add mapping"); + if (ImGui::Button("Cancel")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + // todo: figure out why optional params (using id = "" in the definition) wasn't working + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetButton(bitmask) + ->AddOrEditButtonMappingFromRawPress(bitmask, "")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} + +void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, uint16_t bitmask, std::string id) { + auto mapping = Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetButton(bitmask) + ->GetButtonMappingById(id); + if (mapping == nullptr) { + return; + } + + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f)); + std::string icon = ""; + switch (mapping->GetMappingType()) { + case MAPPING_TYPE_GAMEPAD: + icon = ICON_FA_GAMEPAD; + break; + case MAPPING_TYPE_KEYBOARD: + icon = ICON_FA_KEYBOARD_O; + break; + case MAPPING_TYPE_UNKNOWN: + icon = ICON_FA_BUG; + break; + } + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + auto physicalInputDisplayName = + StringHelper::Sprintf("%s %s", icon.c_str(), mapping->GetPhysicalInputName().c_str()); + GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + auto popupId = StringHelper::Sprintf("editButtonMappingPopup##%s", id.c_str()); + if (ImGui::Button( + StringHelper::Sprintf("%s###editButtonMappingButton%s", physicalInputDisplayName.c_str(), id.c_str()) + .c_str(), + ImVec2(ImGui::CalcTextSize(physicalInputDisplayName.c_str()).x + SCALE_IMGUI_SIZE(12.0f), 0.0f))) { + ImGui::OpenPopup(popupId.c_str()); + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) { + ImGui::SetTooltip(mapping->GetPhysicalDeviceName().c_str()); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Press any button,\nmove any axis,\nor press any key\nto edit mapping"); + if (ImGui::Button("Cancel")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetButton(bitmask) + ->AddOrEditButtonMappingFromRawPress(bitmask, id)) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + ImGui::PopStyleVar(); + ImGui::SameLine(0, 0); + +#ifndef __WIIU__ + auto sdlAxisDirectionToButtonMapping = std::dynamic_pointer_cast(mapping); + auto indexMapping = Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetDeviceIndexMappingFromShipDeviceIndex(mapping->GetShipDeviceIndex()); + auto sdlIndexMapping = std::dynamic_pointer_cast(indexMapping); + + if (sdlIndexMapping != nullptr && sdlAxisDirectionToButtonMapping != nullptr) { + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f)); + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + auto popupId = StringHelper::Sprintf("editAxisThresholdPopup##%s", id.c_str()); + if (ImGui::Button(StringHelper::Sprintf("%s###editAxisThresholdButton%s", ICON_FA_COG, id.c_str()).c_str(), + ImVec2(ImGui::CalcTextSize(ICON_FA_COG).x + SCALE_IMGUI_SIZE(10.0f), 0.0f))) { + ImGui::OpenPopup(popupId.c_str()); + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) { + ImGui::SetTooltip("Edit axis threshold"); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Axis Threshold\n\nThe extent to which the joystick\nmust be moved or the trigger\npressed to " + "initiate the assigned\nbutton action.\n\n"); + + if (sdlAxisDirectionToButtonMapping->AxisIsStick()) { + ImGui::Text("Stick axis threshold:"); + + int32_t stickAxisThreshold = sdlIndexMapping->GetStickAxisThresholdPercentage(); + if (stickAxisThreshold == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##Stick Axis Threshold%s", id.c_str()).c_str())) { + sdlIndexMapping->SetStickAxisThresholdPercentage(stickAxisThreshold - 1); + sdlIndexMapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (stickAxisThreshold == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##Stick Axis Threshold%s", id.c_str()).c_str(), + &stickAxisThreshold, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp)) { + sdlIndexMapping->SetStickAxisThresholdPercentage(stickAxisThreshold); + sdlIndexMapping->SaveToConfig(); + } + ImGui::SameLine(0.0f, 0.0f); + if (stickAxisThreshold == 100) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##Stick Axis Threshold%s", id.c_str()).c_str())) { + sdlIndexMapping->SetStickAxisThresholdPercentage(stickAxisThreshold + 1); + sdlIndexMapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (stickAxisThreshold == 100) { + ImGui::EndDisabled(); + } + } + + if (sdlAxisDirectionToButtonMapping->AxisIsTrigger()) { + ImGui::Text("Trigger axis threshold:"); + + int32_t triggerAxisThreshold = sdlIndexMapping->GetTriggerAxisThresholdPercentage(); + if (triggerAxisThreshold == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##Trigger Axis Threshold%s", id.c_str()).c_str())) { + sdlIndexMapping->SetTriggerAxisThresholdPercentage(triggerAxisThreshold - 1); + sdlIndexMapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (triggerAxisThreshold == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##Trigger Axis Threshold%s", id.c_str()).c_str(), + &triggerAxisThreshold, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp)) { + sdlIndexMapping->SetTriggerAxisThresholdPercentage(triggerAxisThreshold); + sdlIndexMapping->SaveToConfig(); + } + ImGui::SameLine(0.0f, 0.0f); + if (triggerAxisThreshold == 100) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##Trigger Axis Threshold%s", id.c_str()).c_str())) { + sdlIndexMapping->SetTriggerAxisThresholdPercentage(triggerAxisThreshold + 1); + sdlIndexMapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (triggerAxisThreshold == 100) { + ImGui::EndDisabled(); + } + } + + if (ImGui::Button("Close")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } + + ImGui::PopStyleVar(); + ImGui::SameLine(0, 0); + } +#endif + + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + if (ImGui::Button(StringHelper::Sprintf("%s###removeButtonMappingButton%s", ICON_FA_TIMES, id.c_str()).c_str(), + ImVec2(ImGui::CalcTextSize(ICON_FA_TIMES).x + SCALE_IMGUI_SIZE(10.0f), 0.0f))) { + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetButton(bitmask) + ->ClearButtonMapping(id); + }; + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); + + ImGui::SameLine(0, SCALE_IMGUI_SIZE(4.0f)); +} + +void SohInputEditorWindow::DrawButtonLine(const char* buttonName, uint8_t port, uint16_t bitmask, + ImVec4 color = CHIP_COLOR_N64_GREY) { + ImGui::NewLine(); + ImGui::SameLine(SCALE_IMGUI_SIZE(32.0f)); + DrawInputChip(buttonName, color); + ImGui::SameLine(SCALE_IMGUI_SIZE(86.0f)); + for (auto id : mBitmaskToMappingIds[port][bitmask]) { + DrawButtonLineEditMappingButton(port, bitmask, id); + } + DrawButtonLineAddMappingButton(port, bitmask); +} + +void SohInputEditorWindow::DrawStickDirectionLineAddMappingButton(uint8_t port, uint8_t stick, + Ship::Direction direction) { + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + auto popupId = StringHelper::Sprintf("addStickDirectionMappingPopup##%d-%d-%d", port, stick, direction); + if (ImGui::Button( + StringHelper::Sprintf("%s###addStickDirectionMappingButton%d-%d-%d", ICON_FA_PLUS, port, stick, direction) + .c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), 0.0f))) { + ImGui::OpenPopup(popupId.c_str()); + }; + ImGui::PopStyleVar(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Press any button,\nmove any axis,\nor press any key\nto add mapping"); + if (ImGui::Button("Cancel")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + if (stick == Ship::LEFT) { + if (mMappingInputBlockTimer == INT32_MAX && + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetLeftStick() + ->AddOrEditAxisDirectionMappingFromRawPress(direction, "")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + } else { + if (mMappingInputBlockTimer == INT32_MAX && + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetRightStick() + ->AddOrEditAxisDirectionMappingFromRawPress(direction, "")) { + ImGui::CloseCurrentPopup(); + } + } + ImGui::EndPopup(); + } +} + +void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port, uint8_t stick, + Ship::Direction direction, std::string id) { + std::shared_ptr mapping = nullptr; + if (stick == Ship::LEFT) { + mapping = Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetLeftStick() + ->GetAxisDirectionMappingById(direction, id); + } else { + mapping = Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetRightStick() + ->GetAxisDirectionMappingById(direction, id); + } + + if (mapping == nullptr) { + return; + } + + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f)); + std::string icon = ""; + switch (mapping->GetMappingType()) { + case MAPPING_TYPE_GAMEPAD: + icon = ICON_FA_GAMEPAD; + break; + case MAPPING_TYPE_KEYBOARD: + icon = ICON_FA_KEYBOARD_O; + break; + case MAPPING_TYPE_UNKNOWN: + icon = ICON_FA_BUG; + break; + } + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + auto physicalInputDisplayName = + StringHelper::Sprintf("%s %s", icon.c_str(), mapping->GetPhysicalInputName().c_str()); + GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + auto popupId = StringHelper::Sprintf("editStickDirectionMappingPopup##%s", id.c_str()); + if (ImGui::Button( + StringHelper::Sprintf("%s###editStickDirectionMappingButton%s", physicalInputDisplayName.c_str(), + id.c_str()) + .c_str(), + ImVec2(ImGui::CalcTextSize(physicalInputDisplayName.c_str()).x + SCALE_IMGUI_SIZE(12.0f), 0.0f))) { + ImGui::OpenPopup(popupId.c_str()); + } + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) { + ImGui::SetTooltip(mapping->GetPhysicalDeviceName().c_str()); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Press any button,\nmove any axis,\nor press any key\nto edit mapping"); + if (ImGui::Button("Cancel")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + + if (stick == Ship::LEFT) { + if (mMappingInputBlockTimer == INT32_MAX && + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetLeftStick() + ->AddOrEditAxisDirectionMappingFromRawPress(direction, id)) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + } else { + if (mMappingInputBlockTimer == INT32_MAX && + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetRightStick() + ->AddOrEditAxisDirectionMappingFromRawPress(direction, id)) { + ImGui::CloseCurrentPopup(); + } + } + ImGui::EndPopup(); + } + + ImGui::PopStyleVar(); + ImGui::SameLine(0, 0); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + if (ImGui::Button( + StringHelper::Sprintf("%s###removeStickDirectionMappingButton%s", ICON_FA_TIMES, id.c_str()).c_str(), + ImVec2(ImGui::CalcTextSize(ICON_FA_TIMES).x + SCALE_IMGUI_SIZE(10.0f), 0.0f))) { + if (stick == Ship::LEFT) { + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetLeftStick() + ->ClearAxisDirectionMapping(direction, id); + } else { + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetRightStick() + ->ClearAxisDirectionMapping(direction, id); + } + }; + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); + ImGui::SameLine(0, SCALE_IMGUI_SIZE(4.0f)); +} + +void SohInputEditorWindow::DrawStickDirectionLine(const char* axisDirectionName, uint8_t port, uint8_t stick, + Ship::Direction direction, ImVec4 color = CHIP_COLOR_N64_GREY) { + ImGui::NewLine(); + ImGui::SameLine(); + ImGui::BeginDisabled(); + ImGui::PushStyleColor(ImGuiCol_Button, color); + ImGui::Button(axisDirectionName, ImVec2(SCALE_IMGUI_SIZE(26.0f), 0)); + ImGui::PopStyleColor(); + ImGui::EndDisabled(); + ImGui::SameLine(0.0f, SCALE_IMGUI_SIZE(4.0f)); + for (auto id : mStickDirectionToMappingIds[port][stick][direction]) { + DrawStickDirectionLineEditMappingButton(port, stick, direction, id); + } + DrawStickDirectionLineAddMappingButton(port, stick, direction); +} + +void SohInputEditorWindow::DrawStickSection(uint8_t port, uint8_t stick, int32_t id, + ImVec4 color = CHIP_COLOR_N64_GREY) { + static int8_t sX, sY; + std::shared_ptr controllerStick = nullptr; + if (stick == Ship::LEFT) { + controllerStick = Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLeftStick(); + } else { + controllerStick = Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetRightStick(); + } + controllerStick->Process(sX, sY); + DrawAnalogPreview(StringHelper::Sprintf("##AnalogPreview%d", id).c_str(), ImVec2(sX, sY)); + + ImGui::SameLine(); + ImGui::BeginGroup(); + DrawStickDirectionLine(ICON_FA_ARROW_UP, port, stick, Ship::UP, color); + DrawStickDirectionLine(ICON_FA_ARROW_DOWN, port, stick, Ship::DOWN, color); + DrawStickDirectionLine(ICON_FA_ARROW_LEFT, port, stick, Ship::LEFT, color); + DrawStickDirectionLine(ICON_FA_ARROW_RIGHT, port, stick, Ship::RIGHT, color); + ImGui::EndGroup(); + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (ImGui::TreeNode(StringHelper::Sprintf("Analog Stick Options##%d", id).c_str())) { + ImGui::Text("Sensitivity:"); + + int32_t sensitivityPercentage = controllerStick->GetSensitivityPercentage(); + if (sensitivityPercentage == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##Sensitivity%d", id).c_str())) { + controllerStick->SetSensitivity(sensitivityPercentage - 1); + } + ImGui::PopButtonRepeat(); + if (sensitivityPercentage == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##Sensitivity%d", id).c_str(), &sensitivityPercentage, 0, 200, "%d%%", + ImGuiSliderFlags_AlwaysClamp)) { + controllerStick->SetSensitivity(sensitivityPercentage); + } + ImGui::SameLine(0.0f, 0.0f); + if (sensitivityPercentage == 200) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##Sensitivity%d", id).c_str())) { + controllerStick->SetSensitivity(sensitivityPercentage + 1); + } + ImGui::PopButtonRepeat(); + if (sensitivityPercentage == 200) { + ImGui::EndDisabled(); + } + if (!controllerStick->SensitivityIsDefault()) { + ImGui::SameLine(); + if (ImGui::Button(StringHelper::Sprintf("Reset to Default###resetStickSensitivity%d", id).c_str())) { + controllerStick->ResetSensitivityToDefault(); + } + } + + ImGui::Text("Deadzone:"); + + int32_t deadzonePercentage = controllerStick->GetDeadzonePercentage(); + if (deadzonePercentage == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##Deadzone%d", id).c_str())) { + controllerStick->SetDeadzone(deadzonePercentage - 1); + } + ImGui::PopButtonRepeat(); + if (deadzonePercentage == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##Deadzone%d", id).c_str(), &deadzonePercentage, 0, 100, "%d%%", + ImGuiSliderFlags_AlwaysClamp)) { + controllerStick->SetDeadzone(deadzonePercentage); + } + ImGui::SameLine(0.0f, 0.0f); + if (deadzonePercentage == 100) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##Deadzone%d", id).c_str())) { + controllerStick->SetDeadzone(deadzonePercentage + 1); + } + ImGui::PopButtonRepeat(); + if (deadzonePercentage == 100) { + ImGui::EndDisabled(); + } + if (!controllerStick->DeadzoneIsDefault()) { + ImGui::SameLine(); + if (ImGui::Button(StringHelper::Sprintf("Reset to Default###resetStickDeadzone%d", id).c_str())) { + controllerStick->ResetDeadzoneToDefault(); + } + } + + ImGui::Text("Notch Snap Angle:"); + int32_t notchSnapAngle = controllerStick->GetNotchSnapAngle(); + if (notchSnapAngle == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##NotchProximityThreshold%d", id).c_str())) { + controllerStick->SetNotchSnapAngle(notchSnapAngle - 1); + } + ImGui::PopButtonRepeat(); + if (notchSnapAngle == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##NotchProximityThreshold%d", id).c_str(), ¬chSnapAngle, 0, 45, + "%d°", ImGuiSliderFlags_AlwaysClamp)) { + controllerStick->SetNotchSnapAngle(notchSnapAngle); + } + ImGui::SameLine(0.0f, 0.0f); + if (notchSnapAngle == 45) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##NotchProximityThreshold%d", id).c_str())) { + controllerStick->SetNotchSnapAngle(notchSnapAngle + 1); + } + ImGui::PopButtonRepeat(); + if (notchSnapAngle == 45) { + ImGui::EndDisabled(); + } + if (!controllerStick->NotchSnapAngleIsDefault()) { + ImGui::SameLine(); + if (ImGui::Button(StringHelper::Sprintf("Reset to Default###resetStickSnap%d", id).c_str())) { + controllerStick->ResetNotchSnapAngleToDefault(); + } + } + + ImGui::TreePop(); + } +} + +void SohInputEditorWindow::UpdateBitmaskToMappingIds(uint8_t port) { + // todo: do we need this now that ControllerButton exists? + + for (auto [bitmask, button] : + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetAllButtons()) { + for (auto [id, mapping] : button->GetAllButtonMappings()) { + // using a vector here instead of a set because i want newly added mappings + // to go to the end of the list instead of autosorting + if (std::find(mBitmaskToMappingIds[port][bitmask].begin(), mBitmaskToMappingIds[port][bitmask].end(), id) == + mBitmaskToMappingIds[port][bitmask].end()) { + mBitmaskToMappingIds[port][bitmask].push_back(id); + } + } + } +} + +void SohInputEditorWindow::UpdateStickDirectionToMappingIds(uint8_t port) { + // todo: do we need this? + for (auto stick : + { std::make_pair>( + Ship::LEFT, Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLeftStick()), + std::make_pair>( + Ship::RIGHT, + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetRightStick()) }) { + for (auto direction : { Ship::LEFT, Ship::RIGHT, Ship::UP, Ship::DOWN }) { + for (auto [id, mapping] : stick.second->GetAllAxisDirectionMappingByDirection(direction)) { + // using a vector here instead of a set because i want newly added mappings + // to go to the end of the list instead of autosorting + if (std::find(mStickDirectionToMappingIds[port][stick.first][direction].begin(), + mStickDirectionToMappingIds[port][stick.first][direction].end(), + id) == mStickDirectionToMappingIds[port][stick.first][direction].end()) { + mStickDirectionToMappingIds[port][stick.first][direction].push_back(id); + } + } + } + } +} + +void SohInputEditorWindow::DrawRemoveRumbleMappingButton(uint8_t port, std::string id) { + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + if (ImGui::Button(StringHelper::Sprintf("%s###removeRumbleMapping%s", ICON_FA_TIMES, id.c_str()).c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetRumble()->ClearRumbleMapping(id); + } + ImGui::PopStyleVar(); +} + +void SohInputEditorWindow::DrawAddRumbleMappingButton(uint8_t port) { + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + auto popupId = StringHelper::Sprintf("addRumbleMappingPopup##%d", port); + if (ImGui::Button(StringHelper::Sprintf("%s###addRumbleMapping%d", ICON_FA_PLUS, port).c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { + ImGui::OpenPopup(popupId.c_str()); + } + ImGui::PopStyleVar(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Press any button\nor move any axis\nto add rumble device"); + if (ImGui::Button("Cancel")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetRumble() + ->AddRumbleMappingFromRawPress()) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} + +bool SohInputEditorWindow::TestingRumble() { + return mRumbleTimer != INT32_MAX; +} + +void SohInputEditorWindow::DrawRumbleSection(uint8_t port) { + for (auto [id, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetRumble() + ->GetAllRumbleMappings()) { + ImGui::AlignTextToFramePadding(); + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor); + // begin hackaround https://github.com/ocornut/imgui/issues/282#issuecomment-123763192 + // spaces to have background color for text in a tree node + std::string spaces = ""; + for (size_t i = 0; i < mapping->GetPhysicalDeviceName().length(); i++) { + spaces += " "; + } + auto open = ImGui::TreeNode(StringHelper::Sprintf("%s###Rumble%s", spaces.c_str(), id.c_str()).c_str()); + ImGui::SameLine(); + ImGui::SetCursorPosX(SCALE_IMGUI_SIZE(30.0f)); + // end hackaround + + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::Button(mapping->GetPhysicalDeviceName().c_str()); + ImGui::PopStyleColor(); + ImGui::PopItemFlag(); + + DrawRemoveRumbleMappingButton(port, id); + ImGui::SameLine(); + if (ImGui::Button( + StringHelper::Sprintf("%s###rumbleTestButton%s", TestingRumble() ? "Stop" : "Test", id.c_str()) + .c_str())) { + if (mRumbleTimer != INT32_MAX) { + mRumbleTimer = INT32_MAX; + mRumbleMappingToTest->StopRumble(); + mRumbleMappingToTest = nullptr; + } else { + mRumbleTimer = ImGui::GetIO().Framerate; + mRumbleMappingToTest = mapping; + } + } + if (open) { + ImGui::Text("Small Motor Intensity:"); + + int32_t smallMotorIntensity = mapping->GetHighFrequencyIntensityPercentage(); + if (smallMotorIntensity == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##Small Motor Intensity%s", id.c_str()).c_str())) { + mapping->SetHighFrequencyIntensity(smallMotorIntensity - 1); + mapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (smallMotorIntensity == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##Small Motor Intensity%s", id.c_str()).c_str(), + &smallMotorIntensity, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp)) { + mapping->SetHighFrequencyIntensity(smallMotorIntensity); + mapping->SaveToConfig(); + } + ImGui::SameLine(0.0f, 0.0f); + if (smallMotorIntensity == 100) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##Small Motor Intensity%s", id.c_str()).c_str())) { + mapping->SetHighFrequencyIntensity(smallMotorIntensity + 1); + mapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (smallMotorIntensity == 100) { + ImGui::EndDisabled(); + } + if (!mapping->HighFrequencyIntensityIsDefault()) { + ImGui::SameLine(); + if (ImGui::Button(StringHelper::Sprintf("Reset to Default###resetHighFrequencyIntensity%s", id.c_str()) + .c_str())) { + mapping->ResetHighFrequencyIntensityToDefault(); + } + } + + ImGui::Text("Large Motor Intensity:"); + + int32_t largeMotorIntensity = mapping->GetLowFrequencyIntensityPercentage(); + if (largeMotorIntensity == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##Large Motor Intensity%s", id.c_str()).c_str())) { + mapping->SetLowFrequencyIntensity(largeMotorIntensity - 1); + mapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (largeMotorIntensity == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##Large Motor Intensity%s", id.c_str()).c_str(), + &largeMotorIntensity, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp)) { + mapping->SetLowFrequencyIntensity(largeMotorIntensity); + mapping->SaveToConfig(); + } + ImGui::SameLine(0.0f, 0.0f); + if (largeMotorIntensity == 100) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##Large Motor Intensity%s", id.c_str()).c_str())) { + mapping->SetLowFrequencyIntensity(largeMotorIntensity + 1); + mapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (largeMotorIntensity == 100) { + ImGui::EndDisabled(); + } + if (!mapping->LowFrequencyIntensityIsDefault()) { + ImGui::SameLine(); + if (ImGui::Button( + StringHelper::Sprintf("Reset to Default###resetLowFrequencyIntensity%s", id.c_str()).c_str())) { + mapping->ResetLowFrequencyIntensityToDefault(); + } + } + ImGui::Dummy(ImVec2(0, SCALE_IMGUI_SIZE(20))); + + ImGui::TreePop(); + } + } + + ImGui::AlignTextToFramePadding(); + ImGui::BulletText("Add rumble device"); + DrawAddRumbleMappingButton(port); +} + +void SohInputEditorWindow::DrawRemoveLEDMappingButton(uint8_t port, std::string id) { + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + if (ImGui::Button(StringHelper::Sprintf("%s###removeLEDMapping%s", ICON_FA_TIMES, id.c_str()).c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLED()->ClearLEDMapping(id); + } + ImGui::PopStyleVar(); +} + +void SohInputEditorWindow::DrawAddLEDMappingButton(uint8_t port) { + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + auto popupId = StringHelper::Sprintf("addLEDMappingPopup##%d", port); + if (ImGui::Button(StringHelper::Sprintf("%s###addLEDMapping%d", ICON_FA_PLUS, port).c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { + ImGui::OpenPopup(popupId.c_str()); + } + ImGui::PopStyleVar(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Press any button\nor move any axis\nto add LED device"); + if (ImGui::Button("Cancel")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetLED() + ->AddLEDMappingFromRawPress()) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} + +void SohInputEditorWindow::DrawLEDSection(uint8_t port) { + for (auto [id, mapping] : + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLED()->GetAllLEDMappings()) { + ImGui::AlignTextToFramePadding(); + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + auto open = ImGui::TreeNode( + StringHelper::Sprintf("%s##LED%s", mapping->GetPhysicalDeviceName().c_str(), id.c_str()).c_str()); + DrawRemoveLEDMappingButton(port, id); + if (open) { + ImGui::AlignTextToFramePadding(); + ImGui::Text("LED Color:"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(80.0f)); + int32_t colorSource = mapping->GetColorSource(); + if (ImGui::Combo(StringHelper::Sprintf("###ledColorSource%s", mapping->GetLEDMappingId().c_str()).c_str(), + &colorSource, "Off\0Set\0Game\0\0")) { + mapping->SetColorSource(colorSource); + }; + if (mapping->GetColorSource() == LED_COLOR_SOURCE_SET) { + ImGui::SameLine(); + ImVec4 color = { mapping->GetSavedColor().r / 255.0f, mapping->GetSavedColor().g / 255.0f, + mapping->GetSavedColor().b / 255.0f, 1.0f }; + if (ImGui::ColorEdit3( + StringHelper::Sprintf("###ledSavedColor%s", mapping->GetLEDMappingId().c_str()).c_str(), + (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + mapping->SetSavedColor( + Color_RGB8({ static_cast(color.x * 255.0), static_cast(color.y * 255.0), + static_cast(color.z * 255.0) })); + } + } + // todo: clean this up, probably just hardcode to LED_COLOR_SOURCE_GAME and use SoH options only here + if (mapping->GetColorSource() == LED_COLOR_SOURCE_GAME) { + 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(CVAR_SETTING("LEDColorSource"), ledSources, LED_SOURCE_TUNIC_ORIGINAL); + UIWidgets::Tooltip("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(CVAR_SETTING("LEDColorSource"), 1) == LED_SOURCE_CUSTOM) { + UIWidgets::Spacer(3); + auto port1Color = CVarGetColor24(CVAR_SETTING("LEDPort1Color"), { 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(CVAR_SETTING("LEDPort1Color"), color); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } + ImGui::SameLine(); + ImGui::Text("Custom Color"); + } + UIWidgets::PaddedEnhancementSliderFloat("Brightness: %.1f %%", "##LED_Brightness", CVAR_SETTING("LEDBrightness"), 0.0f, + 1.0f, "", 1.0f, true, true); + UIWidgets::Tooltip("Sets the brightness of controller LEDs. 0% brightness = LEDs off."); + UIWidgets::PaddedEnhancementCheckbox( + "Critical Health Override", CVAR_SETTING("LEDCriticalOverride"), true, true, + CVarGetInteger(CVAR_SETTING("LEDColorSource"), LED_SOURCE_TUNIC_ORIGINAL) == LED_SOURCE_HEALTH, + "Override redundant for health source.", UIWidgets::CheckboxGraphics::Cross, true); + UIWidgets::Tooltip("Shows red color when health is critical, otherwise displays according to color source."); + } + ImGui::TreePop(); + } + } + + ImGui::AlignTextToFramePadding(); + ImGui::BulletText("Add LED device"); + DrawAddLEDMappingButton(port); +} + +void SohInputEditorWindow::DrawRemoveGyroMappingButton(uint8_t port, std::string id) { + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + if (ImGui::Button(StringHelper::Sprintf("%s###removeGyroMapping%s", ICON_FA_TIMES, id.c_str()).c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetGyro()->ClearGyroMapping(); + } + ImGui::PopStyleVar(); +} + +void SohInputEditorWindow::DrawAddGyroMappingButton(uint8_t port) { + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + auto popupId = StringHelper::Sprintf("addGyroMappingPopup##%d", port); + if (ImGui::Button(StringHelper::Sprintf("%s###addGyroMapping%d", ICON_FA_PLUS, port).c_str(), + ImVec2(SCALE_IMGUI_SIZE(20.0f), SCALE_IMGUI_SIZE(20.0f)))) { + ImGui::OpenPopup(popupId.c_str()); + } + ImGui::PopStyleVar(); + + if (ImGui::BeginPopup(popupId.c_str())) { + mInputEditorPopupOpen = true; + ImGui::Text("Press any button\nor move any axis\nto add gyro device"); + if (ImGui::Button("Cancel")) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + + if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(port) + ->GetGyro() + ->SetGyroMappingFromRawPress()) { + mInputEditorPopupOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} + +void SohInputEditorWindow::DrawGyroSection(uint8_t port) { + auto mapping = + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetGyro()->GetGyroMapping(); + if (mapping != nullptr) { + auto id = mapping->GetGyroMappingId(); + ImGui::AlignTextToFramePadding(); + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + ImGui::BulletText(mapping->GetPhysicalDeviceName().c_str()); + DrawRemoveGyroMappingButton(port, id); + + static float sPitch, sYaw = 0.0f; + mapping->UpdatePad(sPitch, sYaw); + + ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x, ImGui::GetCursorPos().y - SCALE_IMGUI_SIZE(8))); + // to find a reasonable scaling factor gyro values + // I tried to find the maximum value reported by shaking + // a PS5 controller as hard as I could without worrying about breaking it + // the max I found for both pitch and yaw was ~21 + // the preview window expects values in an n64 analog stick range (-85 to 85) + // so I decided to multiply these by 85/21 + DrawAnalogPreview(StringHelper::Sprintf("###GyroPreview%s", id.c_str()).c_str(), + ImVec2(sYaw * (85.0f / 21.0f), sPitch * (85.0f / 21.0f)), 0.0f, true); + ImGui::SameLine(); + ImGui::SetCursorPos( + ImVec2(ImGui::GetCursorPos().x + SCALE_IMGUI_SIZE(8), ImGui::GetCursorPos().y + SCALE_IMGUI_SIZE(8))); + + ImGui::BeginGroup(); + ImGui::Text("Sensitivity:"); + + int32_t sensitivity = mapping->GetSensitivityPercent(); + if (sensitivity == 0) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("-##GyroSensitivity%s", id.c_str()).c_str())) { + mapping->SetSensitivity(sensitivity - 1); + mapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (sensitivity == 0) { + ImGui::EndDisabled(); + } + ImGui::SameLine(0.0f, 0.0f); + ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); + if (ImGui::SliderInt(StringHelper::Sprintf("##GyroSensitivity%s", id.c_str()).c_str(), &sensitivity, 0, 100, + "%d%%", ImGuiSliderFlags_AlwaysClamp)) { + mapping->SetSensitivity(sensitivity); + mapping->SaveToConfig(); + } + ImGui::SameLine(0.0f, 0.0f); + if (sensitivity == 100) { + ImGui::BeginDisabled(); + } + ImGui::PushButtonRepeat(true); + if (ImGui::Button(StringHelper::Sprintf("+##GyroSensitivity%s", id.c_str()).c_str())) { + mapping->SetSensitivity(sensitivity + 1); + mapping->SaveToConfig(); + } + ImGui::PopButtonRepeat(); + if (sensitivity == 100) { + ImGui::EndDisabled(); + } + + if (!mapping->SensitivityIsDefault()) { + ImGui::SameLine(); + if (ImGui::Button(StringHelper::Sprintf("Reset to Default###resetGyroSensitivity%s", id.c_str()).c_str())) { + mapping->ResetSensitivityToDefault(); + } + } + + ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x, ImGui::GetCursorPos().y + SCALE_IMGUI_SIZE(8))); + if (ImGui::Button("Recalibrate")) { + mapping->Recalibrate(); + mapping->SaveToConfig(); + } + ImGui::EndGroup(); + ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x, ImGui::GetCursorPos().y - SCALE_IMGUI_SIZE(8))); + } else { + ImGui::AlignTextToFramePadding(); + ImGui::BulletText("Add gyro device"); + DrawAddGyroMappingButton(port); + } +} + +void SohInputEditorWindow::DrawButtonDeviceIcons(uint8_t portIndex, std::set bitmasks) { + std::set allLusDeviceIndices; + allLusDeviceIndices.insert(Ship::ShipDeviceIndex::Keyboard); + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappingsFromConfig()) { + allLusDeviceIndices.insert(lusIndex); + } + + std::vector> lusDeviceIndiciesWithMappings; + for (auto lusIndex : allLusDeviceIndices) { + for (auto [bitmask, button] : + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetAllButtons()) { + if (!bitmasks.contains(bitmask)) { + continue; + } + + if (button->HasMappingsForShipDeviceIndex(lusIndex)) { + for (auto [id, mapping] : button->GetAllButtonMappings()) { + if (mapping->GetShipDeviceIndex() == lusIndex) { + lusDeviceIndiciesWithMappings.push_back( + std::pair(lusIndex, mapping->PhysicalDeviceIsConnected())); + break; + } + } + break; + } + } + } + + for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) { + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::SameLine(); + if (lusIndex == Ship::ShipDeviceIndex::Keyboard) { + ImGui::SmallButton(ICON_FA_KEYBOARD_O); + } else { + ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + } +} + +void SohInputEditorWindow::DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::Stick stick) { + std::set allLusDeviceIndices; + allLusDeviceIndices.insert(Ship::ShipDeviceIndex::Keyboard); + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappingsFromConfig()) { + allLusDeviceIndices.insert(lusIndex); + } + + std::vector> lusDeviceIndiciesWithMappings; + for (auto lusIndex : allLusDeviceIndices) { + auto controllerStick = + stick == Ship::Stick::LEFT_STICK + ? Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetLeftStick() + : Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetRightStick(); + if (controllerStick->HasMappingsForShipDeviceIndex(lusIndex)) { + for (auto [direction, mappings] : controllerStick->GetAllAxisDirectionMappings()) { + bool foundMapping = false; + for (auto [id, mapping] : mappings) { + if (mapping->GetShipDeviceIndex() == lusIndex) { + foundMapping = true; + lusDeviceIndiciesWithMappings.push_back( + std::pair(lusIndex, mapping->PhysicalDeviceIsConnected())); + break; + } + } + if (foundMapping) { + break; + } + } + } + } + + for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) { + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::SameLine(); + if (lusIndex == Ship::ShipDeviceIndex::Keyboard) { + ImGui::SmallButton(ICON_FA_KEYBOARD_O); + } else { + ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + } +} + +void SohInputEditorWindow::DrawRumbleDeviceIcons(uint8_t portIndex) { + std::set allLusDeviceIndices; + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappingsFromConfig()) { + allLusDeviceIndices.insert(lusIndex); + } + + std::vector> lusDeviceIndiciesWithMappings; + for (auto lusIndex : allLusDeviceIndices) { + if (Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(portIndex) + ->GetRumble() + ->HasMappingsForShipDeviceIndex(lusIndex)) { + for (auto [id, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(portIndex) + ->GetRumble() + ->GetAllRumbleMappings()) { + if (mapping->GetShipDeviceIndex() == lusIndex) { + lusDeviceIndiciesWithMappings.push_back( + std::pair(lusIndex, mapping->PhysicalDeviceIsConnected())); + break; + } + } + } + } + + for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) { + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::SameLine(); + ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + } +} + +void SohInputEditorWindow::DrawGyroDeviceIcons(uint8_t portIndex) { + auto mapping = + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetGyro()->GetGyroMapping(); + if (mapping == nullptr) { + return; + } + + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::SameLine(); + ImGui::SmallButton(mapping->PhysicalDeviceIsConnected() ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); +} + +void SohInputEditorWindow::DrawLEDDeviceIcons(uint8_t portIndex) { + std::set allLusDeviceIndices; + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappingsFromConfig()) { + allLusDeviceIndices.insert(lusIndex); + } + + std::vector> lusDeviceIndiciesWithMappings; + for (auto lusIndex : allLusDeviceIndices) { + if (Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(portIndex) + ->GetRumble() + ->HasMappingsForShipDeviceIndex(lusIndex)) { + for (auto [id, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(portIndex) + ->GetLED() + ->GetAllLEDMappings()) { + if (mapping->GetShipDeviceIndex() == lusIndex) { + lusDeviceIndiciesWithMappings.push_back( + std::pair(lusIndex, mapping->PhysicalDeviceIsConnected())); + break; + } + } + } + } + + for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) { + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + ImGui::SameLine(); + ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + } +} + +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); + } +} + +typedef uint32_t N64ButtonMask; + +void SohInputEditorWindow::addButtonName(N64ButtonMask mask, const char* name) { + buttons.push_back(std::make_pair(mask, name)); + buttonNames[mask] = std::prev(buttons.end()); +} + +// Ocarina button maps +static CustomButtonMap ocarinaD5 = {"D5", CVAR_SETTING("CustomOcarina.D5Button"), BTN_CUP}; +static CustomButtonMap ocarinaB4 = {"B4", CVAR_SETTING("CustomOcarina.B4Button"), BTN_CLEFT}; +static CustomButtonMap ocarinaA4 = {"A4", CVAR_SETTING("CustomOcarina.A4Button"), BTN_CRIGHT}; +static CustomButtonMap ocarinaF4 = {"F4", CVAR_SETTING("CustomOcarina.F4Button"), BTN_CDOWN}; +static CustomButtonMap ocarinaD4 = {"D4", CVAR_SETTING("CustomOcarina.D4Button"), BTN_A}; +static CustomButtonMap ocarinaSongDisable = {"Disable songs", CVAR_SETTING("CustomOcarina.DisableButton"), BTN_L}; +static CustomButtonMap ocarinaSharp = {"Pitch up", CVAR_SETTING("CustomOcarina.SharpButton"), BTN_R}; +static CustomButtonMap ocarinaFlat = {"Pitch down", CVAR_SETTING("CustomOcarina.FlatButton"), BTN_Z}; + +// Draw a button mapping setting consisting of a padded label and button dropdown. +// excludedButtons indicates which buttons are unavailable to choose from. +void SohInputEditorWindow::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); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } + } + ImGui::EndCombo(); + } + UIWidgets::Spacer(0); +} + +void SohInputEditorWindow::DrawOcarinaControlPanel() { + 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", CVAR_SETTING("CustomOcarina.Enabled")); + + if (CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0) == 1) { + if (ImGui::BeginTable("tableCustomMainOcarinaControls", 2, ImGuiTableFlags_SizingStretchProp)) { + float labelWidth; + N64ButtonMask disableMask = BTN_B; + if (CVarGetInteger(CVAR_SETTING("OcarinaControl.Dpad"), 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); + + Ship::GuiWindow::BeginGroupPanel("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(); + Ship::GuiWindow::EndGroupPanel(0); + + TableHelper::NextCol(); + + Ship::GuiWindow::BeginGroupPanel("Modifiers", ImGui::GetContentRegionAvail()); + labelWidth = ImGui::CalcTextSize(ocarinaSongDisable.label).x + 10; + DrawMapping(ocarinaSongDisable, labelWidth, disableMask); + DrawMapping(ocarinaSharp, labelWidth, disableMask); + DrawMapping(ocarinaFlat, labelWidth, disableMask); + Ship::GuiWindow::EndGroupPanel(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); + } + + Ship::GuiWindow::BeginGroupPanel("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", CVAR_SETTING("OcarinaControl.Dpad")); + TableHelper::NextCol(); + UIWidgets::EnhancementCheckbox("Play with camera stick", CVAR_SETTING("OcarinaControl.RStick")); + UIWidgets::Spacer(0); + ImGui::EndTable(); + } + Ship::GuiWindow::EndGroupPanel(0); + + ImGui::EndTable(); +} + +void SohInputEditorWindow::DrawCameraControlPanel() { + ImVec2 cursor = ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); + Ship::GuiWindow::BeginGroupPanel("Aiming/First-Person Camera", ImGui::GetContentRegionAvail()); + UIWidgets::PaddedEnhancementCheckbox("Right Stick Aiming", CVAR_SETTING("Controls.RightStickAim")); + UIWidgets::Tooltip("Allows for aiming with the right stick in:\n-First-Person/C-Up view\n-Weapon Aiming"); + if (CVarGetInteger(CVAR_SETTING("Controls.RightStickAim"), 0)) { + UIWidgets::PaddedEnhancementCheckbox("Allow moving while in first person mode", CVAR_SETTING("MoveInFirstPerson")); + UIWidgets::Tooltip("Changes the left stick to move the player while in first person mode"); + } + UIWidgets::PaddedEnhancementCheckbox("Invert Aiming X Axis", CVAR_SETTING("Controls.InvertAimingXAxis")); + UIWidgets::Tooltip("Inverts the Camera X Axis in:\n-First-Person/C-Up view\n-Weapon Aiming"); + UIWidgets::PaddedEnhancementCheckbox("Invert Aiming Y Axis", CVAR_SETTING("Controls.InvertAimingYAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); + UIWidgets::Tooltip("Inverts the Camera Y Axis in:\n-First-Person/C-Up view\n-Weapon Aiming"); + UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming Y Axis", CVAR_SETTING("Controls.InvertShieldAimingYAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); + UIWidgets::Tooltip("Inverts the Shield Aiming Y Axis"); + UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming X Axis", CVAR_SETTING("Controls.InvertShieldAimingYAxis")); + UIWidgets::Tooltip("Inverts the Shield Aiming X Axis"); + UIWidgets::PaddedEnhancementCheckbox("Invert Z-Weapon Aiming Y Axis", CVAR_SETTING("Controls.InvertZAimingYAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); + UIWidgets::Tooltip("Inverts the Camera Y Axis in:\n-Z-Weapon Aiming"); + UIWidgets::PaddedEnhancementCheckbox("Disable Auto-Centering in First-Person View", CVAR_SETTING("DisableFirstPersonAutoCenterView")); + UIWidgets::Tooltip("Prevents the C-Up view from auto-centering, allowing for Gyro Aiming"); + if (UIWidgets::PaddedEnhancementCheckbox("Enable Custom Aiming/First-Person sensitivity", CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), true, false)) { + if (!CVarGetInteger(CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), 0)) { + CVarClear(CVAR_SETTING("FirstPersonCameraSensitivity.X")); + CVarClear(CVAR_SETTING("FirstPersonCameraSensitivity.Y")); + } + } + if (CVarGetInteger(CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), 0)) { + UIWidgets::EnhancementSliderFloat("Aiming/First-Person Horizontal Sensitivity: %.0f %%", "##FirstPersonSensitivity Horizontal", + CVAR_SETTING("FirstPersonCameraSensitivity.X"), 0.01f, 5.0f, "", 1.0f, true); + UIWidgets::EnhancementSliderFloat("Aiming/First-Person Vertical Sensitivity: %.0f %%", "##FirstPersonSensitivity Vertical", + CVAR_SETTING("FirstPersonCameraSensitivity.Y"), 0.01f, 5.0f, "", 1.0f, true); + } + UIWidgets::Spacer(0); + Ship::GuiWindow::EndGroupPanel(0); + + UIWidgets::Spacer(0); + cursor = ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); + Ship::GuiWindow::BeginGroupPanel("Third-Person Camera", ImGui::GetContentRegionAvail()); + + UIWidgets::PaddedEnhancementCheckbox("Free Look", CVAR_SETTING("FreeLook.Enabled")); + UIWidgets::Tooltip("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 Camera X Axis", CVAR_SETTING("FreeLook.InvertXAxis")); + UIWidgets::Tooltip("Inverts the Camera X Axis in:\n-Free look"); + UIWidgets::PaddedEnhancementCheckbox("Invert Camera Y Axis", CVAR_SETTING("FreeLook.InvertYAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); + UIWidgets::Tooltip("Inverts the Camera Y Axis in:\n-Free look"); + UIWidgets::Spacer(0); + UIWidgets::PaddedEnhancementSliderFloat("Third-Person Horizontal Sensitivity: %.0f %%", "##ThirdPersonSensitivity Horizontal", + CVAR_SETTING("FreeLook.CameraSensitivity.X"), 0.01f, 5.0f, "", 1.0f, true, true, false, true); + UIWidgets::PaddedEnhancementSliderFloat("Third-Person Vertical Sensitivity: %.0f %%", "##ThirdPersonSensitivity Vertical", + CVAR_SETTING("FreeLook.CameraSensitivity.Y"), 0.01f, 5.0f, "", 1.0f, true, true, false, true); + UIWidgets::PaddedEnhancementSliderInt("Camera Distance: %d", "##CamDist", + CVAR_SETTING("FreeLook.MaxCameraDistance"), 100, 900, "", 185, true, false, true); + UIWidgets::PaddedEnhancementSliderInt("Camera Transition Speed: %d", "##CamTranSpeed", + CVAR_SETTING("FreeLook.TransitionSpeed"), 0, 900, "", 25, true, false, true); + Ship::GuiWindow::EndGroupPanel(0); +} + +void SohInputEditorWindow::DrawDpadControlPanel() { + ImVec2 cursor = ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); + Ship::GuiWindow::BeginGroupPanel("D-Pad Options", ImGui::GetContentRegionAvail()); + UIWidgets::PaddedEnhancementCheckbox("D-pad Support on Pause Screen", CVAR_SETTING("DPadOnPause")); + UIWidgets::Tooltip("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 gSettings.DpadHoldChange to 0"); + UIWidgets::PaddedEnhancementCheckbox("D-pad Support in Text Boxes", CVAR_SETTING("DpadInText")); + UIWidgets::Tooltip("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 gSettings.DpadHoldChange to 0"); + UIWidgets::PaddedEnhancementCheckbox("D-pad as Equip Items", CVAR_SETTING("DpadEquips")); + UIWidgets::Tooltip("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"); + Ship::GuiWindow::EndGroupPanel(0); +} + +void SohInputEditorWindow::DrawMiscControlPanel() { + ImVec2 cursor = ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); + Ship::GuiWindow::BeginGroupPanel("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(CVAR_SETTING("PauseAnyCursor"), cursorOnAnySlot, PAUSE_ANY_CURSOR_RANDO_ONLY); + UIWidgets::Tooltip("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(CVAR_SETTING("DisableChanges"), 0)); + UIWidgets::PaddedEnhancementCheckbox("Enable speed modifiers", CVAR_SETTING("WalkModifier.Enabled"), true, false); + UIWidgets::Tooltip("Hold the assigned button to change the maximum walking or swimming speed"); + if (CVarGetInteger(CVAR_SETTING("WalkModifier.Enabled"), 0)) { + UIWidgets::Spacer(5); + Ship::GuiWindow::BeginGroupPanel("Speed Modifier", ImGui::GetContentRegionAvail()); + UIWidgets::PaddedEnhancementCheckbox("Toggle modifier instead of holding", CVAR_SETTING("WalkModifier.SpeedToggle"), true, false); + Ship::GuiWindow::BeginGroupPanel("Walk Modifier", ImGui::GetContentRegionAvail()); + UIWidgets::PaddedEnhancementCheckbox("Don't affect jump distance/velocity", CVAR_SETTING("WalkModifier.DoesntChangeJump"), true, false); + UIWidgets::PaddedEnhancementSliderFloat("Walk Modifier 1: %.0f %%", "##WalkMod1", CVAR_SETTING("WalkModifier.Mapping1"), 0.0f, 5.0f, "", 1.0f, true, true, false, true); + UIWidgets::PaddedEnhancementSliderFloat("Walk Modifier 2: %.0f %%", "##WalkMod2", CVAR_SETTING("WalkModifier.Mapping2"), 0.0f, 5.0f, "", 1.0f, true, true, false, true); + Ship::GuiWindow::EndGroupPanel(0); + Ship::GuiWindow::BeginGroupPanel("Swim Modifier", ImGui::GetContentRegionAvail()); + UIWidgets::PaddedEnhancementSliderFloat("Swim Modifier 1: %.0f %%", "##SwimMod1", CVAR_SETTING("WalkModifier.SwimMapping1"), 0.0f, 5.0f, "", 1.0f, true, true, false, true); + UIWidgets::PaddedEnhancementSliderFloat("Swim Modifier 2: %.0f %%", "##SwimMod2", CVAR_SETTING("WalkModifier.SwimMapping2"), 0.0f, 5.0f, "", 1.0f, true, true, false, true); + Ship::GuiWindow::EndGroupPanel(0); + Ship::GuiWindow::EndGroupPanel(0); + } + ImGui::EndDisabled(); + UIWidgets::Spacer(0); + UIWidgets::PaddedEnhancementCheckbox("Answer Navi Prompt with L Button", CVAR_SETTING("NaviOnL")); + UIWidgets::Tooltip("Speak to Navi with L but enter first-person camera with C-Up"); + Ship::GuiWindow::EndGroupPanel(0); +} + +void SohInputEditorWindow::DrawLinkTab() { + uint8_t portIndex = 0; + if (ImGui::BeginTabItem(StringHelper::Sprintf("Link (P1)###port%d", portIndex).c_str())) { + DrawClearAllButton(portIndex); + DrawSetDefaultsButton(portIndex); + + UpdateBitmaskToMappingIds(portIndex); + UpdateStickDirectionToMappingIds(portIndex); + + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.133f, 0.133f, 0.133f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + + if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + DrawButtonLine("A", portIndex, BTN_A, CHIP_COLOR_N64_BLUE); + DrawButtonLine("B", portIndex, BTN_B, CHIP_COLOR_N64_GREEN); + DrawButtonLine("Start", portIndex, BTN_START, CHIP_COLOR_N64_RED); + DrawButtonLine("L", portIndex, BTN_L); + DrawButtonLine("R", portIndex, BTN_R); + DrawButtonLine("Z", portIndex, BTN_Z); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_CUP, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_CDOWN, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_CLEFT, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT, + CHIP_COLOR_N64_YELLOW); + } else { + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + } + + if (ImGui::CollapsingHeader("D-Pad", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_DUP); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_DDOWN); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_DLEFT); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_DRIGHT); + } else { + DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + } + + if (ImGui::CollapsingHeader("Analog Stick", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK); + DrawStickSection(portIndex, Ship::LEFT, 0); + } else { + DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK); + } + + if (ImGui::CollapsingHeader("Additional (\"Right\") Stick")) { + DrawAnalogStickDeviceIcons(portIndex, Ship::RIGHT_STICK); + DrawStickSection(portIndex, Ship::RIGHT, 1, CHIP_COLOR_N64_YELLOW); + } else { + DrawAnalogStickDeviceIcons(portIndex, Ship::RIGHT_STICK); + } + + if (ImGui::CollapsingHeader("Rumble")) { + DrawRumbleDeviceIcons(portIndex); + DrawRumbleSection(portIndex); + } else { + DrawRumbleDeviceIcons(portIndex); + } + + if (ImGui::CollapsingHeader("Gyro")) { + DrawGyroDeviceIcons(portIndex); + DrawGyroSection(portIndex); + } else { + DrawGyroDeviceIcons(portIndex); + } + + if (ImGui::CollapsingHeader("LEDs")) { + DrawLEDDeviceIcons(portIndex); + DrawLEDSection(portIndex); + } else { + DrawLEDDeviceIcons(portIndex); + } + + if (ImGui::CollapsingHeader("Modifier Buttons")) { + DrawButtonDeviceIcons(portIndex, mModifierButtonsBitmasks); + DrawButtonLine("M1", portIndex, BTN_MODIFIER1); + DrawButtonLine("M2", portIndex, BTN_MODIFIER2); + } else { + DrawButtonDeviceIcons(portIndex, mModifierButtonsBitmasks); + } + + if (ImGui::CollapsingHeader("Ocarina Controls")) { + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + DrawOcarinaControlPanel(); + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.133f, 0.133f, 0.133f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + } + + if (ImGui::CollapsingHeader("Camera Controls")) { + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + DrawCameraControlPanel(); + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.133f, 0.133f, 0.133f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + } + + if (ImGui::CollapsingHeader("D-Pad Controls")) { + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + DrawDpadControlPanel(); + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.133f, 0.133f, 0.133f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + } + + if (ImGui::CollapsingHeader("Miscellaneous Controls")) { + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + DrawMiscControlPanel(); + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.133f, 0.133f, 0.133f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + } + + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::EndTabItem(); + } +} + +void SohInputEditorWindow::DrawIvanTab() { + if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0)) { + DrawDebugPortTab(1, "Ivan (P2)"); + return; + } + + uint8_t portIndex = 1; + if (ImGui::BeginTabItem(StringHelper::Sprintf("Ivan (P2)###port%d", portIndex).c_str())) { + DrawClearAllButton(portIndex); + DrawSetDefaultsButton(portIndex); + + UpdateBitmaskToMappingIds(portIndex); + UpdateStickDirectionToMappingIds(portIndex); + + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.133f, 0.133f, 0.133f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + + if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + DrawButtonLine("A", portIndex, BTN_A, CHIP_COLOR_N64_BLUE); + DrawButtonLine("B", portIndex, BTN_B, CHIP_COLOR_N64_GREEN); + DrawButtonLine("Z", portIndex, BTN_Z); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_CUP, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_CDOWN, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_CLEFT, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT, + CHIP_COLOR_N64_YELLOW); + } else { + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + } + + if (ImGui::CollapsingHeader("D-Pad", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_DUP); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_DDOWN); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_DLEFT); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_DRIGHT); + } else { + DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + } + + if (ImGui::CollapsingHeader("Analog Stick", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK); + DrawStickSection(portIndex, Ship::LEFT, 0); + } else { + DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK); + } + + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::EndTabItem(); + } +} + +void SohInputEditorWindow::DrawDebugPortTab(uint8_t portIndex, std::string customName) { + if (ImGui::BeginTabItem(customName == "" + ? StringHelper::Sprintf("Port %d###port%d", portIndex + 1, portIndex).c_str() + : customName.c_str())) { + DrawClearAllButton(portIndex); + DrawSetDefaultsButton(portIndex); + + UpdateBitmaskToMappingIds(portIndex); + UpdateStickDirectionToMappingIds(portIndex); + + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.133f, 0.133f, 0.133f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); + + if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + DrawButtonLine("A", portIndex, BTN_A, CHIP_COLOR_N64_BLUE); + DrawButtonLine("B", portIndex, BTN_B, CHIP_COLOR_N64_GREEN); + DrawButtonLine("Start", portIndex, BTN_START, CHIP_COLOR_N64_RED); + DrawButtonLine("L", portIndex, BTN_L); + DrawButtonLine("R", portIndex, BTN_R); + DrawButtonLine("Z", portIndex, BTN_Z); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_CUP, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_CDOWN, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_CLEFT, + CHIP_COLOR_N64_YELLOW); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT, + CHIP_COLOR_N64_YELLOW); + } else { + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + } + + if (ImGui::CollapsingHeader("D-Pad", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_DUP); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_DDOWN); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_DLEFT); + DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_DRIGHT); + } else { + DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + } + + if (ImGui::CollapsingHeader("Analog Stick", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { + DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK); + DrawStickSection(portIndex, Ship::LEFT, 0); + } else { + DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK); + } + + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::EndTabItem(); + } +} + +void SohInputEditorWindow::DrawClearAllButton(uint8_t portIndex) { + if (ImGui::Button("Clear All", ImGui::CalcTextSize("Clear All") * 2)) { + ImGui::OpenPopup("Clear All##clearAllPopup"); + } + if (ImGui::BeginPopupModal("Clear All##clearAllPopup", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("This will clear all mappings for port %d.\n\nContinue?", portIndex + 1); + if (ImGui::Button("Cancel")) { + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Clear All")) { + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->ClearAllMappings(); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } +} + +#ifdef __WIIU__ +void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) { + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); + auto popupId = StringHelper::Sprintf("setDefaultsPopup##%d", portIndex); + if (ImGui::Button(StringHelper::Sprintf("Set defaults...##%d", portIndex).c_str())) { + ImGui::OpenPopup(popupId.c_str()); + } + ImGui::PopStyleVar(); + + if (ImGui::BeginPopup(popupId.c_str())) { + std::map> indexMappings; + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappings()) { + auto wiiuIndexMapping = std::static_pointer_cast(mapping); + if (wiiuIndexMapping == nullptr) { + continue; + } + + indexMappings[lusIndex] = { wiiuIndexMapping->GetWiiUControllerName(), + wiiuIndexMapping->IsWiiUGamepad() ? INT32_MAX + : wiiuIndexMapping->GetDeviceChannel() }; + } + + bool shouldClose = false; + for (auto [lusIndex, info] : indexMappings) { + auto [name, wiiuChannel] = info; + bool isGamepad = wiiuChannel == INT32_MAX; + + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + + auto fancyName = StringHelper::Sprintf( + "%s%s", name.c_str(), isGamepad ? "" : StringHelper::Sprintf(" (%d)", wiiuChannel).c_str()); + if (ImGui::Button(StringHelper::Sprintf("%s %s", ICON_FA_GAMEPAD, fancyName.c_str()).c_str())) { + ImGui::OpenPopup(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str()); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + if (ImGui::BeginPopupModal(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str(), NULL, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("This will clear all existing mappings for\n%s on port %d.\n\nContinue?", fancyName.c_str(), + portIndex + 1); + if (ImGui::Button("Cancel")) { + shouldClose = true; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Set defaults")) { + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(portIndex) + ->ClearAllMappingsForDevice(lusIndex); + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings( + lusIndex); + shouldClose = true; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + } + + if (ImGui::Button("Cancel") || shouldClose) { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } +} + +void SohInputEditorWindow::DrawDevicesTab() { + if (ImGui::BeginTabItem("Devices")) { + std::map> indexMappings; + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappingsFromConfig()) { + auto wiiuIndexMapping = std::static_pointer_cast(mapping); + if (wiiuIndexMapping == nullptr) { + continue; + } + + indexMappings[lusIndex] = { wiiuIndexMapping->GetWiiUControllerName(), -1 }; + } + + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappings()) { + auto wiiuIndexMapping = std::static_pointer_cast(mapping); + if (wiiuIndexMapping == nullptr) { + continue; + } + + indexMappings[lusIndex] = { wiiuIndexMapping->GetWiiUControllerName(), + wiiuIndexMapping->IsWiiUGamepad() ? INT32_MAX + : wiiuIndexMapping->GetDeviceChannel() }; + } + + for (auto [lusIndex, info] : indexMappings) { + auto [name, wiiuChannel] = info; + bool connected = wiiuChannel != -1; + bool isGamepad = wiiuChannel == INT32_MAX; + + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::Button(StringHelper::Sprintf("%s %s%s", connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN, + name.c_str(), + !connected ? " (Disconnected)" + : isGamepad ? "" + : StringHelper::Sprintf(" (%d)", wiiuChannel).c_str()) + .c_str()); + ImGui::PopStyleColor(); + ImGui::PopItemFlag(); + } + + ImGui::EndTabItem(); + } +} +#else +void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) { + ImGui::SameLine(); + auto popupId = StringHelper::Sprintf("setDefaultsPopup##%d", portIndex); + if (ImGui::Button(StringHelper::Sprintf("Set Defaults##%d", portIndex).c_str(), + ImVec2(ImGui::CalcTextSize("Set Defaults") * 2))) { + ImGui::OpenPopup(popupId.c_str()); + } + + if (ImGui::BeginPopup(popupId.c_str())) { + std::map> indexMappings; + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappings()) { + auto sdlIndexMapping = std::static_pointer_cast(mapping); + if (sdlIndexMapping == nullptr) { + continue; + } + + indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), sdlIndexMapping->GetSDLDeviceIndex() }; + } + + bool shouldClose = false; + ImGui::PushStyleColor(ImGuiCol_Button, BUTTON_COLOR_KEYBOARD_BEIGE); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, BUTTON_COLOR_KEYBOARD_BEIGE_HOVERED); + if (ImGui::Button(StringHelper::Sprintf("%s Keyboard", ICON_FA_KEYBOARD_O).c_str())) { + ImGui::OpenPopup("Set Defaults for Keyboard"); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + if (ImGui::BeginPopupModal("Set Defaults for Keyboard", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("This will clear all existing mappings for\nKeyboard on port %d.\n\nContinue?", portIndex + 1); + if (ImGui::Button("Cancel")) { + shouldClose = true; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Set defaults")) { + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(portIndex) + ->ClearAllMappingsForDevice(Ship::ShipDeviceIndex::Keyboard); + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings( + Ship::ShipDeviceIndex::Keyboard); + shouldClose = true; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + for (auto [lusIndex, info] : indexMappings) { + auto [name, sdlIndex] = info; + + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); + if (ImGui::Button(StringHelper::Sprintf("%s %s (%s)", ICON_FA_GAMEPAD, name.c_str(), + StringHelper::Sprintf("SDL %d", sdlIndex).c_str()) + .c_str())) { + ImGui::OpenPopup(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str()); + } + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + if (ImGui::BeginPopupModal(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str(), NULL, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("This will clear all existing mappings for\n%s (SDL %d) on port %d.\n\nContinue?", + name.c_str(), sdlIndex, portIndex + 1); + if (ImGui::Button("Cancel")) { + shouldClose = true; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Set defaults")) { + Ship::Context::GetInstance() + ->GetControlDeck() + ->GetControllerByPort(portIndex) + ->ClearAllMappingsForDevice(lusIndex); + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings( + lusIndex); + shouldClose = true; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + } + + if (ImGui::Button("Cancel") || shouldClose) { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } +} + +void SohInputEditorWindow::DrawDevicesTab() { + if (ImGui::BeginTabItem("Devices")) { + std::map> indexMappings; + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappingsFromConfig()) { + auto sdlIndexMapping = std::static_pointer_cast(mapping); + if (sdlIndexMapping == nullptr) { + continue; + } + + indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), -1 }; + } + + for (auto [lusIndex, mapping] : Ship::Context::GetInstance() + ->GetControlDeck() + ->GetDeviceIndexMappingManager() + ->GetAllDeviceIndexMappings()) { + auto sdlIndexMapping = std::static_pointer_cast(mapping); + if (sdlIndexMapping == nullptr) { + continue; + } + + indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), sdlIndexMapping->GetSDLDeviceIndex() }; + } + + for (auto [lusIndex, info] : indexMappings) { + auto [name, sdlIndex] = info; + bool connected = sdlIndex != -1; + + auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered); + GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor); + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleColor(ImGuiCol_Button, buttonColor); + ImGui::Button( + StringHelper::Sprintf("%s %s (%s)", connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN, name.c_str(), + connected ? StringHelper::Sprintf("SDL %d", sdlIndex).c_str() : "Disconnected") + .c_str()); + ImGui::PopStyleColor(); + ImGui::PopItemFlag(); + } + + ImGui::EndTabItem(); + } +} +#endif + +void SohInputEditorWindow::DrawElement() { + ImGui::Begin("Controller Configuration###sohControllerConfigWindowV1", &mIsVisible); + ImGui::BeginTabBar("##ControllerConfigPortTabs"); + DrawLinkTab(); + DrawIvanTab(); + if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0)) { + DrawDebugPortTab(2); + DrawDebugPortTab(3); + } + DrawDevicesTab(); + ImGui::EndTabBar(); + ImGui::End(); +} diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.h b/soh/soh/Enhancements/controls/SohInputEditorWindow.h new file mode 100644 index 000000000..b418a041e --- /dev/null +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.h @@ -0,0 +1,107 @@ +#pragma once + +#include "stdint.h" +#include +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include +#include +#include +#include +#include +#include + +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> buttons; + std::unordered_map 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 mRumbleMappingToTest; + + // mBitmaskToMappingIds[port][bitmask] = { id0, id1, ... } + std::unordered_map>> mBitmaskToMappingIds; + + // mStickDirectionToMappingIds[port][stick][direction] = { id0, id1, ... } + std::unordered_map>>> + 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 mButtonsBitmasks; + std::set mDpadBitmasks; + std::set mModifierButtonsBitmasks; + void DrawButtonDeviceIcons(uint8_t portIndex, std::set 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); +}; diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 378197bcd..b932d24cc 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -13,6 +13,7 @@ #include #include "soh/UIWidgets.hpp" +#include "soh/OTRGlobals.h" extern "C" { #include @@ -57,42 +58,24 @@ u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); #define dgEndGrayscaleAndEndDlistDL "__OTR__helpers/cosmetics/gEndGrayscaleAndEndDlistDL" static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL; -// 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 { - GROUP_LINK, - GROUP_MIRRORSHIELD, - GROUP_SWORDS, - GROUP_GLOVES, - GROUP_EQUIPMENT, - GROUP_CONSUMABLE, - GROUP_HUD, - GROUP_TITLE, - GROUP_NPC, - GROUP_WORLD, - GROUP_MAGIC, - GROUP_ARROWS, - GROUP_SPIN_ATTACK, - GROUP_TRAILS, - GROUP_NAVI, -} CosmeticGroup; - std::map groupLabels = { - { GROUP_LINK, "Link" }, - { GROUP_MIRRORSHIELD, "Mirror Shield" }, - { GROUP_SWORDS, "Swords" }, - { GROUP_GLOVES, "Gloves" }, - { GROUP_EQUIPMENT, "Equipment" }, - { GROUP_CONSUMABLE, "Consumables" }, - { GROUP_HUD, "HUD" }, - { GROUP_TITLE, "Title Screen" }, - { GROUP_NPC, "NPCs" }, - { GROUP_WORLD, "World" }, - { GROUP_MAGIC, "Magic Effects" }, - { GROUP_ARROWS, "Arrow Effects" }, - { GROUP_SPIN_ATTACK, "Spin Attack" }, - { GROUP_TRAILS, "Trails" }, - { GROUP_NAVI, "Navi" }, + { COSMETICS_GROUP_LINK, "Link" }, + { COSMETICS_GROUP_MIRRORSHIELD, "Mirror Shield" }, + { COSMETICS_GROUP_SWORDS, "Swords" }, + { COSMETICS_GROUP_GLOVES, "Gloves" }, + { COSMETICS_GROUP_EQUIPMENT, "Equipment" }, + { COSMETICS_GROUP_CONSUMABLE, "Consumables" }, + { COSMETICS_GROUP_HUD, "HUD" }, + { COSMETICS_GROUP_KALEIDO, "Pause Menu" }, + { COSMETICS_GROUP_TITLE, "Title Screen" }, + { COSMETICS_GROUP_NPC, "NPCs" }, + { COSMETICS_GROUP_WORLD, "World" }, + { COSMETICS_GROUP_MAGIC, "Magic Effects" }, + { COSMETICS_GROUP_ARROWS, "Arrow Effects" }, + { COSMETICS_GROUP_SPIN_ATTACK, "Spin Attack" }, + { COSMETICS_GROUP_TRAILS, "Trails" }, + { COSMETICS_GROUP_NAVI, "Navi" }, + { COSMETICS_GROUP_IVAN, "Ivan" } }; typedef struct { @@ -111,7 +94,7 @@ typedef struct { #define COSMETIC_OPTION(id, label, group, defaultColor, supportsAlpha, supportsRainbow, advancedOption) \ { id, { \ - "gCosmetics." id ".Value", "gCosmetics." id ".Rainbow", "gCosmetics." id ".Locked", "gCosmetics." id ".Changed", label, group, \ + CVAR_COSMETIC(id ".Value"), CVAR_COSMETIC(id ".Rainbow"), CVAR_COSMETIC(id ".Locked"), CVAR_COSMETIC(id ".Changed"), label, group, \ defaultColor, defaultColor, \ supportsAlpha, supportsRainbow, advancedOption \ } } @@ -170,8 +153,8 @@ typedef struct { gDPSetEnvColor(POLY_OPA_DISP++, 80, 70, 20, alpha); // with cosmetics change - if (CVarGetInteger("gCosmetics.World_Moon.Changed", 0)) { - Color_RGB8 moonColor = CVarGetColor24("gCosmetics.World_Moon.Value", (Color_RGB8){ 0, 0, 240 }); + if (CVarGetInteger(CVAR_COSMETIC("World.Moon.Changed"), 0)) { + Color_RGB8 moonColor = CVarGetColor24(CVAR_COSMETIC("World.Moon.Value"), (Color_RGB8){ 0, 0, 240 }); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, moonColor.r, moonColor.g, moonColor.b, alpha); gDPSetEnvColor(POLY_OPA_DISP++, moonColor.r / 2, moonColor.g / 2, moonColor.b / 2, alpha); } else { @@ -190,153 +173,189 @@ typedef struct { colors were darker than the gDPSetPrimColor. You will see many more examples of this below in the `ApplyOrResetCustomGfxPatches` method */ static std::map cosmeticOptions = { - COSMETIC_OPTION("Link_KokiriTunic", "Kokiri Tunic", GROUP_LINK, ImVec4( 30, 105, 27, 255), false, true, false), - COSMETIC_OPTION("Link_GoronTunic", "Goron Tunic", GROUP_LINK, ImVec4(100, 20, 0, 255), false, true, false), - COSMETIC_OPTION("Link_ZoraTunic", "Zora Tunic", GROUP_LINK, ImVec4( 0, 60, 100, 255), false, true, false), - COSMETIC_OPTION("Link_Hair", "Hair", GROUP_LINK, ImVec4(255, 173, 27, 255), false, true, true), - COSMETIC_OPTION("Link_Linen", "Linen", GROUP_LINK, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Link_Boots", "Boots", GROUP_LINK, ImVec4( 93, 44, 18, 255), false, true, true), + COSMETIC_OPTION("Link.KokiriTunic", "Kokiri Tunic", COSMETICS_GROUP_LINK, ImVec4( 30, 105, 27, 255), false, true, false), + COSMETIC_OPTION("Link.GoronTunic", "Goron Tunic", COSMETICS_GROUP_LINK, ImVec4(100, 20, 0, 255), false, true, false), + COSMETIC_OPTION("Link.ZoraTunic", "Zora Tunic", COSMETICS_GROUP_LINK, ImVec4( 0, 60, 100, 255), false, true, false), + COSMETIC_OPTION("Link.Hair", "Hair", COSMETICS_GROUP_LINK, ImVec4(255, 173, 27, 255), false, true, true), + COSMETIC_OPTION("Link.Linen", "Linen", COSMETICS_GROUP_LINK, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Link.Boots", "Boots", COSMETICS_GROUP_LINK, ImVec4( 93, 44, 18, 255), false, true, true), - COSMETIC_OPTION("MirrorShield_Body", "Body", GROUP_MIRRORSHIELD, ImVec4(215, 0, 0, 255), false, true, false), - COSMETIC_OPTION("MirrorShield_Mirror", "Mirror", GROUP_MIRRORSHIELD, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("MirrorShield_Emblem", "Emblem", GROUP_MIRRORSHIELD, ImVec4(205, 225, 255, 255), false, true, true), + COSMETIC_OPTION("MirrorShield.Body", "Body", COSMETICS_GROUP_MIRRORSHIELD, ImVec4(215, 0, 0, 255), false, true, false), + COSMETIC_OPTION("MirrorShield.Mirror", "Mirror", COSMETICS_GROUP_MIRRORSHIELD, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("MirrorShield.Emblem", "Emblem", COSMETICS_GROUP_MIRRORSHIELD, ImVec4(205, 225, 255, 255), false, true, true), - COSMETIC_OPTION("Swords_KokiriBlade", "Kokiri Sword Blade", GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Swords_KokiriHilt", "Kokiri Sword Hilt", GROUP_SWORDS, ImVec4(160, 100, 15, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale - COSMETIC_OPTION("Swords_MasterBlade", "Master Sword Blade", GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Swords_MasterHilt", "Master Sword Hilt", GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale - COSMETIC_OPTION("Swords_BiggoronBlade", "Biggoron Sword Blade", GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Swords_BiggoronHilt", "Biggoron Sword Hilt", GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale + COSMETIC_OPTION("Swords.KokiriBlade", "Kokiri Sword Blade", COSMETICS_GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), + // COSMETIC_OPTION("Swords.KokiriHilt", "Kokiri Sword Hilt", COSMETICS_GROUP_SWORDS, ImVec4(160, 100, 15, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale + COSMETIC_OPTION("Swords.MasterBlade", "Master Sword Blade", COSMETICS_GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), + // COSMETIC_OPTION("Swords.MasterHilt", "Master Sword Hilt", COSMETICS_GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale + COSMETIC_OPTION("Swords.BiggoronBlade", "Biggoron Sword Blade", COSMETICS_GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), + // COSMETIC_OPTION("Swords.BiggoronHilt", "Biggoron Sword Hilt", COSMETICS_GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale - COSMETIC_OPTION("Gloves_GoronBracelet", "Goron Bracelet", GROUP_GLOVES, ImVec4(255, 255, 170, 255), false, true, false), - COSMETIC_OPTION("Gloves_SilverGauntlets", "Silver Gauntlets", GROUP_GLOVES, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Gloves_GoldenGauntlets", "Golden Gauntlets", GROUP_GLOVES, ImVec4(254, 207, 15, 255), false, true, false), - COSMETIC_OPTION("Gloves_GauntletsGem", "Gauntlets Gem", GROUP_GLOVES, ImVec4(255, 60, 100, 255), false, true, true), + COSMETIC_OPTION("Gloves.GoronBracelet", "Goron Bracelet", COSMETICS_GROUP_GLOVES, ImVec4(255, 255, 170, 255), false, true, false), + COSMETIC_OPTION("Gloves.SilverGauntlets", "Silver Gauntlets", COSMETICS_GROUP_GLOVES, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Gloves.GoldenGauntlets", "Golden Gauntlets", COSMETICS_GROUP_GLOVES, ImVec4(254, 207, 15, 255), false, true, false), + COSMETIC_OPTION("Gloves.GauntletsGem", "Gauntlets Gem", COSMETICS_GROUP_GLOVES, ImVec4(255, 60, 100, 255), false, true, true), - COSMETIC_OPTION("Equipment_BoomerangBody", "Boomerang Body", GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, false), - COSMETIC_OPTION("Equipment_BoomerangGem", "Boomerang Gem", GROUP_EQUIPMENT, ImVec4(255, 50, 150, 255), false, true, true), - // COSMETIC_OPTION("Equipment_SlingshotBody", "Slingshot Body", GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale - COSMETIC_OPTION("Equipment_SlingshotString", "Slingshot String", GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Equipment_HammerHead", "Hammer Head", GROUP_EQUIPMENT, ImVec4(155, 192, 201, 255), false, true, false), - COSMETIC_OPTION("Equipment_HammerHandle", "Hammer Handle", GROUP_EQUIPMENT, ImVec4(110, 60, 0, 255), false, true, true), - // COSMETIC_OPTION("Equipment_HookshotChain", "Hookshot Chain", GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement - // COSMETIC_OPTION("Equipment_HookshotTip", "Hookshot Tip", GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement - COSMETIC_OPTION("HookshotReticle_Target", "Hookshotable Reticle", GROUP_EQUIPMENT, ImVec4( 0, 255, 0, 255), false, false, false), - COSMETIC_OPTION("HookshotReticle_NonTarget", "Non-Hookshotable Reticle", GROUP_EQUIPMENT, ImVec4(255, 0, 0, 255), false, false, false), - COSMETIC_OPTION("Equipment_BowTips", "Bow Tips", GROUP_EQUIPMENT, ImVec4(200, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Equipment_BowString", "Bow String", GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Equipment_BowBody", "Bow Body", GROUP_EQUIPMENT, ImVec4(140, 90, 10, 255), false, true, false), - COSMETIC_OPTION("Equipment_BowHandle", "Bow Handle", GROUP_EQUIPMENT, ImVec4( 50, 150, 255, 255), false, true, true), - COSMETIC_OPTION("Equipment_ChuFace", "Bombchu Face", GROUP_EQUIPMENT, ImVec4( 0, 100, 150, 255), false, true, true), - COSMETIC_OPTION("Equipment_ChuBody", "Bombchu Body", GROUP_EQUIPMENT, ImVec4(180, 130, 50, 255), false, true, true), - COSMETIC_OPTION("Equipment_BunnyHood", "Bunny Hood", GROUP_EQUIPMENT, ImVec4(255, 235, 109, 255), false, true, true), + COSMETIC_OPTION("Equipment.BoomerangBody", "Boomerang Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, false), + COSMETIC_OPTION("Equipment.BoomerangGem", "Boomerang Gem", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 50, 150, 255), false, true, true), + // COSMETIC_OPTION("Equipment.SlingshotBody", "Slingshot Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale + COSMETIC_OPTION("Equipment.SlingshotString", "Slingshot String", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Equipment.HammerHead", "Hammer Head", COSMETICS_GROUP_EQUIPMENT, ImVec4(155, 192, 201, 255), false, true, false), + COSMETIC_OPTION("Equipment.HammerHandle", "Hammer Handle", COSMETICS_GROUP_EQUIPMENT, ImVec4(110, 60, 0, 255), false, true, true), + // COSMETIC_OPTION("Equipment.HookshotChain", "Hookshot Chain", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement + // COSMETIC_OPTION("Equipment.HookshotTip", "Hookshot Tip", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement + COSMETIC_OPTION("HookshotReticle.Target", "Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT, ImVec4( 0, 255, 0, 255), false, false, false), + COSMETIC_OPTION("HookshotReticle.NonTarget", "Non-Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 0, 0, 255), false, false, false), + COSMETIC_OPTION("Equipment.BowTips", "Bow Tips", COSMETICS_GROUP_EQUIPMENT, ImVec4(200, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Equipment.BowString", "Bow String", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Equipment.BowBody", "Bow Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(140, 90, 10, 255), false, true, false), + COSMETIC_OPTION("Equipment.BowHandle", "Bow Handle", COSMETICS_GROUP_EQUIPMENT, ImVec4( 50, 150, 255, 255), false, true, true), + COSMETIC_OPTION("Equipment.ChuFace", "Bombchu Face", COSMETICS_GROUP_EQUIPMENT, ImVec4( 0, 100, 150, 255), false, true, true), + COSMETIC_OPTION("Equipment.ChuBody", "Bombchu Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(180, 130, 50, 255), false, true, true), + COSMETIC_OPTION("Equipment.BunnyHood", "Bunny Hood", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 235, 109, 255), false, true, true), - COSMETIC_OPTION("Consumable_Hearts", "Hearts", GROUP_CONSUMABLE, ImVec4(255, 70, 50, 255), false, true, false), - COSMETIC_OPTION("Consumable_HeartBorder", "Heart Border", GROUP_CONSUMABLE, ImVec4( 50, 40, 60, 255), false, true, true), - COSMETIC_OPTION("Consumable_DDHearts", "DD Hearts", GROUP_CONSUMABLE, ImVec4(200, 0, 0, 255), false, true, false), - COSMETIC_OPTION("Consumable_DDHeartBorder", "DD Heart Border", GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Consumable_Magic", "Magic", GROUP_CONSUMABLE, ImVec4( 0, 200, 0, 255), false, true, false), - COSMETIC_OPTION("Consumable_MagicActive", "Magic Active", GROUP_CONSUMABLE, ImVec4(250, 250, 0, 255), false, true, true), - COSMETIC_OPTION("Consumable_MagicBorder", "Magic Border", GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, false, true), - COSMETIC_OPTION("Consumable_MagicBorderActive", "Magic Border Active", GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, false, true), - COSMETIC_OPTION("Consumable_GreenRupee", "Green Rupee", GROUP_CONSUMABLE, ImVec4( 50, 255, 50, 255), false, true, true), - COSMETIC_OPTION("Consumable_BlueRupee", "Blue Rupee", GROUP_CONSUMABLE, ImVec4( 50, 50, 255, 255), false, true, true), - COSMETIC_OPTION("Consumable_RedRupee", "Red Rupee", GROUP_CONSUMABLE, ImVec4(255, 50, 50, 255), false, true, true), - COSMETIC_OPTION("Consumable_PurpleRupee", "Purple Rupee", GROUP_CONSUMABLE, ImVec4(150, 50, 255, 255), false, true, true), - COSMETIC_OPTION("Consumable_GoldRupee", "Gold Rupee", GROUP_CONSUMABLE, ImVec4(255, 190, 55, 255), false, true, true), - COSMETIC_OPTION("Consumable_SilverRupee", "Silver Rupee", GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.Hearts", "Hearts", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 70, 50, 255), false, true, false), + COSMETIC_OPTION("Consumable.HeartBorder", "Heart Border", COSMETICS_GROUP_CONSUMABLE, ImVec4( 50, 40, 60, 255), false, true, true), + COSMETIC_OPTION("Consumable.DDHearts", "DD Hearts", COSMETICS_GROUP_CONSUMABLE, ImVec4(200, 0, 0, 255), false, true, false), + COSMETIC_OPTION("Consumable.DDHeartBorder", "DD Heart Border", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.Magic", "Magic", COSMETICS_GROUP_CONSUMABLE, ImVec4( 0, 200, 0, 255), false, true, false), + COSMETIC_OPTION("Consumable.MagicActive", "Magic Active", COSMETICS_GROUP_CONSUMABLE, ImVec4(250, 250, 0, 255), false, true, true), + COSMETIC_OPTION("Consumable.MagicBorder", "Magic Border", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, false, true), + COSMETIC_OPTION("Consumable.MagicBorderActive", "Magic Border Active", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, false, true), + COSMETIC_OPTION("Consumable.GreenRupee", "Green Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4( 50, 255, 50, 255), false, true, true), + COSMETIC_OPTION("Consumable.BlueRupee", "Blue Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4( 50, 50, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.RedRupee", "Red Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 50, 50, 255), false, true, true), + COSMETIC_OPTION("Consumable.PurpleRupee", "Purple Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(150, 50, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.GoldRupee", "Gold Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 190, 55, 255), false, true, true), + COSMETIC_OPTION("Consumable.SilverRupee", "Silver Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Hud_AButton", "A Button", GROUP_HUD, ImVec4( 90, 90, 255, 255), false, true, false), - COSMETIC_OPTION("Hud_BButton", "B Button", GROUP_HUD, ImVec4( 0, 150, 0, 255), false, true, false), - COSMETIC_OPTION("Hud_CButtons", "C Buttons", GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, false), - COSMETIC_OPTION("Hud_CUpButton", "C Up Button", GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("Hud_CDownButton", "C Down Button", GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("Hud_CLeftButton", "C Left Button", GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("Hud_CRightButton", "C Right Button", GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("Hud_StartButton", "Start Button", GROUP_HUD, ImVec4(200, 0, 0, 255), false, true, false), - COSMETIC_OPTION("Hud_Dpad", "Dpad", GROUP_HUD, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Hud_KeyCount", "Key Count", GROUP_HUD, ImVec4(200, 230, 255, 255), false, true, true), - COSMETIC_OPTION("Hud_StoneOfAgony", "Stone of Agony", GROUP_HUD, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Hud_Minimap", "Minimap", GROUP_HUD, ImVec4( 0, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Hud_MinimapPosition", "Minimap Position", GROUP_HUD, ImVec4(200, 255, 0, 255), false, true, true), - COSMETIC_OPTION("Hud_MinimapEntrance", "Minimap Entrance", GROUP_HUD, ImVec4(200, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Hud_EnemyHealthBar", "Enemy Health Bar", GROUP_HUD, ImVec4(255, 0, 0, 255), true, true, false), - COSMETIC_OPTION("Hud_EnemyHealthBorder", "Enemy Health Border", GROUP_HUD, ImVec4(255, 255, 255, 255), true, false, true), - COSMETIC_OPTION("Hud_NameTagActorText", "Nametag Text", GROUP_HUD, ImVec4(255, 255, 255, 255), true, true, false), - COSMETIC_OPTION("Hud_NameTagActorBackground", "Nametag Background", GROUP_HUD, ImVec4(0, 0, 0, 80), true, false, true), + COSMETIC_OPTION("HUD.AButton", "A Button", COSMETICS_GROUP_HUD, ImVec4( 90, 90, 255, 255), false, true, false), + COSMETIC_OPTION("HUD.BButton", "B Button", COSMETICS_GROUP_HUD, ImVec4( 0, 150, 0, 255), false, true, false), + COSMETIC_OPTION("HUD.CButtons", "C Buttons", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, false), + COSMETIC_OPTION("HUD.CUpButton", "C Up Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.CDownButton", "C Down Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.CLeftButton", "C Left Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.CRightButton", "C Right Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.StartButton", "Start Button", COSMETICS_GROUP_HUD, ImVec4(200, 0, 0, 255), false, true, false), + COSMETIC_OPTION("HUD.Dpad", "Dpad", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("HUD.KeyCount", "Key Count", COSMETICS_GROUP_HUD, ImVec4(200, 230, 255, 255), false, true, true), + COSMETIC_OPTION("HUD.StoneOfAgony", "Stone of Agony", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("HUD.Minimap", "Minimap", COSMETICS_GROUP_HUD, ImVec4( 0, 255, 255, 255), false, true, false), + COSMETIC_OPTION("HUD.MinimapPosition", "Minimap Position", COSMETICS_GROUP_HUD, ImVec4(200, 255, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.MinimapEntrance", "Minimap Entrance", COSMETICS_GROUP_HUD, ImVec4(200, 0, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.EnemyHealthBar", "Enemy Health Bar", COSMETICS_GROUP_HUD, ImVec4(255, 0, 0, 255), true, true, false), + COSMETIC_OPTION("HUD.EnemyHealthBorder", "Enemy Health Border", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), true, false, true), + COSMETIC_OPTION("HUD.NameTagActorText", "Nametag Text", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), true, true, false), + COSMETIC_OPTION("HUD.NameTagActorBackground", "Nametag Background", COSMETICS_GROUP_HUD, ImVec4(0, 0, 0, 80), true, false, true), + // Todo (Cosmetics): re-implement title card colors - COSMETIC_OPTION("Title_FileChoose", "File Choose", GROUP_TITLE, ImVec4(100, 150, 255, 255), false, true, false), - COSMETIC_OPTION("Title_NintendoLogo", "Nintendo Logo", GROUP_TITLE, ImVec4( 0, 0, 255, 255), false, true, true), - COSMETIC_OPTION("Title_N64LogoRed", "N64 Red", GROUP_TITLE, ImVec4(150, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Title_N64LogoBlue", "N64 Blue", GROUP_TITLE, ImVec4( 0, 50, 150, 255), false, true, true), - COSMETIC_OPTION("Title_N64LogoGreen", "N64 Green", GROUP_TITLE, ImVec4( 50, 100, 0, 255), false, true, true), - COSMETIC_OPTION("Title_N64LogoYellow", "N64 Yellow", GROUP_TITLE, ImVec4(200, 150, 0, 255), false, true, true), - // COSMETIC_OPTION("Title_FirePrimary", "Title Fire Primary", GROUP_TITLE, ImVec4(255, 255, 170, 255), false, true, false), // Todo (Cosmetics): Kinda complicated - // COSMETIC_OPTION("Title_FireSecondary", "Title Fire Secondary", GROUP_TITLE, ImVec4(255, 100, 0, 255), false, true, true), // Todo (Cosmetics): Kinda complicated + COSMETIC_OPTION("Kaleido.ItemSelA", "Item Select Color", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, false), + COSMETIC_OPTION("Kaleido.ItemSelB", "Item Select Color B", COSMETICS_GROUP_KALEIDO, ImVec4(70, 100, 130, 255), false, true, true), + COSMETIC_OPTION("Kaleido.ItemSelC", "Item Select Color C", COSMETICS_GROUP_KALEIDO, ImVec4(70, 100, 130, 255), false, true, true), + COSMETIC_OPTION("Kaleido.ItemSelD", "Item Select Color D", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, true), - COSMETIC_OPTION("Arrows_NormalPrimary", "Normal Primary", GROUP_ARROWS, ImVec4( 0, 150, 0, 0), false, true, false), - COSMETIC_OPTION("Arrows_NormalSecondary", "Normal Secondary", GROUP_ARROWS, ImVec4(255, 255, 170, 255), false, true, true), - COSMETIC_OPTION("Arrows_FirePrimary", "Fire Primary", GROUP_ARROWS, ImVec4(255, 200, 0, 0), false, true, false), - COSMETIC_OPTION("Arrows_FireSecondary", "Fire Secondary", GROUP_ARROWS, ImVec4(255, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Arrows_IcePrimary", "Ice Primary", GROUP_ARROWS, ImVec4( 0, 0, 255, 255), false, true, false), - COSMETIC_OPTION("Arrows_IceSecondary", "Ice Secondary", GROUP_ARROWS, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Arrows_LightPrimary", "Light Primary", GROUP_ARROWS, ImVec4(255, 255, 0, 255), false, true, false), - COSMETIC_OPTION("Arrows_LightSecondary", "Light Secondary", GROUP_ARROWS, ImVec4(255, 255, 170, 0), false, true, true), + COSMETIC_OPTION("Kaleido.EquipSelA", "Equip Select Color", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 40, 255), false, true, false), + COSMETIC_OPTION("Kaleido.EquipSelB", "Equip Select Color B", COSMETICS_GROUP_KALEIDO, ImVec4(90, 100, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.EquipSelC", "Equip Select Color C", COSMETICS_GROUP_KALEIDO, ImVec4(90, 100, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.EquipSelD", "Equip Select Color D", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, true), - // COSMETIC_OPTION("Magic_DinsPrimary", "Din's Primary", GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Replace gDF_Col - // COSMETIC_OPTION("Magic_DinsSecondary", "Din's Secondary", GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Replace gDF_Env - // COSMETIC_OPTION("Magic_FaroresPrimary", "Farore's Primary", GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement - // COSMETIC_OPTION("Magic_FaroresSecondary", "Farore's Secondary", GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement - // COSMETIC_OPTION("Magic_NayrusPrimary", "Nayru's Primary", GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Replace gNL_Diamond_Col / gNL_Orb_Col - // COSMETIC_OPTION("Magic_NayrusSecondary", "Nayru's Secondary", GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Replace gNL_Diamond_Env / gNL_Orb_Env + COSMETIC_OPTION("Kaleido.MapSelDunA", "Map Dungeon Color", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelDunB", "Map Dungeon Color B", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelDunC", "Map Dungeon Color C", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelDunD", "Map Dungeon Color D", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, true), - COSMETIC_OPTION("SpinAttack_Level1Primary", "Level 1 Primary", GROUP_SPIN_ATTACK, ImVec4(170, 255, 255, 255), false, true, true), - COSMETIC_OPTION("SpinAttack_Level1Secondary", "Level 1 Secondary", GROUP_SPIN_ATTACK, ImVec4( 0, 100, 255, 255), false, true, false), - COSMETIC_OPTION("SpinAttack_Level2Primary", "Level 2 Primary", GROUP_SPIN_ATTACK, ImVec4(255, 255, 170, 255), false, true, true), - COSMETIC_OPTION("SpinAttack_Level2Secondary", "Level 2 Secondary", GROUP_SPIN_ATTACK, ImVec4(255, 100, 0, 255), false, true, false), + COSMETIC_OPTION("Kaleido.QuestStatusA", "Quest Status Color", COSMETICS_GROUP_KALEIDO, ImVec4(80, 80, 50, 255), false, true, false), + COSMETIC_OPTION("Kaleido.QuestStatusB", "Quest Status Color B", COSMETICS_GROUP_KALEIDO, ImVec4(120, 120, 70, 255), false, true, true), + COSMETIC_OPTION("Kaleido.QuestStatusC", "Quest Status Color C", COSMETICS_GROUP_KALEIDO, ImVec4(120, 120, 70, 255), false, true, true), + COSMETIC_OPTION("Kaleido.QuestStatusD", "Quest Status Color D", COSMETICS_GROUP_KALEIDO, ImVec4(80, 80, 50, 255), false, true, true), - COSMETIC_OPTION("Trails_Bombchu", "Bombchu", GROUP_TRAILS, ImVec4(250, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Trails_Boomerang", "Boomerang", GROUP_TRAILS, ImVec4(255, 255, 100, 255), false, true, true), - COSMETIC_OPTION("Trails_KokiriSword", "Kokiri Sword", GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Trails_MasterSword", "Master Sword", GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Trails_BiggoronSword", "Biggoron Sword", GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Trails_Stick", "Stick", GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Trails_Hammer", "Hammer", GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelectA", "Map Color", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, false), + COSMETIC_OPTION("Kaleido.MapSelectB", "Map Color B", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelectC", "Map Color C", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelectD", "Map Color D", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, true), - COSMETIC_OPTION("World_BlockOfTime", "Block of Time", GROUP_WORLD, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("World_Moon", "Moon", GROUP_WORLD, ImVec4(240, 255, 180, 255), false, true, true), - COSMETIC_OPTION("World_GossipStone", "Gossip Stone", GROUP_WORLD, ImVec4(200, 200, 200, 255), false, true, true), - COSMETIC_OPTION("World_RedIce", "Red Ice", GROUP_WORLD, ImVec4(255, 0, 0, 255), false, true, false), + COSMETIC_OPTION("Kaleido.SaveA", "Save Color", COSMETICS_GROUP_KALEIDO, ImVec4(50, 50, 50, 255), false, true, false), + COSMETIC_OPTION("Kaleido.SaveB", "Save Color B", COSMETICS_GROUP_KALEIDO, ImVec4(110, 110, 110, 255), false, true, true), + COSMETIC_OPTION("Kaleido.SaveC", "Save Color C", COSMETICS_GROUP_KALEIDO, ImVec4(110, 110, 110, 255), false, true, true), + COSMETIC_OPTION("Kaleido.SaveD", "Save Color D", COSMETICS_GROUP_KALEIDO, ImVec4(50, 50, 50, 255), false, true, true), - COSMETIC_OPTION("Navi_IdlePrimary", "Idle Primary", GROUP_NAVI, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Navi_IdleSecondary", "Idle Secondary", GROUP_NAVI, ImVec4( 0, 0, 255, 0), false, true, true), - COSMETIC_OPTION("Navi_NPCPrimary", "NPC Primary", GROUP_NAVI, ImVec4(150, 150, 255, 255), false, true, false), - COSMETIC_OPTION("Navi_NPCSecondary", "NPC Secondary", GROUP_NAVI, ImVec4(150, 150, 255, 0), false, true, true), - COSMETIC_OPTION("Navi_EnemyPrimary", "Enemy Primary", GROUP_NAVI, ImVec4(255, 255, 0, 255), false, true, false), - COSMETIC_OPTION("Navi_EnemySecondary", "Enemy Secondary", GROUP_NAVI, ImVec4(200, 155, 0, 0), false, true, true), - COSMETIC_OPTION("Navi_PropsPrimary", "Props Primary", GROUP_NAVI, ImVec4( 0, 255, 0, 255), false, true, false), - COSMETIC_OPTION("Navi_PropsSecondary", "Props Secondary", GROUP_NAVI, ImVec4( 0, 255, 0, 0), false, true, true), + COSMETIC_OPTION("Kaleido.NamePanel", "Name Panel", COSMETICS_GROUP_KALEIDO, ImVec4(90,100,130,255), true, true, false), - COSMETIC_OPTION("NPC_FireKeesePrimary", "Fire Keese Primary", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("NPC_FireKeeseSecondary", "Fire Keese Secondary", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("NPC_IceKeesePrimary", "Ice Keese Primary", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("NPC_IceKeeseSecondary", "Ice Keese Secondary", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Title.FileChoose", "File Choose", COSMETICS_GROUP_TITLE, ImVec4(100, 150, 255, 255), false, true, false), + COSMETIC_OPTION("Title.NintendoLogo", "Nintendo Logo", COSMETICS_GROUP_TITLE, ImVec4( 0, 0, 255, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoRed", "N64 Red", COSMETICS_GROUP_TITLE, ImVec4(150, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoBlue", "N64 Blue", COSMETICS_GROUP_TITLE, ImVec4( 0, 50, 150, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoGreen", "N64 Green", COSMETICS_GROUP_TITLE, ImVec4( 50, 100, 0, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoYellow", "N64 Yellow", COSMETICS_GROUP_TITLE, ImVec4(200, 150, 0, 255), false, true, true), + // COSMETIC_OPTION("Title.FirePrimary", "Title Fire Primary", COSMETICS_GROUP_TITLE, ImVec4(255, 255, 170, 255), false, true, false), // Todo (Cosmetics): Kinda complicated + // COSMETIC_OPTION("Title.FireSecondary", "Title Fire Secondary", COSMETICS_GROUP_TITLE, ImVec4(255, 100, 0, 255), false, true, true), // Todo (Cosmetics): Kinda complicated + + COSMETIC_OPTION("Arrows.NormalPrimary", "Normal Primary", COSMETICS_GROUP_ARROWS, ImVec4( 0, 150, 0, 0), false, true, false), + COSMETIC_OPTION("Arrows.NormalSecondary", "Normal Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 170, 255), false, true, true), + COSMETIC_OPTION("Arrows.FirePrimary", "Fire Primary", COSMETICS_GROUP_ARROWS, ImVec4(255, 200, 0, 0), false, true, false), + COSMETIC_OPTION("Arrows.FireSecondary", "Fire Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Arrows.IcePrimary", "Ice Primary", COSMETICS_GROUP_ARROWS, ImVec4( 0, 0, 255, 255), false, true, false), + COSMETIC_OPTION("Arrows.IceSecondary", "Ice Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Arrows.LightPrimary", "Light Primary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 0, 255), false, true, false), + COSMETIC_OPTION("Arrows.LightSecondary", "Light Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 170, 0), false, true, true), + + // COSMETIC_OPTION("Magic.DinsPrimary", "Din's Primary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), + // COSMETIC_OPTION("Magic.DinsSecondary", "Din's Secondary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), + // COSMETIC_OPTION("Magic.FaroresPrimary", "Farore's Primary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement + // COSMETIC_OPTION("Magic.FaroresSecondary", "Farore's Secondary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement + // COSMETIC_OPTION("Magic.NayrusPrimary", "Nayru's Primary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), + // COSMETIC_OPTION("Magic.NayrusSecondary", "Nayru's Secondary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), + + COSMETIC_OPTION("SpinAttack.Level1Primary", "Level 1 Primary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4(170, 255, 255, 255), false, true, true), + COSMETIC_OPTION("SpinAttack.Level1Secondary", "Level 1 Secondary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4( 0, 100, 255, 255), false, true, false), + COSMETIC_OPTION("SpinAttack.Level2Primary", "Level 2 Primary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4(255, 255, 170, 255), false, true, true), + COSMETIC_OPTION("SpinAttack.Level2Secondary", "Level 2 Secondary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4(255, 100, 0, 255), false, true, false), + + COSMETIC_OPTION("Trails.Bombchu", "Bombchu", COSMETICS_GROUP_TRAILS, ImVec4(250, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Trails.Boomerang", "Boomerang", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 100, 255), false, true, true), + COSMETIC_OPTION("Trails.KokiriSword", "Kokiri Sword", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Trails.MasterSword", "Master Sword", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Trails.BiggoronSword", "Biggoron Sword", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Trails.Stick", "Stick", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Trails.Hammer", "Hammer", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), + + COSMETIC_OPTION("World.BlockOfTime", "Block of Time", COSMETICS_GROUP_WORLD, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("World.Moon", "Moon", COSMETICS_GROUP_WORLD, ImVec4(240, 255, 180, 255), false, true, true), + COSMETIC_OPTION("World.GossipStone", "Gossip Stone", COSMETICS_GROUP_WORLD, ImVec4(200, 200, 200, 255), false, true, true), + COSMETIC_OPTION("World.RedIce", "Red Ice", COSMETICS_GROUP_WORLD, ImVec4(255, 0, 0, 255), false, true, false), + + COSMETIC_OPTION("Navi.IdlePrimary", "Idle Primary", COSMETICS_GROUP_NAVI, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Navi.IdleSecondary", "Idle Secondary", COSMETICS_GROUP_NAVI, ImVec4( 0, 0, 255, 0), false, true, true), + COSMETIC_OPTION("Navi.NPCPrimary", "NPC Primary", COSMETICS_GROUP_NAVI, ImVec4(150, 150, 255, 255), false, true, false), + COSMETIC_OPTION("Navi.NPCSecondary", "NPC Secondary", COSMETICS_GROUP_NAVI, ImVec4(150, 150, 255, 0), false, true, true), + COSMETIC_OPTION("Navi.EnemyPrimary", "Enemy Primary", COSMETICS_GROUP_NAVI, ImVec4(255, 255, 0, 255), false, true, false), + COSMETIC_OPTION("Navi.EnemySecondary", "Enemy Secondary", COSMETICS_GROUP_NAVI, ImVec4(200, 155, 0, 0), false, true, true), + COSMETIC_OPTION("Navi.PropsPrimary", "Props Primary", COSMETICS_GROUP_NAVI, ImVec4( 0, 255, 0, 255), false, true, false), + COSMETIC_OPTION("Navi.PropsSecondary", "Props Secondary", COSMETICS_GROUP_NAVI, ImVec4( 0, 255, 0, 0), false, true, true), + + COSMETIC_OPTION("Ivan.IdlePrimary", "Ivan Idle Primary", COSMETICS_GROUP_IVAN, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Ivan.IdleSecondary", "Ivan Idle Secondary", COSMETICS_GROUP_IVAN, ImVec4( 0, 255, 0, 255), false, true, true), + + COSMETIC_OPTION("NPC.FireKeesePrimary", "Fire Keese Primary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("NPC.FireKeeseSecondary", "Fire Keese Secondary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("NPC.IceKeesePrimary", "Ice Keese Primary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("NPC.IceKeeseSecondary", "Ice Keese Secondary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Health fairy - COSMETIC_OPTION("NPC_Dog1", "Dog 1", GROUP_NPC, ImVec4(255, 255, 200, 255), false, true, true), - COSMETIC_OPTION("NPC_Dog2", "Dog 2", GROUP_NPC, ImVec4(150, 100, 50, 255), false, true, true), - COSMETIC_OPTION("NPC_GoldenSkulltula", "Golden Skulltula", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("NPC_Kokiri", "Kokiri", GROUP_NPC, ImVec4( 0, 130, 70, 255), false, true, false), - COSMETIC_OPTION("NPC_Gerudo", "Gerudo", GROUP_NPC, ImVec4( 90, 0, 140, 255), false, true, false), - COSMETIC_OPTION("NPC_MetalTrap", "Metal Trap", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("NPC_IronKnuckles", "Iron Knuckles", GROUP_NPC, ImVec4(245, 255, 205, 255), false, true, false), + COSMETIC_OPTION("NPC.Dog1", "Dog 1", COSMETICS_GROUP_NPC, ImVec4(255, 255, 200, 255), false, true, true), + COSMETIC_OPTION("NPC.Dog2", "Dog 2", COSMETICS_GROUP_NPC, ImVec4(150, 100, 50, 255), false, true, true), + COSMETIC_OPTION("NPC.GoldenSkulltula", "Golden Skulltula", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("NPC.Kokiri", "Kokiri", COSMETICS_GROUP_NPC, ImVec4( 0, 130, 70, 255), false, true, false), + COSMETIC_OPTION("NPC.Gerudo", "Gerudo", COSMETICS_GROUP_NPC, ImVec4( 90, 0, 140, 255), false, true, false), + COSMETIC_OPTION("NPC.MetalTrap", "Metal Trap", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("NPC.IronKnuckles", "Iron Knuckles", COSMETICS_GROUP_NPC, ImVec4(245, 255, 205, 255), false, true, false), }; static const char* MarginCvarList[] { - "gHearts", "gHeartsCount", "gMagicBar", "gVSOA", "gBBtn", "gABtn", "gStartBtn", - "gCBtnU", "gCBtnD", "gCBtnL", "gCBtnR", "gDPad", "gMinimap", - "gSKC", "gRC", "gCarrots", "gTimers", "gAS", "gTCM", "gTCB", "gIGT" + CVAR_COSMETIC("HUD.Hearts"), CVAR_COSMETIC("HUD.HeartsCount"), CVAR_COSMETIC("HUD.MagicBar"), CVAR_COSMETIC("HUD.VisualSoA"), CVAR_COSMETIC("HUD.BButton"), CVAR_COSMETIC("HUD.AButton"), CVAR_COSMETIC("HUD.StartButton"), + CVAR_COSMETIC("HUD.CUpButton"), CVAR_COSMETIC("HUD.CDownButton"), CVAR_COSMETIC("HUD.CLeftButton"), CVAR_COSMETIC("HUD.CRightButton"), CVAR_COSMETIC("HUD.Dpad"), CVAR_COSMETIC("HUD.Minimap"), + CVAR_COSMETIC("HUD.SmallKey"), CVAR_COSMETIC("HUD.Rupees"), CVAR_COSMETIC("HUD.Carrots"), CVAR_COSMETIC("HUD.Timers"), CVAR_COSMETIC("HUD.ArcheryScore"), CVAR_COSMETIC("HUD.TitleCard.Map"), CVAR_COSMETIC("HUD.TitleCard.Boss"), CVAR_COSMETIC("HUD.IGT") }; -static const char* MarginCvarNonAnchor[]{ "gCarrots", "gTimers", "gAS", "gTCM","gTCB" }; +static const char* MarginCvarNonAnchor[]{ CVAR_COSMETIC("HUD.Carrots"), CVAR_COSMETIC("HUD.Timers"), CVAR_COSMETIC("HUD.ArcheryScore"), CVAR_COSMETIC("HUD.TitleCard.Map"),CVAR_COSMETIC("HUD.TitleCard.Boss") }; ImVec4 GetRandomValue(int MaximumPossible){ ImVec4 NewColor; @@ -361,8 +380,8 @@ void SetMarginAll(const char* ButtonName, bool SetActivated) { //MarginCvarNonAnchor is an array that list every element that has No anchor by default, because if that the case this function will not touch it with pose type 0. u8 arrayLengthNonMargin = sizeof(MarginCvarNonAnchor) / sizeof(*MarginCvarNonAnchor); for (auto cvarName : MarginCvarList) { - std::string cvarPosType = std::string(cvarName).append("PosType"); - std::string cvarNameMargins = std::string(cvarName).append("UseMargins"); + std::string cvarPosType = std::string(cvarName).append(".PosType"); + std::string cvarNameMargins = std::string(cvarName).append(".UseMargins"); if (CVarGetInteger(cvarPosType.c_str(),0) <= 2 && SetActivated) { //Our element is not Hidden or Non anchor for (int i = 0; i < arrayLengthNonMargin; i++){ if ((strcmp(cvarName, MarginCvarNonAnchor[i]) == 0) && (CVarGetInteger(cvarPosType.c_str(), 0) == 0)) { //Our element is both in original position and do not have anchor by default so we skip it. @@ -385,8 +404,8 @@ void SetMarginAll(const char* ButtonName, bool SetActivated) { void ResetPositionAll() { if (ImGui::Button("Reset all positions")) { for (auto cvarName : MarginCvarList) { - std::string cvarPosType = std::string(cvarName).append("PosType"); - std::string cvarNameMargins = std::string(cvarName).append("UseMargins"); + std::string cvarPosType = std::string(cvarName).append(".PosType"); + std::string cvarNameMargins = std::string(cvarName).append(".UseMargins"); CVarSetInteger(cvarPosType.c_str(), 0); CVarSetInteger(cvarNameMargins.c_str(), false); //Turn margin off to everythings as that original position. } @@ -398,7 +417,7 @@ int hue = 0; // Runs every frame to update rainbow hue, a potential future optimization is to only run this a once or twice a second and increase the speed of the rainbow hue rotation. void CosmeticsUpdateTick() { int index = 0; - float rainbowSpeed = CVarGetFloat("gCosmetics.RainbowSpeed", 0.6f); + float rainbowSpeed = CVarGetFloat(CVAR_COSMETIC("RainbowSpeed"), 0.6f); for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.supportsRainbow && CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { float frequency = 2 * M_PI / (360 * rainbowSpeed); @@ -422,7 +441,7 @@ void CosmeticsUpdateTick() { // If we don't want the rainbow color on items to be synced, offset the index for each item in the loop. // Technically this would work if you replaced "60" with 1 but the hue would be so close it's // indistinguishable, 60 gives us a big enough gap to notice the difference. - if (!CVarGetInteger("gCosmetics.RainbowSync", 0)) { + if (!CVarGetInteger(CVAR_COSMETIC("RainbowSync"), 0)) { index+= (60 * rainbowSpeed); } } @@ -441,7 +460,7 @@ void CosmeticsUpdateTick() { 5. GFX Command: The GFX command you want to insert */ void ApplyOrResetCustomGfxPatches(bool manualChange) { - static CosmeticOption& linkGoronTunic = cosmeticOptions.at("Link_GoronTunic"); + static CosmeticOption& linkGoronTunic = cosmeticOptions.at("Link.GoronTunic"); if (manualChange || CVarGetInteger(linkGoronTunic.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {linkGoronTunic.defaultColor.x, linkGoronTunic.defaultColor.y, linkGoronTunic.defaultColor.z, linkGoronTunic.defaultColor.w}; Color_RGBA8 color = CVarGetColor(linkGoronTunic.cvar, defaultColor); @@ -451,7 +470,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiGoronCollarColorDL, "Link_GoronTunic4", linkGoronTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } - static CosmeticOption& linkZoraTunic = cosmeticOptions.at("Link_ZoraTunic"); + static CosmeticOption& linkZoraTunic = cosmeticOptions.at("Link.ZoraTunic"); if (manualChange || CVarGetInteger(linkZoraTunic.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {linkZoraTunic.defaultColor.x, linkZoraTunic.defaultColor.y, linkZoraTunic.defaultColor.z, linkZoraTunic.defaultColor.w}; Color_RGBA8 color = CVarGetColor(linkZoraTunic.cvar, defaultColor); @@ -461,7 +480,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiZoraCollarColorDL, "Link_ZoraTunic4", linkZoraTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } - static CosmeticOption& linkHair = cosmeticOptions.at("Link_Hair"); + static CosmeticOption& linkHair = cosmeticOptions.at("Link.Hair"); if (manualChange || CVarGetInteger(linkHair.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {linkHair.defaultColor.x, linkHair.defaultColor.y, linkHair.defaultColor.z, linkHair.defaultColor.w}; Color_RGBA8 color = CVarGetColor(linkHair.cvar, defaultColor); @@ -484,7 +503,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } } - static CosmeticOption& linkLinen = cosmeticOptions.at("Link_Linen"); + static CosmeticOption& linkLinen = cosmeticOptions.at("Link.Linen"); if (manualChange || CVarGetInteger(linkLinen.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {linkLinen.defaultColor.x, linkLinen.defaultColor.y, linkLinen.defaultColor.z, linkLinen.defaultColor.w}; Color_RGBA8 color = CVarGetColor(linkLinen.cvar, defaultColor); @@ -526,7 +545,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } } - static CosmeticOption& linkBoots = cosmeticOptions.at("Link_Boots"); + static CosmeticOption& linkBoots = cosmeticOptions.at("Link.Boots"); if (manualChange || CVarGetInteger(linkBoots.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {linkBoots.defaultColor.x, linkBoots.defaultColor.y, linkBoots.defaultColor.z, linkBoots.defaultColor.w}; Color_RGBA8 color = CVarGetColor(linkBoots.cvar, defaultColor); @@ -563,7 +582,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } } - static CosmeticOption& mirrorShieldBody = cosmeticOptions.at("MirrorShield_Body"); + static CosmeticOption& mirrorShieldBody = cosmeticOptions.at("MirrorShield.Body"); if (manualChange || CVarGetInteger(mirrorShieldBody.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {mirrorShieldBody.defaultColor.x, mirrorShieldBody.defaultColor.y, mirrorShieldBody.defaultColor.z, mirrorShieldBody.defaultColor.w}; Color_RGBA8 color = CVarGetColor(mirrorShieldBody.cvar, defaultColor); @@ -576,7 +595,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Body7", mirrorShieldBody.changedCvar, 28, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Body8", mirrorShieldBody.changedCvar, 95, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& mirrorShieldMirror = cosmeticOptions.at("MirrorShield_Mirror"); + static CosmeticOption& mirrorShieldMirror = cosmeticOptions.at("MirrorShield.Mirror"); if (manualChange || CVarGetInteger(mirrorShieldMirror.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {mirrorShieldMirror.defaultColor.x, mirrorShieldMirror.defaultColor.y, mirrorShieldMirror.defaultColor.z, mirrorShieldMirror.defaultColor.w}; Color_RGBA8 color = CVarGetColor(mirrorShieldMirror.cvar, defaultColor); @@ -589,7 +608,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Mirror7", mirrorShieldMirror.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Mirror8", mirrorShieldMirror.changedCvar, 111, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& mirrorShieldEmblem = cosmeticOptions.at("MirrorShield_Emblem"); + static CosmeticOption& mirrorShieldEmblem = cosmeticOptions.at("MirrorShield.Emblem"); if (manualChange || CVarGetInteger(mirrorShieldEmblem.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {mirrorShieldEmblem.defaultColor.x, mirrorShieldEmblem.defaultColor.y, mirrorShieldEmblem.defaultColor.z, mirrorShieldEmblem.defaultColor.w}; Color_RGBA8 color = CVarGetColor(mirrorShieldEmblem.cvar, defaultColor); @@ -603,7 +622,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Emblem8", mirrorShieldEmblem.changedCvar, 133, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& swordsKokiriBlade = cosmeticOptions.at("Swords_KokiriBlade"); + static CosmeticOption& swordsKokiriBlade = cosmeticOptions.at("Swords.KokiriBlade"); if (manualChange || CVarGetInteger(swordsKokiriBlade.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {swordsKokiriBlade.defaultColor.x, swordsKokiriBlade.defaultColor.y, swordsKokiriBlade.defaultColor.z, swordsKokiriBlade.defaultColor.w}; Color_RGBA8 color = CVarGetColor(swordsKokiriBlade.cvar, defaultColor); @@ -612,7 +631,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade3", swordsKokiriBlade.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade4", swordsKokiriBlade.changedCvar, 6, gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); } - // static CosmeticOption& swordsKokiriHilt = cosmeticOptions.at("Swords_KokiriHilt"); + // static CosmeticOption& swordsKokiriHilt = cosmeticOptions.at("Swords.KokiriHilt"); // if (manualChange || CVarGetInteger(swordsKokiriHilt.rainbowCvar, 0)) { // static Color_RGBA8 defaultColor = {swordsKokiriHilt.defaultColor.x, swordsKokiriHilt.defaultColor.y, swordsKokiriHilt.defaultColor.z, swordsKokiriHilt.defaultColor.w}; // Color_RGBA8 color = CVarGetColor(swordsKokiriHilt.cvar, defaultColor); @@ -653,7 +672,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt33", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); // } // } - static CosmeticOption& swordsMasterBlade = cosmeticOptions.at("Swords_MasterBlade"); + static CosmeticOption& swordsMasterBlade = cosmeticOptions.at("Swords.MasterBlade"); if (manualChange || CVarGetInteger(swordsMasterBlade.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {swordsMasterBlade.defaultColor.x, swordsMasterBlade.defaultColor.y, swordsMasterBlade.defaultColor.z, swordsMasterBlade.defaultColor.w}; Color_RGBA8 color = CVarGetColor(swordsMasterBlade.cvar, defaultColor); @@ -664,7 +683,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade5", swordsMasterBlade.changedCvar, 13, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade6", swordsMasterBlade.changedCvar, 14, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } - // static CosmeticOption& swordsMasterHilt = cosmeticOptions.at("Swords_MasterHilt"); + // static CosmeticOption& swordsMasterHilt = cosmeticOptions.at("Swords.MasterHilt"); // if (manualChange || CVarGetInteger(swordsMasterHilt.rainbowCvar, 0)) { // static Color_RGBA8 defaultColor = {swordsMasterHilt.defaultColor.x, swordsMasterHilt.defaultColor.y, swordsMasterHilt.defaultColor.z, swordsMasterHilt.defaultColor.w}; // Color_RGBA8 color = CVarGetColor(swordsMasterHilt.cvar, defaultColor); @@ -711,7 +730,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { // PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt39", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); // } // } - static CosmeticOption& swordsBiggoronBlade = cosmeticOptions.at("Swords_BiggoronBlade"); + static CosmeticOption& swordsBiggoronBlade = cosmeticOptions.at("Swords.BiggoronBlade"); if (manualChange || CVarGetInteger(swordsBiggoronBlade.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {swordsBiggoronBlade.defaultColor.x, swordsBiggoronBlade.defaultColor.y, swordsBiggoronBlade.defaultColor.z, swordsBiggoronBlade.defaultColor.w}; Color_RGBA8 color = CVarGetColor(swordsBiggoronBlade.cvar, defaultColor); @@ -720,7 +739,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade3", swordsBiggoronBlade.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade4", swordsBiggoronBlade.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } - // static CosmeticOption& swordsBiggoronHilt = cosmeticOptions.at("Swords_BiggoronHilt"); + // static CosmeticOption& swordsBiggoronHilt = cosmeticOptions.at("Swords.BiggoronHilt"); // if (manualChange || CVarGetInteger(swordsBiggoronHilt.rainbowCvar, 0)) { // static Color_RGBA8 defaultColor = {swordsBiggoronHilt.defaultColor.x, swordsBiggoronHilt.defaultColor.y, swordsBiggoronHilt.defaultColor.z, swordsBiggoronHilt.defaultColor.w}; // Color_RGBA8 color = CVarGetColor(swordsBiggoronHilt.cvar, defaultColor); @@ -740,7 +759,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { // } // } - static CosmeticOption& glovesGoronBracelet = cosmeticOptions.at("Gloves_GoronBracelet"); + static CosmeticOption& glovesGoronBracelet = cosmeticOptions.at("Gloves.GoronBracelet"); if (manualChange || CVarGetInteger(glovesGoronBracelet.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {glovesGoronBracelet.defaultColor.x, glovesGoronBracelet.defaultColor.y, glovesGoronBracelet.defaultColor.z, glovesGoronBracelet.defaultColor.w}; Color_RGBA8 color = CVarGetColor(glovesGoronBracelet.cvar, defaultColor); @@ -753,21 +772,21 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet5", glovesGoronBracelet.changedCvar, 39, gsSPGrayscale(false)); } } - static CosmeticOption& glovesSilverGauntlets = cosmeticOptions.at("Gloves_SilverGauntlets"); + static CosmeticOption& glovesSilverGauntlets = cosmeticOptions.at("Gloves.SilverGauntlets"); if (manualChange || CVarGetInteger(glovesSilverGauntlets.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {glovesSilverGauntlets.defaultColor.x, glovesSilverGauntlets.defaultColor.y, glovesSilverGauntlets.defaultColor.z, glovesSilverGauntlets.defaultColor.w}; Color_RGBA8 color = CVarGetColor(glovesSilverGauntlets.cvar, defaultColor); PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets1", glovesSilverGauntlets.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets2", glovesSilverGauntlets.changedCvar, 4, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } - static CosmeticOption& glovesGoldenGauntlets = cosmeticOptions.at("Gloves_GoldenGauntlets"); + static CosmeticOption& glovesGoldenGauntlets = cosmeticOptions.at("Gloves.GoldenGauntlets"); if (manualChange || CVarGetInteger(glovesGoldenGauntlets.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {glovesGoldenGauntlets.defaultColor.x, glovesGoldenGauntlets.defaultColor.y, glovesGoldenGauntlets.defaultColor.z, glovesGoldenGauntlets.defaultColor.w}; Color_RGBA8 color = CVarGetColor(glovesGoldenGauntlets.cvar, defaultColor); PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets1", glovesGoldenGauntlets.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets2", glovesGoldenGauntlets.changedCvar, 4, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } - static CosmeticOption& glovesGauntletsGem = cosmeticOptions.at("Gloves_GauntletsGem"); + static CosmeticOption& glovesGauntletsGem = cosmeticOptions.at("Gloves.GauntletsGem"); if (manualChange || CVarGetInteger(glovesGauntletsGem.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {glovesGauntletsGem.defaultColor.x, glovesGauntletsGem.defaultColor.y, glovesGauntletsGem.defaultColor.z, glovesGauntletsGem.defaultColor.w}; Color_RGBA8 color = CVarGetColor(glovesGauntletsGem.cvar, defaultColor); @@ -779,7 +798,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultRightGauntletPlate3DL, "Gloves_GauntletsGem6", glovesGauntletsGem.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentBoomerangBody = cosmeticOptions.at("Equipment_BoomerangBody"); + static CosmeticOption& equipmentBoomerangBody = cosmeticOptions.at("Equipment.BoomerangBody"); if (manualChange || CVarGetInteger(equipmentBoomerangBody.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentBoomerangBody.defaultColor.x, equipmentBoomerangBody.defaultColor.y, equipmentBoomerangBody.defaultColor.z, equipmentBoomerangBody.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentBoomerangBody.cvar, defaultColor); @@ -789,7 +808,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangBody4", equipmentBoomerangBody.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gBoomerangDL, "Equipment_BoomerangBody5", equipmentBoomerangBody.changedCvar, 39, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentBoomerangGem = cosmeticOptions.at("Equipment_BoomerangGem"); + static CosmeticOption& equipmentBoomerangGem = cosmeticOptions.at("Equipment.BoomerangGem"); if (manualChange || CVarGetInteger(equipmentBoomerangGem.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentBoomerangGem.defaultColor.x, equipmentBoomerangGem.defaultColor.y, equipmentBoomerangGem.defaultColor.z, equipmentBoomerangGem.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentBoomerangGem.cvar, defaultColor); @@ -801,7 +820,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { // PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangGem5", equipmentBoomerangGem.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - // static CosmeticOption& equipmentSlingshotBody = cosmeticOptions.at("Equipment_SlingshotBody"); + // static CosmeticOption& equipmentSlingshotBody = cosmeticOptions.at("Equipment.SlingshotBody"); // if (manualChange || CVarGetInteger(equipmentSlingshotBody.rainbowCvar, 0)) { // static Color_RGBA8 defaultColor = {equipmentSlingshotBody.defaultColor.x, equipmentSlingshotBody.defaultColor.y, equipmentSlingshotBody.defaultColor.z, equipmentSlingshotBody.defaultColor.w}; // Color_RGBA8 color = CVarGetColor(equipmentSlingshotBody.cvar, defaultColor); @@ -825,7 +844,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { // PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody16",equipmentSlingshotBody.changedCvar, 138, gsSPEndDisplayList()); // } // } - static CosmeticOption& equipmentSlingshotString = cosmeticOptions.at("Equipment_SlingshotString"); + static CosmeticOption& equipmentSlingshotString = cosmeticOptions.at("Equipment.SlingshotString"); if (manualChange || CVarGetInteger(equipmentSlingshotString.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentSlingshotString.defaultColor.x, equipmentSlingshotString.defaultColor.y, equipmentSlingshotString.defaultColor.z, equipmentSlingshotString.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentSlingshotString.cvar, defaultColor); @@ -834,7 +853,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkChildSlinghotStringDL, "Equipment_SlingshotString3",equipmentSlingshotString.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentBowTips = cosmeticOptions.at("Equipment_BowTips"); + static CosmeticOption& equipmentBowTips = cosmeticOptions.at("Equipment.BowTips"); if (manualChange || CVarGetInteger(equipmentBowTips.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentBowTips.defaultColor.x, equipmentBowTips.defaultColor.y, equipmentBowTips.defaultColor.z, equipmentBowTips.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentBowTips.cvar, defaultColor); @@ -844,7 +863,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowTips4", equipmentBowTips.changedCvar, 26, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowTips5", equipmentBowTips.changedCvar, 25, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentBowString = cosmeticOptions.at("Equipment_BowString"); + static CosmeticOption& equipmentBowString = cosmeticOptions.at("Equipment.BowString"); if (manualChange || CVarGetInteger(equipmentBowString.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentBowString.defaultColor.x, equipmentBowString.defaultColor.y, equipmentBowString.defaultColor.z, equipmentBowString.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentBowString.cvar, defaultColor); @@ -852,7 +871,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiBowDL, "Equipment_BowString2", equipmentBowString.changedCvar, 106, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultBowStringDL, "Equipment_BowString3", equipmentBowString.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentBowBody = cosmeticOptions.at("Equipment_BowBody"); + static CosmeticOption& equipmentBowBody = cosmeticOptions.at("Equipment.BowBody"); if (manualChange || CVarGetInteger(equipmentBowBody.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentBowBody.defaultColor.x, equipmentBowBody.defaultColor.y, equipmentBowBody.defaultColor.z, equipmentBowBody.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentBowBody.cvar, defaultColor); @@ -862,7 +881,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowBody4", equipmentBowBody.changedCvar, 33, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowBody5", equipmentBowBody.changedCvar, 31, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentBowHandle = cosmeticOptions.at("Equipment_BowHandle"); + static CosmeticOption& equipmentBowHandle = cosmeticOptions.at("Equipment.BowHandle"); if (manualChange || CVarGetInteger(equipmentBowHandle.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentBowHandle.defaultColor.x, equipmentBowHandle.defaultColor.y, equipmentBowHandle.defaultColor.z, equipmentBowHandle.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentBowHandle.cvar, defaultColor); @@ -873,7 +892,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowHandle5", equipmentBowHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentHammerHead = cosmeticOptions.at("Equipment_HammerHead"); + static CosmeticOption& equipmentHammerHead = cosmeticOptions.at("Equipment.HammerHead"); if (manualChange || CVarGetInteger(equipmentHammerHead.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentHammerHead.defaultColor.x, equipmentHammerHead.defaultColor.y, equipmentHammerHead.defaultColor.z, equipmentHammerHead.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentHammerHead.cvar, defaultColor); @@ -884,7 +903,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultLeftHandHoldingHammerNearDL, "Equipment_HammerHead5", equipmentHammerHead.changedCvar, 38, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultLeftHandHoldingHammerFarDL, "Equipment_HammerHead6", equipmentHammerHead.changedCvar, 38, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentHammerHandle = cosmeticOptions.at("Equipment_HammerHandle"); + static CosmeticOption& equipmentHammerHandle = cosmeticOptions.at("Equipment.HammerHandle"); if (manualChange || CVarGetInteger(equipmentHammerHandle.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentHammerHandle.defaultColor.x, equipmentHammerHandle.defaultColor.y, equipmentHammerHandle.defaultColor.z, equipmentHammerHandle.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentHammerHandle.cvar, defaultColor); @@ -894,7 +913,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultLeftHandHoldingHammerFarDL, "Equipment_HammerHandle6", equipmentHammerHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentChuFace = cosmeticOptions.at("Equipment_ChuFace"); + static CosmeticOption& equipmentChuFace = cosmeticOptions.at("Equipment.ChuFace"); if (manualChange || CVarGetInteger(equipmentChuFace.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentChuFace.defaultColor.x, equipmentChuFace.defaultColor.y, equipmentChuFace.defaultColor.z, equipmentChuFace.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentChuFace.cvar, defaultColor); @@ -907,7 +926,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gBombchuDL, "Equipment_ChuFace5", equipmentChuFace.changedCvar, 27, gsSPGrayscale(false)); } } - static CosmeticOption& equipmentChuBody = cosmeticOptions.at("Equipment_ChuBody"); + static CosmeticOption& equipmentChuBody = cosmeticOptions.at("Equipment.ChuBody"); if (manualChange || CVarGetInteger(equipmentChuBody.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentChuBody.defaultColor.x, equipmentChuBody.defaultColor.y, equipmentChuBody.defaultColor.z, equipmentChuBody.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentChuBody.cvar, defaultColor); @@ -918,7 +937,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gBombchuDL, "Equipment_ChuBody5", equipmentChuBody.changedCvar, 46, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& equipmentBunnyHood = cosmeticOptions.at("Equipment_BunnyHood"); + static CosmeticOption& equipmentBunnyHood = cosmeticOptions.at("Equipment.BunnyHood"); if (manualChange || CVarGetInteger(equipmentBunnyHood.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {equipmentBunnyHood.defaultColor.x, equipmentBunnyHood.defaultColor.y, equipmentBunnyHood.defaultColor.z, equipmentBunnyHood.defaultColor.w}; Color_RGBA8 color = CVarGetColor(equipmentBunnyHood.cvar, defaultColor); @@ -938,7 +957,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } } - static CosmeticOption& consumableGreenRupee = cosmeticOptions.at("Consumable_GreenRupee"); + static CosmeticOption& consumableGreenRupee = cosmeticOptions.at("Consumable.GreenRupee"); if (manualChange || CVarGetInteger(consumableGreenRupee.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {consumableGreenRupee.defaultColor.x, consumableGreenRupee.defaultColor.y, consumableGreenRupee.defaultColor.z, consumableGreenRupee.defaultColor.w}; Color_RGBA8 color = CVarGetColor(consumableGreenRupee.cvar, defaultColor); @@ -958,7 +977,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { ResourceMgr_UnpatchGfxByName(gRainbowBridgeDL, "RainbowBridge_EndGrayscaleAndEndDlist"); } } - static CosmeticOption& consumableBlueRupee = cosmeticOptions.at("Consumable_BlueRupee"); + static CosmeticOption& consumableBlueRupee = cosmeticOptions.at("Consumable.BlueRupee"); if (manualChange || CVarGetInteger(consumableBlueRupee.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {consumableBlueRupee.defaultColor.x, consumableBlueRupee.defaultColor.y, consumableBlueRupee.defaultColor.z, consumableBlueRupee.defaultColor.w}; Color_RGBA8 color = CVarGetColor(consumableBlueRupee.cvar, defaultColor); @@ -967,7 +986,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiBlueRupeeOuterColorDL, "Consumable_BlueRupee3", consumableBlueRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); PATCH_GFX(gGiBlueRupeeOuterColorDL, "Consumable_BlueRupee4", consumableBlueRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } - static CosmeticOption& consumableRedRupee = cosmeticOptions.at("Consumable_RedRupee"); + static CosmeticOption& consumableRedRupee = cosmeticOptions.at("Consumable.RedRupee"); if (manualChange || CVarGetInteger(consumableRedRupee.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {consumableRedRupee.defaultColor.x, consumableRedRupee.defaultColor.y, consumableRedRupee.defaultColor.z, consumableRedRupee.defaultColor.w}; Color_RGBA8 color = CVarGetColor(consumableRedRupee.cvar, defaultColor); @@ -976,7 +995,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiRedRupeeOuterColorDL, "Consumable_RedRupee3", consumableRedRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); PATCH_GFX(gGiRedRupeeOuterColorDL, "Consumable_RedRupee4", consumableRedRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } - static CosmeticOption& consumablePurpleRupee = cosmeticOptions.at("Consumable_PurpleRupee"); + static CosmeticOption& consumablePurpleRupee = cosmeticOptions.at("Consumable.PurpleRupee"); if (manualChange || CVarGetInteger(consumablePurpleRupee.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {consumablePurpleRupee.defaultColor.x, consumablePurpleRupee.defaultColor.y, consumablePurpleRupee.defaultColor.z, consumablePurpleRupee.defaultColor.w}; Color_RGBA8 color = CVarGetColor(consumablePurpleRupee.cvar, defaultColor); @@ -985,7 +1004,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiPurpleRupeeOuterColorDL, "Consumable_PurpleRupee3", consumablePurpleRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); PATCH_GFX(gGiPurpleRupeeOuterColorDL, "Consumable_PurpleRupee4", consumablePurpleRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } - static CosmeticOption& consumableGoldRupee = cosmeticOptions.at("Consumable_GoldRupee"); + static CosmeticOption& consumableGoldRupee = cosmeticOptions.at("Consumable.GoldRupee"); if (manualChange || CVarGetInteger(consumableGoldRupee.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {consumableGoldRupee.defaultColor.x, consumableGoldRupee.defaultColor.y, consumableGoldRupee.defaultColor.z, consumableGoldRupee.defaultColor.w}; Color_RGBA8 color = CVarGetColor(consumableGoldRupee.cvar, defaultColor); @@ -995,7 +1014,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiGoldRupeeOuterColorDL, "Consumable_GoldRupee4", consumableGoldRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } - static CosmeticOption& consumableHearts = cosmeticOptions.at("Consumable_Hearts"); + static CosmeticOption& consumableHearts = cosmeticOptions.at("Consumable.Hearts"); if (manualChange || CVarGetInteger(consumableHearts.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {consumableHearts.defaultColor.x, consumableHearts.defaultColor.y, consumableHearts.defaultColor.z, consumableHearts.defaultColor.w}; Color_RGBA8 color = CVarGetColor(consumableHearts.cvar, defaultColor); @@ -1010,7 +1029,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiRedPotColorDL, "Consumable_Hearts9", consumableHearts.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiRedPotColorDL, "Consumable_Hearts10", consumableHearts.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } - static CosmeticOption& consumableMagic = cosmeticOptions.at("Consumable_Magic"); + static CosmeticOption& consumableMagic = cosmeticOptions.at("Consumable.Magic"); if (manualChange || CVarGetInteger(consumableMagic.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {consumableMagic.defaultColor.x, consumableMagic.defaultColor.y, consumableMagic.defaultColor.z, consumableMagic.defaultColor.w}; Color_RGBA8 color = CVarGetColor(consumableMagic.cvar, defaultColor); @@ -1022,19 +1041,23 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGiGreenPotColorDL, "Consumable_Magic6", consumableMagic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } - static CosmeticOption& npcGoldenSkulltula = cosmeticOptions.at("NPC_GoldenSkulltula"); + static CosmeticOption& npcGoldenSkulltula = cosmeticOptions.at("NPC.GoldenSkulltula"); if (manualChange || CVarGetInteger(npcGoldenSkulltula.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {npcGoldenSkulltula.defaultColor.x, npcGoldenSkulltula.defaultColor.y, npcGoldenSkulltula.defaultColor.z, npcGoldenSkulltula.defaultColor.w}; Color_RGBA8 color = CVarGetColor(npcGoldenSkulltula.cvar, defaultColor); - PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula1", npcGoldenSkulltula.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula2", npcGoldenSkulltula.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula3", npcGoldenSkulltula.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula4", npcGoldenSkulltula.changedCvar, 33, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula5", npcGoldenSkulltula.changedCvar, 118, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula6", npcGoldenSkulltula.changedCvar, 119, gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); + PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula1", npcGoldenSkulltula.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula2", npcGoldenSkulltula.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gSkulltulaTokenFlameDL, "NPC_GoldenSkulltula3", npcGoldenSkulltula.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gSkulltulaTokenFlameDL, "NPC_GoldenSkulltula4", npcGoldenSkulltula.changedCvar, 33, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula5", npcGoldenSkulltula.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula6", npcGoldenSkulltula.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula7", npcGoldenSkulltula.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula8", npcGoldenSkulltula.changedCvar, 33, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula9", npcGoldenSkulltula.changedCvar, 118, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula10", npcGoldenSkulltula.changedCvar, 119, gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); } - static CosmeticOption& npcGerudo = cosmeticOptions.at("NPC_Gerudo"); + static CosmeticOption& npcGerudo = cosmeticOptions.at("NPC.Gerudo"); if (manualChange || CVarGetInteger(npcGerudo.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {npcGerudo.defaultColor.x, npcGerudo.defaultColor.y, npcGerudo.defaultColor.z, npcGerudo.defaultColor.w}; Color_RGBA8 color = CVarGetColor(npcGerudo.cvar, defaultColor); @@ -1048,35 +1071,35 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGerudoPurpleRightHandDL, "NPC_Gerudo8", npcGerudo.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& npcMetalTrap = cosmeticOptions.at("NPC_MetalTrap"); + static CosmeticOption& npcMetalTrap = cosmeticOptions.at("NPC.MetalTrap"); if (manualChange || CVarGetInteger(npcMetalTrap.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {npcMetalTrap.defaultColor.x, npcMetalTrap.defaultColor.y, npcMetalTrap.defaultColor.z, npcMetalTrap.defaultColor.w}; Color_RGBA8 color = CVarGetColor(npcMetalTrap.cvar, defaultColor); PATCH_GFX(gSlidingBladeTrapDL, "NPC_MetalTrap1", npcMetalTrap.changedCvar, 59, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } - static CosmeticOption& n64LogoRed = cosmeticOptions.at("Title_N64LogoRed"); + static CosmeticOption& n64LogoRed = cosmeticOptions.at("Title.N64LogoRed"); if (manualChange || CVarGetInteger(n64LogoRed.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {n64LogoRed.defaultColor.x, n64LogoRed.defaultColor.y, n64LogoRed.defaultColor.z, n64LogoRed.defaultColor.w}; Color_RGBA8 color = CVarGetColor(n64LogoRed.cvar, defaultColor); PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed1", n64LogoRed.changedCvar, 17, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed2", n64LogoRed.changedCvar, 18, gsDPSetEnvColor(color.r, color.g, color.b, 128)); } - static CosmeticOption& n64LogoBlue = cosmeticOptions.at("Title_N64LogoBlue"); + static CosmeticOption& n64LogoBlue = cosmeticOptions.at("Title.N64LogoBlue"); if (manualChange || CVarGetInteger(n64LogoBlue.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {n64LogoBlue.defaultColor.x, n64LogoBlue.defaultColor.y, n64LogoBlue.defaultColor.z, n64LogoBlue.defaultColor.w}; Color_RGBA8 color = CVarGetColor(n64LogoBlue.cvar, defaultColor); PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue1", n64LogoBlue.changedCvar, 29, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue2", n64LogoBlue.changedCvar, 30, gsDPSetEnvColor(color.r, color.g, color.b, 128)); } - static CosmeticOption& n64LogoGreen = cosmeticOptions.at("Title_N64LogoGreen"); + static CosmeticOption& n64LogoGreen = cosmeticOptions.at("Title.N64LogoGreen"); if (manualChange || CVarGetInteger(n64LogoGreen.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {n64LogoGreen.defaultColor.x, n64LogoGreen.defaultColor.y, n64LogoGreen.defaultColor.z, n64LogoGreen.defaultColor.w}; Color_RGBA8 color = CVarGetColor(n64LogoGreen.cvar, defaultColor); PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen1", n64LogoGreen.changedCvar, 56, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen2", n64LogoGreen.changedCvar, 57, gsDPSetEnvColor(color.r, color.g, color.b, 128)); } - static CosmeticOption& n64LogoYellow = cosmeticOptions.at("Title_N64LogoYellow"); + static CosmeticOption& n64LogoYellow = cosmeticOptions.at("Title.N64LogoYellow"); if (manualChange || CVarGetInteger(n64LogoYellow.rainbowCvar, 0)) { static Color_RGBA8 defaultColor = {n64LogoYellow.defaultColor.x, n64LogoYellow.defaultColor.y, n64LogoYellow.defaultColor.z, n64LogoYellow.defaultColor.w}; Color_RGBA8 color = CVarGetColor(n64LogoYellow.cvar, defaultColor); @@ -1085,9 +1108,9 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } if (gPlayState != nullptr) { - if (CVarGetInteger("gCosmetics.Link_BodyScale.Changed", 0)) { + if (CVarGetInteger(CVAR_COSMETIC("Link.BodyScale.Changed"), 0)) { static Player* player = GET_PLAYER(gPlayState); - float scale = CVarGetFloat("gCosmetics.Link_BodyScale.Value", 0.01f); + float scale = CVarGetFloat(CVAR_COSMETIC("Link.BodyScale.Value"), 0.01f); player->actor.scale.x = scale; player->actor.scale.y = scale; player->actor.scale.z = scale; @@ -1106,13 +1129,13 @@ void Table_InitHeader(bool has_header = true) { ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x-60); } void DrawUseMarginsSlider(const std::string ElementName, const std::string CvarName){ - std::string CvarLabel = CvarName + "UseMargins"; + std::string CvarLabel = CvarName + ".UseMargins"; std::string Label = ElementName + " use margins"; UIWidgets::EnhancementCheckbox(Label.c_str(), CvarLabel.c_str()); UIWidgets::Tooltip("Using this allow you move the element with General margins sliders"); } void DrawPositionsRadioBoxes(const std::string CvarName, bool NoAnchorEnabled = true){ - std::string CvarLabel = CvarName + "PosType"; + std::string CvarLabel = CvarName + ".PosType"; UIWidgets::EnhancementRadioButton("Original position", CvarLabel.c_str(), 0); UIWidgets::Tooltip("This will use original intended elements position"); UIWidgets::EnhancementRadioButton("Anchor to the left", CvarLabel.c_str(), 1); @@ -1127,8 +1150,8 @@ void DrawPositionsRadioBoxes(const std::string CvarName, bool NoAnchorEnabled = UIWidgets::Tooltip("This will make your elements hidden"); } void DrawPositionSlider(const std::string CvarName, int MinY, int MaxY, int MinX, int MaxX){ - std::string PosXCvar = CvarName+"PosX"; - std::string PosYCvar = CvarName+"PosY"; + std::string PosXCvar = CvarName + ".PosX"; + std::string PosYCvar = CvarName + ".PosY"; std::string InvisibleLabelX = "##"+PosXCvar; std::string InvisibleLabelY = "##"+PosYCvar; UIWidgets::EnhancementSliderInt("Up <-> Down : %d", InvisibleLabelY.c_str(), PosYCvar.c_str(), MinY, MaxY, "", 0); @@ -1138,18 +1161,55 @@ void DrawPositionSlider(const std::string CvarName, int MinY, int MaxY, int MinX } void DrawScaleSlider(const std::string CvarName,float DefaultValue){ std::string InvisibleLabel = "##"+CvarName; - std::string CvarLabel = CvarName+"Scale"; + std::string CvarLabel = CvarName + ".Scale"; //Disabled for now. feature not done and several fixes needed to be merged. //UIWidgets::EnhancementSliderFloat("Scale : %dx", InvisibleLabel.c_str(), CvarLabel.c_str(), 0.1f, 3.0f,"",DefaultValue,true); } +void Draw_Table_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, const char* Slider_Title, const char* Slider_ID, int MinY, int MaxY, int MinX, int MaxX, float Default_Value) { + if (ImGui::CollapsingHeader(Header_Title)) { + if (ImGui::BeginTable(Table_ID, 1, FlagsTable)) { + ImGui::TableSetupColumn(Column_Title, FlagsCell, TablesCellsWidth); + Table_InitHeader(false); + DrawUseMarginsSlider(Slider_Title, Slider_ID); + DrawPositionsRadioBoxes(Slider_ID); + DrawPositionSlider(Slider_ID, MinY, MaxY, MinX, MaxX); + DrawScaleSlider(Slider_ID, Default_Value); + ImGui::NewLine(); + ImGui::EndTable(); + } + } +} +void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, const char* Slider_Title, const char* Slider_ID, const char* Int_Type, float Slider_Scale_Value) { + if (ImGui::CollapsingHeader(Header_Title)) { + if (ImGui::BeginTable(Table_ID, 1, FlagsTable)) { + ImGui::TableSetupColumn(Column_Title, FlagsCell, TablesCellsWidth); + Table_InitHeader(false); + DrawUseMarginsSlider(Slider_Title, Slider_ID); + DrawPositionsRadioBoxes(Slider_ID); + s16 Min_X_CU = 0; + s16 Max_X_CU = ImGui::GetWindowViewport()->Size.x/2; + if(CVarGetInteger(Int_Type,0) == 2){ + Max_X_CU = 294; + } else if(CVarGetInteger(Int_Type,0) == 3){ + Max_X_CU = ImGui::GetWindowViewport()->Size.x/2; + } else if(CVarGetInteger(Int_Type,0) == 4){ + Min_X_CU = (ImGui::GetWindowViewport()->Size.x/2)*-1; + } + DrawPositionSlider(Slider_ID, 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_CU, Max_X_CU); + DrawScaleSlider(Slider_ID, Slider_Scale_Value); + ImGui::NewLine(); + ImGui::EndTable(); + } + } +} void Draw_Placements(){ if (ImGui::BeginTable("tableMargins", 1, FlagsTable)) { ImGui::TableSetupColumn("General margins settings", FlagsCell, TablesCellsWidth); Table_InitHeader(); - UIWidgets::EnhancementSliderInt("Top : %dx", "##UIMARGINT", "gHUDMargin_T", (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0); - UIWidgets::EnhancementSliderInt("Left: %dx", "##UIMARGINL", "gHUDMargin_L", -25, ImGui::GetWindowViewport()->Size.x, "", 0); - UIWidgets::EnhancementSliderInt("Right: %dx", "##UIMARGINR", "gHUDMargin_R", (ImGui::GetWindowViewport()->Size.x)*-1, 25, "", 0); - UIWidgets::EnhancementSliderInt("Bottom: %dx", "##UIMARGINB", "gHUDMargin_B", (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0); + UIWidgets::EnhancementSliderInt("Top : %dx", "##UIMARGINT", CVAR_COSMETIC("HUD.Margin.T"), (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0); + UIWidgets::EnhancementSliderInt("Left: %dx", "##UIMARGINL", CVAR_COSMETIC("HUD.Margin.L"), -25, ImGui::GetWindowViewport()->Size.x, "", 0); + UIWidgets::EnhancementSliderInt("Right: %dx", "##UIMARGINR", CVAR_COSMETIC("HUD.Margin.R"), (ImGui::GetWindowViewport()->Size.x)*-1, 25, "", 0); + UIWidgets::EnhancementSliderInt("Bottom: %dx", "##UIMARGINB", CVAR_COSMETIC("HUD.Margin.B"), (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0); SetMarginAll("All margins on",true); UIWidgets::Tooltip("Set most of the elements to use margins\nSome elements with default position will not be affected\nElements without Anchor or Hidden will not be turned on"); ImGui::SameLine(); @@ -1165,11 +1225,11 @@ void Draw_Placements(){ if (ImGui::BeginTable("tableHeartsCounts", 1, FlagsTable)) { ImGui::TableSetupColumn("Hearts counts settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); - DrawUseMarginsSlider("Hearts counts", "gHearts"); - DrawPositionsRadioBoxes("gHeartsCount"); - DrawPositionSlider("gHeartsCount",-22,ImGui::GetWindowViewport()->Size.y,-125,ImGui::GetWindowViewport()->Size.x); - DrawScaleSlider("gHeartsCount",0.7f); - UIWidgets::EnhancementSliderInt("Heart line length : %d", "##HeartLineLength", "gHeartsLineLength", 0, 20, "", 10); + DrawUseMarginsSlider("Hearts counts", CVAR_COSMETIC("HUD.Hearts")); + DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.HeartsCount")); + DrawPositionSlider(CVAR_COSMETIC("HUD.HeartsCount"),-22,ImGui::GetWindowViewport()->Size.y,-125,ImGui::GetWindowViewport()->Size.x); + DrawScaleSlider(CVAR_COSMETIC("HUD.HeartsCount"),0.7f); + UIWidgets::EnhancementSliderInt("Heart line length : %d", "##HeartLineLength", CVAR_COSMETIC("HUD.Hearts.LineLength"), 0, 20, "", 10); UIWidgets::Tooltip("This will set the length of a row of hearts. Set to 0 for unlimited length."); ImGui::NewLine(); ImGui::EndTable(); @@ -1179,326 +1239,127 @@ void Draw_Placements(){ if (ImGui::BeginTable("tablemmpos", 1, FlagsTable)) { ImGui::TableSetupColumn("Magic meter settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); - DrawUseMarginsSlider("Magic meter", "gMagicBar"); - DrawPositionsRadioBoxes("gMagicBar"); - UIWidgets::EnhancementRadioButton("Anchor to life bar", "gMagicBarPosType", 5); + DrawUseMarginsSlider("Magic meter", CVAR_COSMETIC("HUD.MagicBar")); + DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.MagicBar")); + UIWidgets::EnhancementRadioButton("Anchor to life bar", CVAR_COSMETIC("HUD.MagicBar.PosType"), 5); UIWidgets::Tooltip("This will make your elements follow the bottom of the life meter"); - DrawPositionSlider("gMagicBar", 0, ImGui::GetWindowViewport()->Size.y/2, -5, ImGui::GetWindowViewport()->Size.x/2); - DrawScaleSlider("gMagicBar",1.0f); + DrawPositionSlider(CVAR_COSMETIC("HUD.MagicBar"), 0, ImGui::GetWindowViewport()->Size.y/2, -5, ImGui::GetWindowViewport()->Size.x/2); + DrawScaleSlider(CVAR_COSMETIC("HUD.MagicBar"),1.0f); ImGui::NewLine(); ImGui::EndTable(); } } - if (CVarGetInteger("gVisualAgony",0) && ImGui::CollapsingHeader("Visual stone of agony position")) { + if (CVarGetInteger(CVAR_ENHANCEMENT("VisualAgony"),0) && ImGui::CollapsingHeader("Visual stone of agony position")) { if (ImGui::BeginTable("tabledvisualstoneofagony", 1, FlagsTable)) { ImGui::TableSetupColumn("Visual stone of agony settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); - DrawUseMarginsSlider("Visual stone of agony", "gVSOA"); - DrawPositionsRadioBoxes("gVSOA"); + DrawUseMarginsSlider("Visual stone of agony", CVAR_COSMETIC("HUD.VisualSoA")); + DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.VisualSoA")); s16 Min_X_VSOA = 0; s16 Max_X_VSOA = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger("gVSOAPosType",0) == 2){ + if(CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"),0) == 2){ Max_X_VSOA = 290; - } else if(CVarGetInteger("gVSOAPosType",0) == 4){ + } else if(CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"),0) == 4){ Min_X_VSOA = (ImGui::GetWindowViewport()->Size.x/2)*-1; } - DrawPositionSlider("gVSOA", 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_VSOA, Max_X_VSOA); - DrawScaleSlider("gVSOA",1.0f); + DrawPositionSlider(CVAR_COSMETIC("HUD.VisualSoA"), 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_VSOA, Max_X_VSOA); + DrawScaleSlider(CVAR_COSMETIC("HUD.VisualSoA"),1.0f); ImGui::NewLine(); ImGui::EndTable(); } } - if (ImGui::CollapsingHeader("B Button position")) { - if (ImGui::BeginTable("tablebbtn", 1, FlagsTable)) { - ImGui::TableSetupColumn("B Button settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("B Button", "gBBtn"); - DrawPositionsRadioBoxes("gBBtn"); - DrawPositionSlider("gBBtn", 0, ImGui::GetWindowViewport()->Size.y/4+50, -1, ImGui::GetWindowViewport()->Size.x-50); - DrawScaleSlider("gBBtn",0.95f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("A Button position")) { - if (ImGui::BeginTable("tableabtn", 1, FlagsTable)) { - ImGui::TableSetupColumn("A Button settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("A Button", "gABtn"); - DrawPositionsRadioBoxes("gABtn"); - DrawPositionSlider("gABtn", -10, ImGui::GetWindowViewport()->Size.y/4+50, -20, ImGui::GetWindowViewport()->Size.x-50); - DrawScaleSlider("gABtn",0.95f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Start Button position")) { - if (ImGui::BeginTable("tablestartbtn", 1, FlagsTable)) { - ImGui::TableSetupColumn("Start Button settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Start Button", "gStartBtn"); - DrawPositionsRadioBoxes("gStartBtn"); - DrawPositionSlider("gStartBtn", 0, ImGui::GetWindowViewport()->Size.y/2, 0, ImGui::GetWindowViewport()->Size.x/2+70); - DrawScaleSlider("gStartBtn",0.75f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("C Button Up position")) { - if (ImGui::BeginTable("tablecubtn", 1, FlagsTable)) { - ImGui::TableSetupColumn("C Button Up settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("C Button Up", "gCBtnU"); - DrawPositionsRadioBoxes("gCBtnU"); - s16 Min_X_CU = 0; - s16 Max_X_CU = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger("gCBtnUPosType",0) == 2){ - Max_X_CU = 294; - } else if(CVarGetInteger("gCBtnUPosType",0) == 3){ - Max_X_CU = ImGui::GetWindowViewport()->Size.x/2; - } else if(CVarGetInteger("gCBtnUPosType",0) == 4){ - Min_X_CU = (ImGui::GetWindowViewport()->Size.x/2)*-1; - } - DrawPositionSlider("gCBtnU", 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_CU, Max_X_CU); - DrawScaleSlider("gCBtnU",0.5f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("C Button Down position")) { - if (ImGui::BeginTable("tablecdbtn", 1, FlagsTable)) { - ImGui::TableSetupColumn("C Button Down settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("C Button Down", "gCBtnD"); - DrawPositionsRadioBoxes("gCBtnD"); - s16 Min_X_CD = 0; - s16 Max_X_CD = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger("gCBtnDPosType",0) == 2){ - Max_X_CD = 294; - } else if(CVarGetInteger("gCBtnDPosType",0) == 3){ - Max_X_CD = ImGui::GetWindowViewport()->Size.x/2; - } else if(CVarGetInteger("gCBtnDPosType",0) == 4){ - Min_X_CD = (ImGui::GetWindowViewport()->Size.x/2)*-1; - } - DrawPositionSlider("gCBtnD", 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_CD, Max_X_CD); - DrawScaleSlider("gCBtnD",0.87f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("C Button Left position")) { - if (ImGui::BeginTable("tableclbtn", 1, FlagsTable)) { - ImGui::TableSetupColumn("C Button Left settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("C Button Left", "gCBtnL"); - DrawPositionsRadioBoxes("gCBtnL"); - s16 Min_X_CL = 0; - s16 Max_X_CL = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger("gCBtnLPosType",0) == 2){ - Max_X_CL = 294; - } else if(CVarGetInteger("gCBtnLPosType",0) == 3){ - Max_X_CL = ImGui::GetWindowViewport()->Size.x/2; - } else if(CVarGetInteger("gCBtnLPosType",0) == 4){ - Min_X_CL = (ImGui::GetWindowViewport()->Size.x/2)*-1; - } - DrawPositionSlider("gCBtnL", 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_CL, Max_X_CL); - DrawScaleSlider("gCBtnL",0.87f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("C Button Right position")) { - if (ImGui::BeginTable("tablecrnbtn", 1, FlagsTable)) { - ImGui::TableSetupColumn("C Button Right settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("C Button Right", "gCBtnR"); - DrawPositionsRadioBoxes("gCBtnR"); - s16 Min_X_CR = 0; - s16 Max_X_CR = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger("gCBtnRPosType",0) == 2){ - Max_X_CR = 294; - } else if(CVarGetInteger("gCBtnRPosType",0) == 3){ - Max_X_CR = ImGui::GetWindowViewport()->Size.x/2; - } else if(CVarGetInteger("gCBtnRPosType",0) == 4){ - Min_X_CR = (ImGui::GetWindowViewport()->Size.x/2)*-1; - } - DrawPositionSlider("gCBtnR", 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_CR, Max_X_CR); - DrawScaleSlider("gCBtnR",0.87f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (CVarGetInteger("gDpadEquips",0) && ImGui::CollapsingHeader("DPad items position")) { + Draw_Table_Dropdown("B Button position", "tablebbtn", "B Button settings", "B Button", CVAR_COSMETIC("HUD.BButton"), 0, ImGui::GetWindowViewport()->Size.y/4+50, -1, ImGui::GetWindowViewport()->Size.x-50, 0.95f); + Draw_Table_Dropdown("A Button position", "tableabtn", "A Button settings", "A Button", CVAR_COSMETIC("HUD.AButton"), -10, ImGui::GetWindowViewport()->Size.y/4+50, -20, ImGui::GetWindowViewport()->Size.x-50, 0.95f); + Draw_Table_Dropdown("Start Button position", "tablestartbtn", "Start Button settings", "Start Button", CVAR_COSMETIC("HUD.StartButton"), 0, ImGui::GetWindowViewport()->Size.y/2, 0, ImGui::GetWindowViewport()->Size.x/2+70, 0.75f); + C_Button_Dropdown("C Button Up position", "tablecubtn", "C Button Up settings", "C Button Up", CVAR_COSMETIC("HUD.CUpButton"), CVAR_COSMETIC("HUD.CUpButton.PosType"), 0.5f); + C_Button_Dropdown("C Button Down position", "tablecdbtn", "C Button Down settings", "C Button Down", CVAR_COSMETIC("HUD.CDownButton"), CVAR_COSMETIC("HUD.CDownButton.PosType"), 0.87f); + C_Button_Dropdown("C Button Left position", "tableclbtn", "C Button Left settings", "C Button Left", CVAR_COSMETIC("HUD.CLeftButton"), CVAR_COSMETIC("HUD.CLeftButton.PosType"), 0.87f); + C_Button_Dropdown("C Button Right position", "tablecrbtn", "C Button Right settings", "C Button Right", CVAR_COSMETIC("HUD.CRightButton"), CVAR_COSMETIC("HUD.CRightButton.PosType"), 0.87f); + if (CVarGetInteger(CVAR_SETTING("DpadEquips"),0) && ImGui::CollapsingHeader("DPad items position")) { if (ImGui::BeginTable("tabledpaditems", 1, FlagsTable)) { ImGui::TableSetupColumn("DPad items settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); - DrawUseMarginsSlider("DPad items", "gDPad"); - DrawPositionsRadioBoxes("gDPad"); + DrawUseMarginsSlider("DPad items", CVAR_COSMETIC("HUD.Dpad")); + DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.Dpad")); s16 Min_X_Dpad = 0; s16 Max_X_Dpad = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger("gDPadPosType",0) == 2){ + if(CVarGetInteger(CVAR_COSMETIC("HUD.Dpad.PosType"),0) == 2){ Max_X_Dpad = 290; - } else if(CVarGetInteger("gDPadPosType",0) == 4){ + } else if(CVarGetInteger(CVAR_COSMETIC("HUD.Dpad.PosType"),0) == 4){ Min_X_Dpad = (ImGui::GetWindowViewport()->Size.x/2)*-1; } - DrawPositionSlider("gDPad", 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_Dpad, Max_X_Dpad); - DrawScaleSlider("gDPad",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Minimaps position")) { - if (ImGui::BeginTable("tableminimapspos", 1, FlagsTable)) { - ImGui::TableSetupColumn("minimaps settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Minimap", "gMinimap"); - DrawPositionsRadioBoxes("gMinimap", false); - DrawPositionSlider("gMinimap", (ImGui::GetWindowViewport()->Size.y/3)*-1, ImGui::GetWindowViewport()->Size.y/3, ImGui::GetWindowViewport()->Size.x*-1, ImGui::GetWindowViewport()->Size.x/2); - DrawScaleSlider("gMinimap",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Small Keys counter position")) { - if (ImGui::BeginTable("tablesmolekeys", 1, FlagsTable)) { - ImGui::TableSetupColumn("Small Keys counter settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Small Keys counter", "gSKC"); - DrawPositionsRadioBoxes("gSKC"); - DrawPositionSlider("gSKC", 0, ImGui::GetWindowViewport()->Size.y/3, -1, ImGui::GetWindowViewport()->Size.x/2); - DrawScaleSlider("gSKC",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Rupee counter position")) { - if (ImGui::BeginTable("tablerupeecount", 1, FlagsTable)) { - ImGui::TableSetupColumn("Rupee counter settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Rupee counter", "gRC"); - DrawPositionsRadioBoxes("gRC"); - DrawPositionSlider("gRC", -2, ImGui::GetWindowViewport()->Size.y/3, -3, ImGui::GetWindowViewport()->Size.x/2); - DrawScaleSlider("gRC",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Carrots position")) { - if (ImGui::BeginTable("tableCarrots", 1, FlagsTable)) { - ImGui::TableSetupColumn("Carrots settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Carrots", "gCarrots"); - DrawPositionsRadioBoxes("gCarrots"); - DrawPositionSlider("gCarrots", 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+25); - DrawScaleSlider("gCarrots",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Timers position")) { - if (ImGui::BeginTable("tabletimers", 1, FlagsTable)) { - ImGui::TableSetupColumn("Timers settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Timers", "gTimers"); - DrawPositionsRadioBoxes("gTimers"); - DrawPositionSlider("gTimers", 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2-50); - DrawScaleSlider("gTimers",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Archery Scores position")) { - if (ImGui::BeginTable("tablearchery", 1, FlagsTable)) { - ImGui::TableSetupColumn("Archery Scores settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Archery scores", "gAS"); - DrawPositionsRadioBoxes("gAS", false); - DrawPositionSlider("gAS", 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2-50); - DrawScaleSlider("gAS",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Title cards (Maps) position")) { - if (ImGui::BeginTable("tabletcmaps", 1, FlagsTable)) { - ImGui::TableSetupColumn("Titlecard maps settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Title cards (overworld)", "gTCM"); - DrawPositionsRadioBoxes("gTCM"); - DrawPositionSlider("gTCM", 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+10); - DrawScaleSlider("gTCM",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("Title cards (Bosses) position")) { - if (ImGui::BeginTable("tabletcbosses", 1, FlagsTable)) { - ImGui::TableSetupColumn("Title cards (Bosses) settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("Title cards (Bosses)", "gTCB"); - DrawPositionsRadioBoxes("gTCB"); - DrawPositionSlider("gTCB", 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+10); - DrawScaleSlider("gTCB",1.0f); - ImGui::NewLine(); - ImGui::EndTable(); - } - } - if (ImGui::CollapsingHeader("In-game Gameplay Timer position")) { - if (ImGui::BeginTable("tablegameplaytimer", 1, FlagsTable)) { - ImGui::TableSetupColumn("In-game Gameplay Timer settings", FlagsCell, TablesCellsWidth); - Table_InitHeader(false); - DrawUseMarginsSlider("In-game Gameplay Timer", "gIGT"); - DrawPositionsRadioBoxes("gIGT"); - DrawPositionSlider("gIGT", 0, ImGui::GetWindowViewport()->Size.y / 2, -50, - ImGui::GetWindowViewport()->Size.x / 2 + 10); - DrawScaleSlider("gIGT", 1.0f); + DrawPositionSlider(CVAR_COSMETIC("HUD.Dpad"), 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_Dpad, Max_X_Dpad); + DrawScaleSlider(CVAR_COSMETIC("HUD.Dpad"),1.0f); ImGui::NewLine(); ImGui::EndTable(); } } + Draw_Table_Dropdown("Minimaps position", "tableminimapspos", "minimaps settings", "Minimap", CVAR_COSMETIC("HUD.Minimap"), (ImGui::GetWindowViewport()->Size.y/3)*-1, ImGui::GetWindowViewport()->Size.y/3, ImGui::GetWindowViewport()->Size.x*-1, ImGui::GetWindowViewport()->Size.x/2, 1.0f); + Draw_Table_Dropdown("Small Keys counter position", "tablesmolekeys", "Small Keys counter settings", "Small Keys counter", CVAR_COSMETIC("HUD.SmallKey"), 0, ImGui::GetWindowViewport()->Size.y/3, -1, ImGui::GetWindowViewport()->Size.x/2, 1.0f); + Draw_Table_Dropdown("Rupee counter position", "tablerupeecount", "Rupee counter settings", "Rupee counter", CVAR_COSMETIC("HUD.Rupees"), -2, ImGui::GetWindowViewport()->Size.y/3, -3, ImGui::GetWindowViewport()->Size.x/2, 1.0f); + Draw_Table_Dropdown("Carrots position", "tableCarrots", "Carrots settings", "Carrots", CVAR_COSMETIC("HUD.Carrots"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+25, 1.0f); + Draw_Table_Dropdown("Timers position", "tabletimers", "Timers settings", "Timers", CVAR_COSMETIC("HUD.Timers"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2-50, 1.0f); + Draw_Table_Dropdown("Archery Scores position", "tablearchery", "Archery Scores settings", "Archery scores", CVAR_COSMETIC("HUD.ArcheryScore"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2-50, 1.0f); + Draw_Table_Dropdown("Title cards (Maps) position", "tabletcmaps", "Titlecard maps settings", "Title cards (overworld)", CVAR_COSMETIC("HUD.TitleCard.Map"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+10, 1.0f); + Draw_Table_Dropdown("Title cards (Bosses) position", "tabletcbosses", "Title cards (Bosses) settings", "Title cards (Bosses)", CVAR_COSMETIC("HUD.TitleCard.Boss"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+10, 1.0f); + Draw_Table_Dropdown("In-game Gameplay Timer position", "tablegameplaytimer", "In-game Gameplay Timer settings", "In-game Gameplay Timer", CVAR_COSMETIC("HUD.IGT"), 0, ImGui::GetWindowViewport()->Size.y / 2, -50, ImGui::GetWindowViewport()->Size.x / 2 + 10, 1.0f); if (ImGui::CollapsingHeader("Enemy Health Bar position")) { if (ImGui::BeginTable("enemyhealthbar", 1, FlagsTable)) { ImGui::TableSetupColumn("Enemy Health Bar settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); - std::string posTypeCVar = "gCosmetics.Hud_EnemyHealthBarPosType"; + std::string posTypeCVar = CVAR_COSMETIC("HUD.EnemyHealthBar.PosType"); UIWidgets::EnhancementRadioButton("Anchor to Enemy", posTypeCVar.c_str(), ENEMYHEALTH_ANCHOR_ACTOR); UIWidgets::Tooltip("This will use enemy on screen position"); UIWidgets::EnhancementRadioButton("Anchor to the top", posTypeCVar.c_str(), ENEMYHEALTH_ANCHOR_TOP); UIWidgets::Tooltip("This will make your elements follow the top edge of your game window"); UIWidgets::EnhancementRadioButton("Anchor to the bottom", posTypeCVar.c_str(), ENEMYHEALTH_ANCHOR_BOTTOM); UIWidgets::Tooltip("This will make your elements follow the bottom edge of your game window"); - DrawPositionSlider("gCosmetics.Hud_EnemyHealthBar", -SCREEN_HEIGHT, SCREEN_HEIGHT, -ImGui::GetWindowViewport()->Size.x / 2, ImGui::GetWindowViewport()->Size.x / 2); - if (UIWidgets::EnhancementSliderInt("Health Bar Width: %d", "##EnemyHealthBarWidth", "gCosmetics.Hud_EnemyHealthBarWidth.Value", 32, 128, "", 64)) { - CVarSetInteger("gCosmetics.Hud_EnemyHealthBarWidth.Changed", 1); + DrawPositionSlider(CVAR_COSMETIC("HUD.EnemyHealthBar."), -SCREEN_HEIGHT, SCREEN_HEIGHT, -ImGui::GetWindowViewport()->Size.x / 2, ImGui::GetWindowViewport()->Size.x / 2); + if (UIWidgets::EnhancementSliderInt("Health Bar Width: %d", "##EnemyHealthBarWidth", CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value"), 32, 128, "", 64)) { + CVarSetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Changed"), 1); } UIWidgets::Tooltip("This will change the width of the health bar"); ImGui::SameLine(); if (ImGui::Button("Reset##EnemyHealthBarWidth")) { - CVarClear("gCosmetics.Hud_EnemyHealthBarWidth.Value"); - CVarClear("gCosmetics.Hud_EnemyHealthBarWidth.Changed"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + CVarClear(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value")); + CVarClear(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Changed")); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } ImGui::NewLine(); ImGui::EndTable(); } } } - +void Reset_Option_Single(const char* Button_Title, const char* name) { + ImGui::SameLine(); + if (ImGui::Button(Button_Title)) { + CVarClear(name); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } +} +void Reset_Option_Double(const char* Button_Title, const char* name) { + ImGui::SameLine(); + if (ImGui::Button(Button_Title)) { + CVarClear((std::string(name) + ".Value").c_str()); + CVarClear((std::string(name) + ".Changed").c_str()); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } +} void DrawSillyTab() { - ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0)); - if (CVarGetInteger("gLetItSnow", 0)) { - if (UIWidgets::EnhancementCheckbox("Let It Snow", "gLetItSnow")) { - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); + if (CVarGetInteger(CVAR_GENERAL("LetItSnow"), 0)) { + if (UIWidgets::EnhancementCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"))) { + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } } - if (UIWidgets::EnhancementSliderFloat("Link Body Scale: %f", "##Link_BodyScale", "gCosmetics.Link_BodyScale.Value", 0.001f, 0.025f, "", 0.01f, true)) { - CVarSetInteger("gCosmetics.Link_BodyScale.Changed", 1); + if (UIWidgets::EnhancementSliderFloat("Link Body Scale: %.3fx", "##Link_BodyScale", CVAR_COSMETIC("Link.BodyScale.Value"), 0.001f, 0.025f, "", 0.01f, true)) { + CVarSetInteger(CVAR_COSMETIC("Link.BodyScale.Changed"), 1); } ImGui::SameLine(); if (ImGui::Button("Reset##Link_BodyScale")) { - CVarClear("gCosmetics.Link_BodyScale.Value"); - CVarClear("gCosmetics.Link_BodyScale.Changed"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + CVarClear(CVAR_COSMETIC("Link.BodyScale.Value")); + CVarClear(CVAR_COSMETIC("Link.BodyScale.Changed")); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); if (gPlayState != nullptr) { static Player* player = GET_PLAYER(gPlayState); player->actor.scale.x = 0.01f; @@ -1506,70 +1367,31 @@ void DrawSillyTab() { player->actor.scale.z = 0.01f; } } - if (UIWidgets::EnhancementSliderFloat("Link Head Scale: %f", "##Link_HeadScale", "gCosmetics.Link_HeadScale.Value", 0.4f, 4.0f, "", 1.0f, false)) { - CVarSetInteger("gCosmetics.Link_HeadScale.Changed", 1); + if (UIWidgets::EnhancementSliderFloat("Link Head Scale: %.2fx", "##Link_HeadScale", CVAR_COSMETIC("Link.HeadScale.Value"), 0.4f, 4.0f, "", 1.0f, false)) { + CVarSetInteger(CVAR_COSMETIC("Link.HeadScale.Changed"), 1); } - ImGui::SameLine(); - if (ImGui::Button("Reset##Link_HeadScale")) { - CVarClear("gCosmetics.Link_HeadScale.Value"); - CVarClear("gCosmetics.Link_HeadScale.Changed"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Reset_Option_Double("Reset##Link_HeadScale", CVAR_COSMETIC("Link.HeadScale")); + if (UIWidgets::EnhancementSliderFloat("Link Sword Scale: %f", "##Link_SwordScale", CVAR_COSMETIC("Link.SwordScale.Value"), 1.0f, 2.5f, "", 1.0f, false)) { + CVarSetInteger(CVAR_COSMETIC("Link.SwordScale.Changed"), 1); } - if (UIWidgets::EnhancementSliderFloat("Link Sword Scale: %f", "##Link_SwordScale", "gCosmetics.Link_SwordScale.Value", 1.0f, 2.5f, "", 1.0f, false)) { - CVarSetInteger("gCosmetics.Link_SwordScale.Changed", 1); - } - ImGui::SameLine(); - if (ImGui::Button("Reset##Link_SwordScale")) { - CVarClear("gCosmetics.Link_SwordScale.Value"); - CVarClear("gCosmetics.Link_SwordScale.Changed"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - UIWidgets::EnhancementSliderFloat("Bunny Hood Length: %f", "##BunnyHood_EarLength", "gCosmetics.BunnyHood_EarLength", -300.0f, 1000.0f, "", 0.0f, false); - ImGui::SameLine(); - if (ImGui::Button("Reset##BunnyHood_EarLength")) { - CVarClear("gCosmetics.BunnyHood_EarLength"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - UIWidgets::EnhancementSliderFloat("Bunny Hood Spread: %f", "##BunnyHood_EarSpread", "gCosmetics.BunnyHood_EarSpread", -300.0f, 500.0f, "", 0.0f, false); - ImGui::SameLine(); - if (ImGui::Button("Reset##BunnyHood_EarSpread")) { - CVarClear("gCosmetics.BunnyHood_EarSpread"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - UIWidgets::EnhancementSliderFloat("Goron Neck Length: %f", "##Goron_NeckLength", "gCosmetics.Goron_NeckLength", 0.0f, 5000.0f, "", 0.0f, false); - ImGui::SameLine(); - if (ImGui::Button("Reset##Goron_NeckLength")) { - CVarClear("gCosmetics.Goron_NeckLength"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - UIWidgets::EnhancementCheckbox("Unfix Goron Spin", "gUnfixGoronSpin"); - UIWidgets::EnhancementSliderFloat("Fairies Size: %f", "##Fairies_Size", "gCosmetics.Fairies_Size", 0.25f, 5.0f, "", 1.0f, false); - ImGui::SameLine(); - if (ImGui::Button("Reset##Fairies_Size")) { - CVarClear("gCosmetics.Fairies_Size"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - UIWidgets::EnhancementSliderFloat("N64 Logo Spin Speed: %f", "##N64Logo_SpinSpeed", "gCosmetics.N64Logo_SpinSpeed", 0.25f, 5.0f, "", 1.0f, false); - ImGui::SameLine(); - if (ImGui::Button("Reset##N64Logo_SpinSpeed")) { - CVarClear("gCosmetics.N64Logo_SpinSpeed"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - UIWidgets::EnhancementSliderFloat("Moon Size: %f", "##Moon_Size", "gCosmetics.Moon_Size", 0.5f, 2.0f, "", 1.0f, false); - ImGui::SameLine(); - if (ImGui::Button("Reset##Moon_Size")) { - CVarClear("gCosmetics.Moon_Size"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - if (UIWidgets::EnhancementSliderFloat("Kak Windmill Speed: %f", "##Kak_Windmill_Speed", "gCosmetics.Kak_Windmill_Speed.Value", 100.0f, 6000.0f, "", 100.0f, false)) { - CVarSetInteger("gCosmetics.Kak_Windmill_Speed.Changed", 1); - } - ImGui::SameLine(); - if (ImGui::Button("Reset##Kak_Windmill_Speed")) { - CVarClear("gCosmetics.Kak_Windmill_Speed.Value"); - CVarClear("gCosmetics.Kak_Windmill_Speed.Changed"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Reset_Option_Double("Reset##Link_SwordScale", CVAR_COSMETIC("Link.SwordScale")); + UIWidgets::EnhancementSliderFloat("Bunny Hood Length: %f", "##BunnyHood_EarLength", CVAR_COSMETIC("BunnyHood.EarLength"), -300.0f, 1000.0f, "", 0.0f, false); + Reset_Option_Single("Reset##BunnyHood_EarLength", CVAR_COSMETIC("BunnyHood.EarLength")); + UIWidgets::EnhancementSliderFloat("Bunny Hood Spread: %f", "##BunnyHood_EarSpread", CVAR_COSMETIC("BunnyHood.EarSpread"), -300.0f, 500.0f, "", 0.0f, false); + Reset_Option_Single("Reset##BunnyHood_EarSpread", CVAR_COSMETIC("BunnyHood.EarSpread")); + UIWidgets::EnhancementSliderFloat("Goron Neck Length: %f", "##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength"), 0.0f, 1000.0f, "", 0.0f, false); + Reset_Option_Single("Reset##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength")); + UIWidgets::EnhancementCheckbox("Unfix Goron Spin", CVAR_COSMETIC("UnfixGoronSpin")); + UIWidgets::EnhancementSliderFloat("Fairies Size: %f", "##Fairies_Size", CVAR_COSMETIC("Fairies.Size"), 0.25f, 5.0f, "", 1.0f, false); + Reset_Option_Single("Reset##Fairies_Size", CVAR_COSMETIC("Fairies.Size")); + UIWidgets::EnhancementSliderFloat("N64 Logo Spin Speed: %f", "##N64Logo_SpinSpeed", CVAR_COSMETIC("N64Logo.SpinSpeed"), 0.25f, 5.0f, "", 1.0f, false); + Reset_Option_Single("Reset##N64Logo_SpinSpeed", CVAR_COSMETIC("N64Logo.SpinSpeed")); + UIWidgets::EnhancementSliderFloat("Moon Size: %f", "##Moon_Size", CVAR_COSMETIC("Moon.Size"), 0.5f, 2.0f, "", 1.0f, false); + Reset_Option_Single("Reset##Moon_Size", CVAR_COSMETIC("Moon.Size")); + if (UIWidgets::EnhancementSliderFloat("Kak Windmill Speed: %f", "##Kak_Windmill_Speed", CVAR_COSMETIC("Kak.Windmill_Speed.Value"), 100.0f, 6000.0f, "", 100.0f, false)) { + CVarSetInteger(CVAR_COSMETIC("Kak.Windmill_Speed.Changed"), 1); } + Reset_Option_Double("Reset##Kak_Windmill_Speed", CVAR_COSMETIC("Kak.Windmill_Speed")); ImGui::EndDisabled(); } @@ -1592,6 +1414,104 @@ void CopyMultipliedColor(CosmeticOption& cosmeticOptionSrc, CosmeticOption& cosm CVarSetInteger((cosmeticOptionTarget.changedCvar), 1); } +void ToggleRainbow(CosmeticOption& cosmeticOption, bool state) { + if (state) { + CVarSetInteger(cosmeticOption.rainbowCvar, 1); + CVarSetInteger(cosmeticOption.changedCvar, 1); + } else { + CVarClear(cosmeticOption.rainbowCvar); + CVarClear(cosmeticOption.changedCvar); + } +} + +void ApplySideEffects(CosmeticOption& cosmeticOption) { + if (CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { + return; + } + + // This bit is kind of experimental, not sure how I feel about it yet, but it allows for + // advanced cosmetic options to be changed based on a non-advanced option. + if (cosmeticOption.label == "Bow Body") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Equipment.BowTips"), 0.5f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Equipment.BowHandle"), 1.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOption, 4.0f); + } else if (cosmeticOption.label == "Idle Primary") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi.IdleSecondary"), 0.5f); + } else if (cosmeticOption.label == "Enemy Primary") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi.EnemySecondary"), 0.5f); + } else if (cosmeticOption.label == "NPC Primary") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi.NPCSecondary"), 1.0f); + } else if (cosmeticOption.label == "Props Primary") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi.PropsSecondary"), 1.0f); + } else if (cosmeticOption.label == "Ivan Idle Primary") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Ivan.IdleSecondary"), 0.5f); + } else if (cosmeticOption.label == "Level 1 Secondary") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("SpinAttack.Level1Primary"), 2.0f); + } else if (cosmeticOption.label == "Level 2 Secondary") { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("SpinAttack.Level2Primary"), 2.0f); + } else if (cosmeticOption.label == "Item Select Color") { + if (CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { + ToggleRainbow(cosmeticOptions.at("Kaleido.ItemSelB"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.ItemSelC"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.ItemSelD"), true); + } else { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.ItemSelB"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.ItemSelC"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.ItemSelD"), 1.0f); + } + } else if (cosmeticOption.label == "Equip Select Color") { + if (CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { + ToggleRainbow(cosmeticOptions.at("Kaleido.EquipSelB"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.EquipSelC"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.EquipSelD"), true); + } else { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.EquipSelB"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.EquipSelC"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.EquipSelD"), 1.0f); + } + } else if (cosmeticOption.label == "Map Dungeon Color") { + if (CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { + ToggleRainbow(cosmeticOptions.at("Kaleido.MapSelDunB"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.MapSelDunC"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.MapSelDunD"), true); + } else { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.MapSelDunB"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.MapSelDunC"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.MapSelDunD"), 1.0f); + } + } else if (cosmeticOption.label == "Quest Status Color") { + if (CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { + ToggleRainbow(cosmeticOptions.at("Kaleido.QuestStatusB"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.QuestStatusC"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.QuestStatusD"), true); + } else { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.QuestStatusB"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.QuestStatusC"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.QuestStatusD"), 1.0f); + } + } else if (cosmeticOption.label == "Map Color") { + if (CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { + ToggleRainbow(cosmeticOptions.at("Kaleido.MapSelectB"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.MapSelectC"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.MapSelectD"), true); + } else { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.MapSelectB"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.MapSelectC"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.MapSelectD"), 1.0f); + } + } else if (cosmeticOption.label == "Save Color") { + if (CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { + ToggleRainbow(cosmeticOptions.at("Kaleido.SaveB"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.SaveC"), true); + ToggleRainbow(cosmeticOptions.at("Kaleido.SaveD"), true); + } else { + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.SaveB"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.SaveC"), 2.0f); + CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Kaleido.SaveD"), 1.0f); + } + } +} + void RandomizeColor(CosmeticOption& cosmeticOption) { Color_RGBA8 newColor; newColor.r = Random(0, 255); @@ -1611,26 +1531,7 @@ void RandomizeColor(CosmeticOption& cosmeticOption) { CVarSetColor(cosmeticOption.cvar, newColor); CVarSetInteger((cosmeticOption.rainbowCvar), 0); CVarSetInteger((cosmeticOption.changedCvar), 1); - - // This bit is kind of experimental, not sure how I feel about it yet, but it allows for - // advanced cosmetic options to be changed based on a non-advanced option. - if (cosmeticOption.label == "Bow Body") { - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Equipment_BowTips"), 0.5f); - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Equipment_BowHandle"), 1.0f); - CopyMultipliedColor(cosmeticOption, cosmeticOption, 4.0f); - } else if (cosmeticOption.label == "Idle Primary") { - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi_IdleSecondary"), 0.5f); - } else if (cosmeticOption.label == "Enemy Primary") { - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi_EnemySecondary"), 0.5f); - } else if (cosmeticOption.label == "NPC Primary") { - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi_NPCSecondary"), 1.0f); - } else if (cosmeticOption.label == "Props Primary") { - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("Navi_PropsSecondary"), 1.0f); - } else if (cosmeticOption.label == "Level 1 Secondary") { - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("SpinAttack_Level1Primary"), 2.0f); - } else if (cosmeticOption.label == "Level 2 Secondary") { - CopyMultipliedColor(cosmeticOption, cosmeticOptions.at("SpinAttack_Level2Primary"), 2.0f); - } + ApplySideEffects(cosmeticOption); } void ResetColor(CosmeticOption& cosmeticOption) { @@ -1650,22 +1551,46 @@ void ResetColor(CosmeticOption& cosmeticOption) { CVarClear((std::string(cosmeticOption.cvar) + ".A").c_str()); CVarClear((std::string(cosmeticOption.cvar) + ".Type").c_str()); - // This portion should match 1:1 the multiplied colors in `RandomizeColor()` + // This portion should match 1:1 the multiplied colors in `ApplySideEffect()` if (cosmeticOption.label == "Bow Body") { - ResetColor(cosmeticOptions.at("Equipment_BowTips")); - ResetColor(cosmeticOptions.at("Equipment_BowHandle")); + ResetColor(cosmeticOptions.at("Equipment.BowTips")); + ResetColor(cosmeticOptions.at("Equipment.BowHandle")); } else if (cosmeticOption.label == "Idle Primary") { - ResetColor(cosmeticOptions.at("Navi_IdleSecondary")); + ResetColor(cosmeticOptions.at("Navi.IdleSecondary")); } else if (cosmeticOption.label == "Enemy Primary") { - ResetColor(cosmeticOptions.at("Navi_EnemySecondary")); + ResetColor(cosmeticOptions.at("Navi.EnemySecondary")); } else if (cosmeticOption.label == "NPC Primary") { - ResetColor(cosmeticOptions.at("Navi_NPCSecondary")); + ResetColor(cosmeticOptions.at("Navi.NPCSecondary")); } else if (cosmeticOption.label == "Props Primary") { - ResetColor(cosmeticOptions.at("Navi_PropsSecondary")); + ResetColor(cosmeticOptions.at("Navi.PropsSecondary")); } else if (cosmeticOption.label == "Level 1 Secondary") { - ResetColor(cosmeticOptions.at("SpinAttack_Level1Primary")); + ResetColor(cosmeticOptions.at("SpinAttack.Level1Primary")); } else if (cosmeticOption.label == "Level 2 Secondary") { - ResetColor(cosmeticOptions.at("SpinAttack_Level2Primary")); + ResetColor(cosmeticOptions.at("SpinAttack.Level2Primary")); + } else if (cosmeticOption.label == "Item Select Color") { + ResetColor(cosmeticOptions.at("Kaleido.ItemSelB")); + ResetColor(cosmeticOptions.at("Kaleido.ItemSelC")); + ResetColor(cosmeticOptions.at("Kaleido.ItemSelD")); + } else if (cosmeticOption.label == "Equip Select Color") { + ResetColor(cosmeticOptions.at("Kaleido.EquipSelB")); + ResetColor(cosmeticOptions.at("Kaleido.EquipSelC")); + ResetColor(cosmeticOptions.at("Kaleido.EquipSelD")); + } else if (cosmeticOption.label == "Map Dungeon Color") { + ResetColor(cosmeticOptions.at("Kaleido.MapSelDunB")); + ResetColor(cosmeticOptions.at("Kaleido.MapSelDunC")); + ResetColor(cosmeticOptions.at("Kaleido.MapSelDunD")); + } else if (cosmeticOption.label == "Quest Status Color") { + ResetColor(cosmeticOptions.at("Kaleido.QuestStatusB")); + ResetColor(cosmeticOptions.at("Kaleido.QuestStatusC")); + ResetColor(cosmeticOptions.at("Kaleido.QuestStatusD")); + } else if (cosmeticOption.label == "Map Color") { + ResetColor(cosmeticOptions.at("Kaleido.MapSelectB")); + ResetColor(cosmeticOptions.at("Kaleido.MapSelectC")); + ResetColor(cosmeticOptions.at("Kaleido.MapSelectD")); + } else if (cosmeticOption.label == "Save Color") { + ResetColor(cosmeticOptions.at("Kaleido.SaveB")); + ResetColor(cosmeticOptions.at("Kaleido.SaveC")); + ResetColor(cosmeticOptions.at("Kaleido.SaveD")); } } @@ -1686,8 +1611,9 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { CVarSetColor(cosmeticOption.cvar, color); CVarSetInteger((cosmeticOption.rainbowCvar), 0); CVarSetInteger((cosmeticOption.changedCvar), 1); + ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } ImGui::SameLine(); ImGui::Text("%s", cosmeticOption.label.c_str()); @@ -1695,7 +1621,7 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { if (ImGui::Button(("Random##" + cosmeticOption.label).c_str())) { RandomizeColor(cosmeticOption); ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } if (cosmeticOption.supportsRainbow) { ImGui::SameLine(); @@ -1703,22 +1629,23 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { if (ImGui::Checkbox(("Rainbow##" + cosmeticOption.label).c_str(), &isRainbow)) { CVarSetInteger((cosmeticOption.rainbowCvar), isRainbow); CVarSetInteger((cosmeticOption.changedCvar), 1); + ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } } ImGui::SameLine(); bool isLocked = (bool)CVarGetInteger((cosmeticOption.lockedCvar), 0); if (ImGui::Checkbox(("Locked##" + cosmeticOption.label).c_str(), &isLocked)) { CVarSetInteger((cosmeticOption.lockedCvar), isLocked); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } if (CVarGetInteger((cosmeticOption.changedCvar), 0)) { ImGui::SameLine(); if (ImGui::Button(("Reset##" + cosmeticOption.label).c_str())) { ResetColor(cosmeticOption); ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } } } @@ -1729,12 +1656,12 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { ImGui::SameLine((ImGui::CalcTextSize("Mirror Shield Mirror").x * 1.0f) + 60.0f); if (ImGui::Button(("Random##" + label).c_str())) { for (auto& [id, cosmeticOption] : cosmeticOptions) { - if (cosmeticOption.group == cosmeticGroup && (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0)) && !CVarGetInteger(cosmeticOption.lockedCvar, 0)) { + if (cosmeticOption.group == cosmeticGroup && (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) && !CVarGetInteger(cosmeticOption.lockedCvar, 0)) { RandomizeColor(cosmeticOption); } } ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } ImGui::SameLine(); if (ImGui::Button(("Reset##" + label).c_str())) { @@ -1744,10 +1671,10 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { } } ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } for (auto& [id, cosmeticOption] : cosmeticOptions) { - if (cosmeticOption.group == cosmeticGroup && (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0))) { + if (cosmeticOption.group == cosmeticGroup && (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { DrawCosmeticRow(cosmeticOption); } } @@ -1759,7 +1686,7 @@ static const char* colorSchemes[2] = { }; void CosmeticsEditorWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(480, 520), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(550, 520), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Cosmetics Editor", &mIsVisible)) { ImGui::End(); return; @@ -1767,20 +1694,20 @@ void CosmeticsEditorWindow::DrawElement() { ImGui::Text("Color Scheme"); ImGui::SameLine(); - UIWidgets::EnhancementCombobox("gCosmetics.DefaultColorScheme", colorSchemes, COLORSCHEME_N64); - UIWidgets::EnhancementCheckbox("Advanced Mode", "gCosmetics.AdvancedMode"); + UIWidgets::EnhancementCombobox(CVAR_COSMETIC("DefaultColorScheme"), colorSchemes, COLORSCHEME_N64); + UIWidgets::EnhancementCheckbox("Advanced Mode", CVAR_COSMETIC("AdvancedMode")); UIWidgets::InsertHelpHoverText( "Some cosmetic options may not apply if you have any mods that provide custom models for the cosmetic option.\n\n" "For example, if you have custom Link model, then the Link's Hair color option will most likely not apply." ); - if (CVarGetInteger("gCosmetics.AdvancedMode", 0)) { + if (CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { if (ImGui::Button("Lock All Advanced", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.advancedOption) { CVarSetInteger(cosmeticOption.lockedCvar, 1); } } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } ImGui::SameLine(); if (ImGui::Button("Unlock All Advanced", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { @@ -1789,19 +1716,16 @@ void CosmeticsEditorWindow::DrawElement() { CVarSetInteger(cosmeticOption.lockedCvar, 0); } } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } } - UIWidgets::EnhancementCheckbox("Sync Rainbow colors", "gCosmetics.RainbowSync"); - UIWidgets::EnhancementSliderFloat("Rainbow Speed: %f", "##rainbowSpeed", "gCosmetics.RainbowSpeed", 0.03f, 1.0f, "", 0.6f, false); + UIWidgets::EnhancementCheckbox("Sync Rainbow colors", CVAR_COSMETIC("RainbowSync")); + UIWidgets::EnhancementSliderFloat("Rainbow Speed: %.3f", "##rainbowSpeed", CVAR_COSMETIC("RainbowSpeed"), 0.03f, 1.0f, "", 0.6f, false, true); + UIWidgets::EnhancementCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene")); + UIWidgets::Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene."); + if (ImGui::Button("Randomize All", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { - for (auto& [id, cosmeticOption] : cosmeticOptions) { - if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0))) { - RandomizeColor(cosmeticOption); - } - } - ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + CosmeticsEditor_RandomizeAll(); } ImGui::SameLine(); if (ImGui::Button("Reset All", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { @@ -1811,57 +1735,58 @@ void CosmeticsEditorWindow::DrawElement() { } } ApplyOrResetCustomGfxPatches(); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } if (ImGui::Button("Lock All", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { - if (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0)) { + if (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { CVarSetInteger(cosmeticOption.lockedCvar, 1); } } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } ImGui::SameLine(); if (ImGui::Button("Unlock All", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { - if (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0)) { + if (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { CVarSetInteger(cosmeticOption.lockedCvar, 0); } } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } if (ImGui::BeginTabBar("CosmeticsContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { if (ImGui::BeginTabItem("Link & Items")) { - DrawCosmeticGroup(GROUP_LINK); - DrawCosmeticGroup(GROUP_GLOVES); - DrawCosmeticGroup(GROUP_MIRRORSHIELD); - DrawCosmeticGroup(GROUP_EQUIPMENT); - DrawCosmeticGroup(GROUP_SWORDS); - DrawCosmeticGroup(GROUP_CONSUMABLE); + DrawCosmeticGroup(COSMETICS_GROUP_LINK); + DrawCosmeticGroup(COSMETICS_GROUP_GLOVES); + DrawCosmeticGroup(COSMETICS_GROUP_MIRRORSHIELD); + DrawCosmeticGroup(COSMETICS_GROUP_EQUIPMENT); + DrawCosmeticGroup(COSMETICS_GROUP_SWORDS); + DrawCosmeticGroup(COSMETICS_GROUP_CONSUMABLE); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Effects")) { - // DrawCosmeticGroup(GROUP_MAGIC); // Cosmetics TODO: Implement magic effect colors - DrawCosmeticGroup(GROUP_ARROWS); - DrawCosmeticGroup(GROUP_SPIN_ATTACK); - DrawCosmeticGroup(GROUP_TRAILS); - if (UIWidgets::EnhancementSliderInt("Trails Duration: %d", "##Trails_Duration", "gCosmetics.Trails_Duration.Value", 2, 20, "", 4)) { - CVarSetInteger("gCosmetics.Trails_Duration.Changed", 1); + // DrawCosmeticGroup(COSMETICS_GROUP_MAGIC); // Cosmetics TODO: Implement magic effect colors + DrawCosmeticGroup(COSMETICS_GROUP_ARROWS); + DrawCosmeticGroup(COSMETICS_GROUP_SPIN_ATTACK); + DrawCosmeticGroup(COSMETICS_GROUP_TRAILS); + if (UIWidgets::EnhancementSliderInt("Trails Duration: %d", "##Trails_Duration", CVAR_COSMETIC("Trails.Duration.Value"), 2, 20, "", 4)) { + CVarSetInteger(CVAR_COSMETIC("Trails.Duration.Changed"), 1); } ImGui::SameLine(); if (ImGui::Button("Reset##Trails_Duration")) { - CVarClear("gCosmetics.Trails_Duration.Value"); - CVarClear("gCosmetics.Trails_Duration.Changed"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + CVarClear(CVAR_COSMETIC("Trails.Duration.Value")); + CVarClear(CVAR_COSMETIC("Trails.Duration.Changed")); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } ImGui::EndTabItem(); } if (ImGui::BeginTabItem("World & NPCs")) { - DrawCosmeticGroup(GROUP_WORLD); - DrawCosmeticGroup(GROUP_NAVI); - DrawCosmeticGroup(GROUP_NPC); + DrawCosmeticGroup(COSMETICS_GROUP_WORLD); + DrawCosmeticGroup(COSMETICS_GROUP_NAVI); + DrawCosmeticGroup(COSMETICS_GROUP_IVAN); + DrawCosmeticGroup(COSMETICS_GROUP_NPC); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Silly")) { @@ -1869,14 +1794,20 @@ void CosmeticsEditorWindow::DrawElement() { ImGui::EndTabItem(); } if (ImGui::BeginTabItem("HUD")) { - DrawCosmeticGroup(GROUP_HUD); - DrawCosmeticGroup(GROUP_TITLE); + DrawCosmeticGroup(COSMETICS_GROUP_HUD); + DrawCosmeticGroup(COSMETICS_GROUP_TITLE); ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("HUD Placement")) { Draw_Placements(); ImGui::EndTabItem(); } + + if (ImGui::BeginTabItem("Pause Menu")) { + DrawCosmeticGroup(COSMETICS_GROUP_KALEIDO); + ImGui::EndTabItem(); + } ImGui::EndTabBar(); } ImGui::End(); @@ -1894,6 +1825,14 @@ void RegisterOnGameFrameUpdateHook() { }); } +void Cosmetics_RegisterOnSceneInitHook() { + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + if (CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnNewScene"), 0)) { + CosmeticsEditor_RandomizeAll(); + } + }); +} + void CosmeticsEditorWindow::InitElement() { // Convert the `current color` into the format that the ImGui color picker expects for (auto& [id, cosmeticOption] : cosmeticOptions) { @@ -1905,23 +1844,37 @@ void CosmeticsEditorWindow::InitElement() { cosmeticOption.currentColor.z = cvarColor.b / 255.0; cosmeticOption.currentColor.w = cvarColor.a / 255.0; } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); ApplyOrResetCustomGfxPatches(); ApplyAuthenticGfxPatches(); RegisterOnLoadGameHook(); RegisterOnGameFrameUpdateHook(); + Cosmetics_RegisterOnSceneInitHook(); } void CosmeticsEditor_RandomizeAll() { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && - (!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0))) { + (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { RandomizeColor(cosmeticOption); } } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + ApplyOrResetCustomGfxPatches(); +} + +void CosmeticsEditor_RandomizeGroup(CosmeticGroup group) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && + (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) && + cosmeticOption.group == group) { + RandomizeColor(cosmeticOption); + } + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); ApplyOrResetCustomGfxPatches(); } @@ -1932,6 +1885,17 @@ void CosmeticsEditor_ResetAll() { } } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + ApplyOrResetCustomGfxPatches(); +} + +void CosmeticsEditor_ResetGroup(CosmeticGroup group) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && cosmeticOption.group == group) { + ResetColor(cosmeticOption); + } + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); ApplyOrResetCustomGfxPatches(); } diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h index b22a51ba7..88f60c76c 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h @@ -8,6 +8,29 @@ 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 { const std::string Name; const std::string ToolTip; @@ -26,10 +49,12 @@ static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | Im void InitCosmeticsEditor();//Init the menu itself ImVec4 GetRandomValue(int MaximumPossible); void CosmeticsEditor_RandomizeAll(); +void CosmeticsEditor_RandomizeGroup(CosmeticGroup group); void CosmeticsEditor_ResetAll(); +void CosmeticsEditor_ResetGroup(CosmeticGroup group); void ApplyOrResetCustomGfxPatches(bool manualChange = true); -class CosmeticsEditorWindow : public LUS::GuiWindow { +class CosmeticsEditorWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; diff --git a/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp b/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp index 709854c35..f31eedd2c 100644 --- a/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp +++ b/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp @@ -1,5 +1,6 @@ #include #include +#include "soh/OTRGlobals.h" extern "C" { #include @@ -81,7 +82,7 @@ void PatchDekuStickTextureOverflow() { const char* dlist = gLinkChildLinkDekuStickDL; int start = 5; - if (!CVarGetInteger("gFixTexturesOOB", 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) { // Unpatch the other texture fix for (size_t i = 0; i < 7; i++) { int instruction = start + (i == 0 ? 0 : i + 1); @@ -121,7 +122,7 @@ void PatchFreezardTextureOverflow() { char patchNameBuf[24]; // Patch using custom overflowed texture - if (!CVarGetInteger("gFixTexturesOOB", 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) { // Unpatch the other texture fix for (size_t i = 0; i < 7; i++) { 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 // Patch using custom overflowed texture - // if (!CVarGetInteger("gFixTexturesOOB", 0)) { + // if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) { // Unpatch the other texture fix for (size_t i = 0; i < 7; i++) { 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), }; - if (CVarGetInteger("gMirroredWorld", 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) { if (mirroredSoldOutVtx == nullptr) { // Copy the original vertices that we want to modify (4 at the beginning of the resource) 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) }; - if (CVarGetInteger("gMirroredWorld", 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) { if (mirroredSunSongVtx == nullptr) { // Copy the original vertices that we want to modify (4 at the beginning of the resource) mirroredSunSongVtx = (Vtx*)malloc(sizeof(Vtx) * 4); diff --git a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp index d2e8e03b1..6443a7ff3 100644 --- a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp +++ b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp @@ -1,4 +1,4 @@ -#ifdef ENABLE_CROWD_CONTROL +#ifdef ENABLE_REMOTE_CONTROL #include "CrowdControl.h" #include "CrowdControlTypes.h" @@ -17,25 +17,17 @@ extern "C" { extern PlayState* gPlayState; } -void CrowdControl::Init() { - SDLNet_Init(); -} - -void CrowdControl::Shutdown() { - SDLNet_Quit(); -} - void CrowdControl::Enable() { if (isEnabled) { return; } - if (SDLNet_ResolveHost(&ip, "127.0.0.1", 43384) == -1) { - SPDLOG_ERROR("[CrowdControl] SDLNet_ResolveHost: {}", SDLNet_GetError()); - } - 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); } @@ -45,87 +37,42 @@ void CrowdControl::Disable() { } isEnabled = false; - ccThreadReceive.join(); ccThreadProcess.join(); + GameInteractor::Instance->DisableRemoteInteractor(); } -void CrowdControl::ListenToServer() { - while (isEnabled) { - while (!connected && isEnabled) { - SPDLOG_TRACE("[CrowdControl] Attempting to make connection to server..."); - tcpsock = SDLNet_TCP_Open(&ip); +void CrowdControl::HandleRemoteData(nlohmann::json payload) { + Effect* incomingEffect = ParseMessage(payload); + if (!incomingEffect) { + return; + } - if (tcpsock) { - connected = true; - SPDLOG_TRACE("[CrowdControl] Connection to server established!"); + // If effect is not a timed effect, execute and return result. + if (!incomingEffect->timeRemaining) { + EffectResult result = CrowdControl::ExecuteEffect(incomingEffect); + EmitMessage(incomingEffect->id, incomingEffect->timeRemaining, result); + } else { + // If another timed effect is already active that conflicts with the incoming effect. + bool isConflictingEffectActive = false; + for (Effect* effect : activeEffects) { + if (effect != incomingEffect && effect->category == incomingEffect->category && effect->id < incomingEffect->id) { + isConflictingEffectActive = true; + EmitMessage(incomingEffect->id, incomingEffect->timeRemaining, EffectResult::Retry); 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 (!isConflictingEffectActive) { + // Check if effect can be applied, if it can't, let CC know. + EffectResult result = CrowdControl::CanApplyEffect(incomingEffect); + if (result == EffectResult::Retry || result == EffectResult::Failure) { + EmitMessage(incomingEffect->id, incomingEffect->timeRemaining, result); + return; } - 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) { - continue; - } - - // If effect is not a timed effect, execute and return result. - if (!incomingEffect->timeRemaining) { - EffectResult result = CrowdControl::ExecuteEffect(incomingEffect); - EmitMessage(tcpsock, incomingEffect->id, incomingEffect->timeRemaining, result); - } else { - // If another timed effect is already active that conflicts with the incoming effect. - bool isConflictingEffectActive = false; - for (Effect* effect : activeEffects) { - if (effect != incomingEffect && effect->category == incomingEffect->category && effect->id < incomingEffect->id) { - isConflictingEffectActive = true; - EmitMessage(tcpsock, incomingEffect->id, incomingEffect->timeRemaining, EffectResult::Retry); - break; - } - } - - if (!isConflictingEffectActive) { - // Check if effect can be applied, if it can't, let CC know. - EffectResult result = CrowdControl::CanApplyEffect(incomingEffect); - if (result == EffectResult::Retry || result == EffectResult::Failure) { - EmitMessage(tcpsock, incomingEffect->id, incomingEffect->timeRemaining, result); - continue; - } - - activeEffectsMutex.lock(); - activeEffects.push_back(incomingEffect); - activeEffectsMutex.unlock(); - } - } - } - - if (connected) { - SDLNet_TCP_Close(tcpsock); - connected = false; - SPDLOG_TRACE("[CrowdControl] Ending Listen thread..."); + activeEffectsMutex.lock(); + activeEffects.push_back(incomingEffect); + activeEffectsMutex.unlock(); } } } @@ -147,13 +94,13 @@ void CrowdControl::ProcessActiveEffects() { if (effect->timeRemaining <= 0) { it = activeEffects.erase(std::remove(activeEffects.begin(), activeEffects.end(), effect), activeEffects.end()); - GameInteractor::RemoveEffect(effect->giEffect); + GameInteractor::RemoveEffect(dynamic_cast(effect->giEffect)); delete effect; } else { // If we have a success after previously being paused, tell CC to resume timer. if (effect->isPaused) { 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 // the result is different from the last time this was ran. // Timed events are put on a thread that runs once per second. @@ -161,7 +108,7 @@ void CrowdControl::ProcessActiveEffects() { effect->timeRemaining -= 1000; if (result != effect->lastExecutionResult) { effect->lastExecutionResult = result; - EmitMessage(tcpsock, effect->id, effect->timeRemaining, EffectResult::Success); + EmitMessage(effect->id, effect->timeRemaining, EffectResult::Success); } } it++; @@ -169,7 +116,7 @@ void CrowdControl::ProcessActiveEffects() { } else { // Timed effects only do Success or Retry if (!effect->isPaused && effect->timeRemaining > 0) { effect->isPaused = true; - EmitMessage(tcpsock, effect->id, effect->timeRemaining, EffectResult::Paused); + EmitMessage(effect->id, effect->timeRemaining, EffectResult::Paused); } it++; } @@ -182,7 +129,7 @@ void CrowdControl::ProcessActiveEffects() { 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; payload["id"] = eventId; @@ -190,8 +137,9 @@ void CrowdControl::EmitMessage(TCPsocket socket, uint32_t eventId, long timeRema payload["timeRemaining"] = timeRemaining; payload["status"] = status; - std::string jsonPayload = payload.dump(); - SDLNet_TCP_Send(socket, jsonPayload.c_str(), jsonPayload.size() + 1); + SPDLOG_INFO("[CrowdControl] Sending payload:\n{}", payload.dump()); + + GameInteractor::Instance->TransmitJsonToRemote(payload); } CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) { @@ -229,13 +177,14 @@ CrowdControl::EffectResult CrowdControl::TranslateGiEnum(GameInteractionEffectQu return result; } -CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { - nlohmann::json dataReceived = nlohmann::json::parse(payload, nullptr, false); - if (dataReceived.is_discarded()) { - SPDLOG_ERROR("Error parsing JSON"); +CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) { + if (!dataReceived.contains("id") || !dataReceived.contains("type")) { + SPDLOG_ERROR("[CrowdControl] Invalid payload received:\n{}", dataReceived.dump()); return nullptr; } + SPDLOG_INFO("[CrowdControl] Received payload:\n{}", dataReceived.dump()); + Effect* effect = new Effect(); effect->lastExecutionResult = EffectResult::Initiate; effect->id = dataReceived["id"]; @@ -333,13 +282,13 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { effect->category = kEffectCatDamageTaken; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier(); - effect->giEffect->parameters[0] = 2; + dynamic_cast(effect->giEffect)->parameters[0] = 2; break; case kEffectTakeDoubleDamage: effect->category = kEffectCatDamageTaken; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier(); - effect->giEffect->parameters[0] = -2; + dynamic_cast(effect->giEffect)->parameters[0] = -2; break; case kEffectOneHitKo: effect->category = kEffectCatDamageTaken; @@ -356,37 +305,37 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { effect->category = kEffectCatSpeed; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier(); - effect->giEffect->parameters[0] = 2; + dynamic_cast(effect->giEffect)->parameters[0] = 2; break; case kEffectDecreaseSpeed: effect->category = kEffectCatSpeed; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier(); - effect->giEffect->parameters[0] = -2; + dynamic_cast(effect->giEffect)->parameters[0] = -2; break; case kEffectLowGravity: effect->category = kEffectCatGravity; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyGravity(); - effect->giEffect->parameters[0] = GI_GRAVITY_LEVEL_LIGHT; + dynamic_cast(effect->giEffect)->parameters[0] = GI_GRAVITY_LEVEL_LIGHT; break; case kEffectHighGravity: effect->category = kEffectCatGravity; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyGravity(); - effect->giEffect->parameters[0] = GI_GRAVITY_LEVEL_HEAVY; + dynamic_cast(effect->giEffect)->parameters[0] = GI_GRAVITY_LEVEL_HEAVY; break; case kEffectForceIronBoots: effect->category = kEffectCatBoots; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ForceEquipBoots(); - effect->giEffect->parameters[0] = EQUIP_VALUE_BOOTS_IRON; + dynamic_cast(effect->giEffect)->parameters[0] = EQUIP_VALUE_BOOTS_IRON; break; case kEffectForceHoverBoots: effect->category = kEffectCatBoots; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ForceEquipBoots(); - effect->giEffect->parameters[0] = EQUIP_VALUE_BOOTS_HOVER; + dynamic_cast(effect->giEffect)->parameters[0] = EQUIP_VALUE_BOOTS_HOVER; break; case kEffectSlipperyFloor: effect->category = kEffectCatSlipperyFloor; @@ -412,23 +361,23 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { // Hurt or Heal Link case kEffectEmptyHeart: effect->giEffect = new GameInteractionEffect::ModifyHealth(); - effect->giEffect->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; break; case kEffectFillHeart: effect->giEffect = new GameInteractionEffect::ModifyHealth(); - effect->giEffect->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; break; case kEffectKnockbackLinkWeak: effect->giEffect = new GameInteractionEffect::KnockbackPlayer(); - effect->giEffect->parameters[0] = 1; + dynamic_cast(effect->giEffect)->parameters[0] = 1; break; case kEffectKnockbackLinkStrong: effect->giEffect = new GameInteractionEffect::KnockbackPlayer(); - effect->giEffect->parameters[0] = 3; + dynamic_cast(effect->giEffect)->parameters[0] = 3; break; case kEffectKnockbackLinkMega: effect->giEffect = new GameInteractionEffect::KnockbackPlayer(); - effect->giEffect->parameters[0] = 6; + dynamic_cast(effect->giEffect)->parameters[0] = 6; break; case kEffectBurnLink: effect->giEffect = new GameInteractionEffect::BurnPlayer(); @@ -441,109 +390,109 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { break; case kEffectKillLink: effect->giEffect = new GameInteractionEffect::SetPlayerHealth(); - effect->giEffect->parameters[0] = 0; + dynamic_cast(effect->giEffect)->parameters[0] = 0; break; // Give Items and Consumables case kEffectAddHeartContainer: effect->giEffect = new GameInteractionEffect::ModifyHeartContainers(); - effect->giEffect->parameters[0] = 1; + dynamic_cast(effect->giEffect)->parameters[0] = 1; break; case kEffectFillMagic: effect->giEffect = new GameInteractionEffect::FillMagic(); break; case kEffectAddRupees: effect->giEffect = new GameInteractionEffect::ModifyRupees(); - effect->giEffect->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; break; case kEffectGiveDekuShield: effect->giEffect = new GameInteractionEffect::GiveOrTakeShield(); - effect->giEffect->parameters[0] = ITEM_SHIELD_DEKU; + dynamic_cast(effect->giEffect)->parameters[0] = ITEM_SHIELD_DEKU; break; case kEffectGiveHylianShield: effect->giEffect = new GameInteractionEffect::GiveOrTakeShield(); - effect->giEffect->parameters[0] = ITEM_SHIELD_HYLIAN; + dynamic_cast(effect->giEffect)->parameters[0] = ITEM_SHIELD_HYLIAN; break; case kEffectRefillSticks: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter; - effect->giEffect->parameters[1] = ITEM_STICK; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_STICK; break; case kEffectRefillNuts: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter; - effect->giEffect->parameters[1] = ITEM_NUT; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_NUT; break; case kEffectRefillBombs: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter; - effect->giEffect->parameters[1] = ITEM_BOMB; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_BOMB; break; case kEffectRefillSeeds: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter; - effect->giEffect->parameters[1] = ITEM_SLINGSHOT; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_SLINGSHOT; break; case kEffectRefillArrows: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter; - effect->giEffect->parameters[1] = ITEM_BOW; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_BOW; break; case kEffectRefillBombchus: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter; - effect->giEffect->parameters[1] = ITEM_BOMBCHU; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_BOMBCHU; break; // Take Items and Consumables case kEffectRemoveHeartContainer: effect->giEffect = new GameInteractionEffect::ModifyHeartContainers(); - effect->giEffect->parameters[0] = -1; + dynamic_cast(effect->giEffect)->parameters[0] = -1; break; case kEffectEmptyMagic: effect->giEffect = new GameInteractionEffect::EmptyMagic(); break; case kEffectRemoveRupees: effect->giEffect = new GameInteractionEffect::ModifyRupees(); - effect->giEffect->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; break; case kEffectTakeDekuShield: effect->giEffect = new GameInteractionEffect::GiveOrTakeShield(); - effect->giEffect->parameters[0] = -ITEM_SHIELD_DEKU; + dynamic_cast(effect->giEffect)->parameters[0] = -ITEM_SHIELD_DEKU; break; case kEffectTakeHylianShield: effect->giEffect = new GameInteractionEffect::GiveOrTakeShield(); - effect->giEffect->parameters[0] = -ITEM_SHIELD_HYLIAN; + dynamic_cast(effect->giEffect)->parameters[0] = -ITEM_SHIELD_HYLIAN; break; case kEffectTakeSticks: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter * -1; - effect->giEffect->parameters[1] = ITEM_STICK; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_STICK; break; case kEffectTakeNuts: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter * -1; - effect->giEffect->parameters[1] = ITEM_NUT; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_NUT; break; case kEffectTakeBombs: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter * -1; - effect->giEffect->parameters[1] = ITEM_BOMB; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_BOMB; break; case kEffectTakeSeeds: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter * -1; - effect->giEffect->parameters[1] = ITEM_SLINGSHOT; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_SLINGSHOT; break; case kEffectTakeArrows: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter * -1; - effect->giEffect->parameters[1] = ITEM_BOW; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_BOW; break; case kEffectTakeBombchus: effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->giEffect->parameters[0] = receivedParameter * -1; - effect->giEffect->parameters[1] = ITEM_BOMBCHU; + dynamic_cast(effect->giEffect)->parameters[0] = receivedParameter * -1; + dynamic_cast(effect->giEffect)->parameters[1] = ITEM_BOMBCHU; break; // Link Size Modifiers @@ -551,25 +500,25 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { effect->category = kEffectCatLinkSize; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyLinkSize(); - effect->giEffect->parameters[0] = GI_LINK_SIZE_GIANT; + dynamic_cast(effect->giEffect)->parameters[0] = GI_LINK_SIZE_GIANT; break; case kEffectMinishLink: effect->category = kEffectCatLinkSize; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyLinkSize(); - effect->giEffect->parameters[0] = GI_LINK_SIZE_MINISH; + dynamic_cast(effect->giEffect)->parameters[0] = GI_LINK_SIZE_MINISH; break; case kEffectPaperLink: effect->category = kEffectCatLinkSize; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyLinkSize(); - effect->giEffect->parameters[0] = GI_LINK_SIZE_PAPER; + dynamic_cast(effect->giEffect)->parameters[0] = GI_LINK_SIZE_PAPER; break; case kEffectSquishedLink: effect->category = kEffectCatLinkSize; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::ModifyLinkSize(); - effect->giEffect->parameters[0] = GI_LINK_SIZE_SQUISHED; + dynamic_cast(effect->giEffect)->parameters[0] = GI_LINK_SIZE_SQUISHED; break; case kEffectInvisibleLink: effect->category = kEffectCatLinkSize; @@ -585,11 +534,11 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { break; case kEffectSetTimeToDawn: effect->giEffect = new GameInteractionEffect::SetTimeOfDay(); - effect->giEffect->parameters[0] = GI_TIMEOFDAY_DAWN; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TIMEOFDAY_DAWN; break; case kEffectSetTimeToDusk: effect->giEffect = new GameInteractionEffect::SetTimeOfDay(); - effect->giEffect->parameters[0] = GI_TIMEOFDAY_DUSK; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TIMEOFDAY_DUSK; break; // Visual Effects @@ -632,186 +581,186 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) { effect->category = kEffectCatRandomButtons; effect->timeRemaining = 30000; effect->giEffect = new GameInteractionEffect::PressRandomButton(); - effect->giEffect->parameters[0] = 30; + dynamic_cast(effect->giEffect)->parameters[0] = 30; break; case kEffectClearCbuttons: effect->giEffect = new GameInteractionEffect::ClearAssignedButtons(); - effect->giEffect->parameters[0] = GI_BUTTONS_CBUTTONS; + dynamic_cast(effect->giEffect)->parameters[0] = GI_BUTTONS_CBUTTONS; break; case kEffectClearDpad: effect->giEffect = new GameInteractionEffect::ClearAssignedButtons(); - effect->giEffect->parameters[0] = GI_BUTTONS_DPAD; + dynamic_cast(effect->giEffect)->parameters[0] = GI_BUTTONS_DPAD; break; // Teleport Player case kEffectTpLinksHouse: effect->giEffect = new GameInteractionEffect::TeleportPlayer(); - effect->giEffect->parameters[0] = GI_TP_DEST_LINKSHOUSE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TP_DEST_LINKSHOUSE; break; case kEffectTpMinuet: effect->giEffect = new GameInteractionEffect::TeleportPlayer(); - effect->giEffect->parameters[0] = GI_TP_DEST_MINUET; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TP_DEST_MINUET; break; case kEffectTpBolero: effect->giEffect = new GameInteractionEffect::TeleportPlayer(); - effect->giEffect->parameters[0] = GI_TP_DEST_BOLERO; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TP_DEST_BOLERO; break; case kEffectTpSerenade: effect->giEffect = new GameInteractionEffect::TeleportPlayer(); - effect->giEffect->parameters[0] = GI_TP_DEST_SERENADE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TP_DEST_SERENADE; break; case kEffectTpRequiem: effect->giEffect = new GameInteractionEffect::TeleportPlayer(); - effect->giEffect->parameters[0] = GI_TP_DEST_REQUIEM; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TP_DEST_REQUIEM; break; case kEffectTpNocturne: effect->giEffect = new GameInteractionEffect::TeleportPlayer(); - effect->giEffect->parameters[0] = GI_TP_DEST_NOCTURNE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TP_DEST_NOCTURNE; break; case kEffectTpPrelude: effect->giEffect = new GameInteractionEffect::TeleportPlayer(); - effect->giEffect->parameters[0] = GI_TP_DEST_PRELUDE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_TP_DEST_PRELUDE; break; // Tunic Color (Bidding War) case kEffectTunicRed: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_RED; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_RED; break; case kEffectTunicGreen: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_GREEN; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_GREEN; break; case kEffectTunicBlue: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_BLUE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BLUE; break; case kEffectTunicOrange: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_ORANGE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE; break; case kEffectTunicYellow: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_YELLOW; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW; break; case kEffectTunicPurple: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_PURPLE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE; break; case kEffectTunicPink: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_PINK; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_PINK; break; case kEffectTunicBrown: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_BROWN; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BROWN; break; case kEffectTunicBlack: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS; - effect->giEffect->parameters[1] = GI_COLOR_BLACK; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BLACK; break; // Navi Color (Bidding War) case kEffectNaviRed: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_RED; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_RED; break; case kEffectNaviGreen: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_GREEN; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_GREEN; break; case kEffectNaviBlue: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_BLUE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BLUE; break; case kEffectNaviOrange: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_ORANGE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE; break; case kEffectNaviYellow: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_YELLOW; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW; break; case kEffectNaviPurple: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_PURPLE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE; break; case kEffectNaviPink: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_PINK; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_PINK; break; case kEffectNaviBrown: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_BROWN; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BROWN; break; case kEffectNaviBlack: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_NAVI; - effect->giEffect->parameters[1] = GI_COLOR_BLACK; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BLACK; break; // Link's Hair Color (Bidding War) case kEffectHairRed: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_RED; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_RED; break; case kEffectHairGreen: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_GREEN; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_GREEN; break; case kEffectHairBlue: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_BLUE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BLUE; break; case kEffectHairOrange: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_ORANGE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE; break; case kEffectHairYellow: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_YELLOW; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW; break; case kEffectHairPurple: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_PURPLE; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE; break; case kEffectHairPink: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_PINK; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_PINK; break; case kEffectHairBrown: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_BROWN; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BROWN; break; case kEffectHairBlack: effect->giEffect = new GameInteractionEffect::SetCosmeticsColor(); - effect->giEffect->parameters[0] = GI_COSMETICS_HAIR; - effect->giEffect->parameters[1] = GI_COLOR_BLACK; + dynamic_cast(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR; + dynamic_cast(effect->giEffect)->parameters[1] = GI_COLOR_BLACK; break; default: diff --git a/soh/soh/Enhancements/crowd-control/CrowdControl.h b/soh/soh/Enhancements/crowd-control/CrowdControl.h index 672e6d361..bb06cc5b1 100644 --- a/soh/soh/Enhancements/crowd-control/CrowdControl.h +++ b/soh/soh/Enhancements/crowd-control/CrowdControl.h @@ -1,4 +1,4 @@ -#ifdef ENABLE_CROWD_CONTROL +#ifdef ENABLE_REMOTE_CONTROL #ifndef _CROWDCONTROL_C #define _CROWDCONTROL_C @@ -73,33 +73,24 @@ class CrowdControl { EffectResult lastExecutionResult; } Effect; - std::thread ccThreadReceive; std::thread ccThreadProcess; - TCPsocket tcpsock; - IPaddress ip; - bool isEnabled; - bool connected; - - char received[512]; std::vector activeEffects; std::mutex activeEffectsMutex; - void ListenToServer(); + void HandleRemoteData(nlohmann::json payload); void ProcessActiveEffects(); - void EmitMessage(TCPsocket socket, uint32_t eventId, long timeRemaining, EffectResult status); - Effect* ParseMessage(char payload[512]); + void EmitMessage(uint32_t eventId, long timeRemaining, EffectResult status); + Effect* ParseMessage(nlohmann::json payload); EffectResult ExecuteEffect(Effect* effect); EffectResult CanApplyEffect(Effect *effect); EffectResult TranslateGiEnum(GameInteractionEffectQueryResult giResult); public: static CrowdControl* Instance; - void Init(); - void Shutdown(); void Enable(); void Disable(); }; diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index d93bae983..9e0d7ec0d 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -38,6 +38,7 @@ typedef enum { TEXT_CARPET_SALESMAN_1 = 0x6077, TEXT_CARPET_SALESMAN_2 = 0x6078, TEXT_MARKET_GUARD_NIGHT = 0x7003, + TEXT_FISHERMAN_LEAVE = 0x409E, TEXT_SHEIK_NEED_HOOK = 0x700F, TEXT_SHEIK_HAVE_HOOK = 0x7010, TEXT_SCRUB_RANDOM = 0x9000, @@ -54,6 +55,22 @@ typedef enum { 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_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; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 88a23718e..ad51f1e4b 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -13,11 +13,15 @@ #define Path _Path #define PATH_HACK -#include +#include #include #include -#include +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include +#include #undef PATH_HACK #undef Path @@ -32,12 +36,12 @@ extern PlayState* gPlayState; #include #include -#define CMD_REGISTER LUS::Context::GetInstance()->GetConsole()->AddCommand +#define CMD_REGISTER Ship::Context::GetInstance()->GetConsole()->AddCommand // TODO: Commands should be using the output passed in. -#define ERROR_MESSAGE std::reinterpret_pointer_cast(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendErrorMessage -#define INFO_MESSAGE std::reinterpret_pointer_cast(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendInfoMessage +#define ERROR_MESSAGE std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendErrorMessage +#define INFO_MESSAGE std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendInfoMessage -static bool ActorSpawnHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ActorSpawnHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if ((args.size() != 9) && (args.size() != 3) && (args.size() != 6)) { ERROR_MESSAGE("Not enough arguments passed to actorspawn"); return 1; @@ -97,9 +101,9 @@ static bool ActorSpawnHandler(std::shared_ptr Console, const std:: return 0; } -static bool KillPlayerHandler(std::shared_ptr Console, const std::vector&, std::string* output) { +static bool KillPlayerHandler(std::shared_ptr Console, const std::vector&, std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth(); - effect->parameters[0] = 0; + dynamic_cast(effect)->parameters[0] = 0; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { INFO_MESSAGE("[SOH] You've met with a terrible fate, haven't you?"); @@ -110,7 +114,7 @@ static bool KillPlayerHandler(std::shared_ptr Console, const std:: } } -static bool SetPlayerHealthHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool SetPlayerHealthHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -130,7 +134,7 @@ static bool SetPlayerHealthHandler(std::shared_ptr Console, const } GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth(); - effect->parameters[0] = health; + dynamic_cast(effect)->parameters[0] = health; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { INFO_MESSAGE("[SOH] Player health updated to %d", health); @@ -141,7 +145,7 @@ static bool SetPlayerHealthHandler(std::shared_ptr Console, const } } -static bool LoadSceneHandler(std::shared_ptr Console, const std::vector&, std::string* output) { +static bool LoadSceneHandler(std::shared_ptr Console, const std::vector&, std::string* output) { gSaveContext.respawnFlag = 0; gSaveContext.seqId = 0xFF; gSaveContext.gameMode = 0; @@ -149,7 +153,7 @@ static bool LoadSceneHandler(std::shared_ptr Console, const std::v return 0; } -static bool RupeeHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool RupeeHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { return 1; } @@ -174,7 +178,7 @@ static bool RupeeHandler(std::shared_ptr Console, const std::vecto return 0; } -static bool SetPosHandler(std::shared_ptr Console, const std::vector args, std::string* output) { +static bool SetPosHandler(std::shared_ptr Console, const std::vector args, std::string* output) { if (gPlayState == nullptr) { ERROR_MESSAGE("PlayState == nullptr"); return 1; @@ -201,7 +205,7 @@ static bool SetPosHandler(std::shared_ptr Console, const std::vect return 0; } -static bool ResetHandler(std::shared_ptr Console, std::vector args, std::string* output) { +static bool ResetHandler(std::shared_ptr Console, std::vector args, std::string* output) { if (gPlayState == nullptr) { ERROR_MESSAGE("PlayState == nullptr"); return 1; @@ -221,7 +225,7 @@ const static std::map ammoItems{ { "beans", ITEM_BEAN } }; -static bool AddAmmoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool AddAmmoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -247,8 +251,8 @@ static bool AddAmmoHandler(std::shared_ptr Console, const std::vec } GameInteractionEffectBase* effect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->parameters[0] = amount; - effect->parameters[1] = it->second; + dynamic_cast(effect)->parameters[0] = amount; + dynamic_cast(effect)->parameters[1] = it->second; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -260,7 +264,7 @@ static bool AddAmmoHandler(std::shared_ptr Console, const std::vec } } -static bool TakeAmmoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool TakeAmmoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -287,8 +291,8 @@ static bool TakeAmmoHandler(std::shared_ptr Console, const std::ve } GameInteractionEffectBase* effect = new GameInteractionEffect::AddOrTakeAmmo(); - effect->parameters[0] = -amount; - effect->parameters[1] = it->second; + dynamic_cast(effect)->parameters[0] = -amount; + dynamic_cast(effect)->parameters[1] = it->second; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -307,7 +311,7 @@ const static std::map bottleItems{ { "big_poe", ITEM_BIG_POE }, { "blue_fire", ITEM_BLUE_FIRE }, { "rutos_letter", ITEM_LETTER_RUTO }, }; -static bool BottleHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BottleHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -339,7 +343,7 @@ static bool BottleHandler(std::shared_ptr Console, const std::vect return 0; } -static bool BHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -349,7 +353,7 @@ static bool BHandler(std::shared_ptr Console, const std::vector Console, const std::vector& args, std::string* output) { +static bool ItemHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -360,7 +364,7 @@ static bool ItemHandler(std::shared_ptr Console, const std::vector return 0; } -static bool GiveItemHandler(std::shared_ptr Console, const std::vector args, std::string* output) { +static bool GiveItemHandler(std::shared_ptr Console, const std::vector args, std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -381,7 +385,7 @@ static bool GiveItemHandler(std::shared_ptr Console, const std::ve return 0; } -static bool EntranceHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool EntranceHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -397,20 +401,20 @@ static bool EntranceHandler(std::shared_ptr Console, const std::ve } gPlayState->nextEntranceIndex = entrance; - gPlayState->sceneLoadFlag = 0x14; - gPlayState->fadeTransition = 11; - gSaveContext.nextTransitionType = 11; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_INSTANT; + gSaveContext.nextTransitionType = TRANS_TYPE_INSTANT; } -static bool VoidHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool VoidHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (gPlayState != nullptr) { gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwchFlags = gPlayState->actorCtx.flags.tempSwch; gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = gPlayState->actorCtx.flags.tempCollect; gSaveContext.respawnFlag = 1; - gPlayState->sceneLoadFlag = 0x14; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; gPlayState->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex; - gPlayState->fadeTransition = 2; - gSaveContext.nextTransitionType = 2; + gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; } else { ERROR_MESSAGE("gPlayState == nullptr"); return 1; @@ -418,12 +422,12 @@ static bool VoidHandler(std::shared_ptr Console, const std::vector return 0; } -static bool ReloadHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ReloadHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (gPlayState != nullptr) { gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; - gPlayState->sceneLoadFlag = 0x14; - gPlayState->fadeTransition = 11; - gSaveContext.nextTransitionType = 11; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_INSTANT; + gSaveContext.nextTransitionType = TRANS_TYPE_INSTANT; } else { ERROR_MESSAGE("gPlayState == nullptr"); return 1; @@ -435,7 +439,7 @@ const static std::map fw_options { { "clear", 0}, {"warp", 1}, {"backup", 2} }; -static bool FWHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool FWHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -457,9 +461,9 @@ static bool FWHandler(std::shared_ptr Console, const std::vector 0) { - gPlayState->sceneLoadFlag = 0x14; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; gPlayState->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_TOP].entranceIndex; - gPlayState->fadeTransition = 5; + gPlayState->transitionType = TRANS_TYPE_FADE_WHITE_FAST; } else { ERROR_MESSAGE("Farore's wind not set!"); return 1; @@ -467,7 +471,7 @@ static bool FWHandler(std::shared_ptr Console, const std::vector Console, const std::vector Console, const std::vector& args, std::string* output) { +static bool FileSelectHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (gPlayState != nullptr) { SET_NEXT_GAMESTATE(&gPlayState->state, FileChoose_Init, FileChooseContext); gPlayState->state.running = 0; @@ -498,12 +502,12 @@ static bool FileSelectHandler(std::shared_ptr Console, const std:: return 0; } -static bool QuitHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { - LUS::Context::GetInstance()->GetWindow()->Close(); +static bool QuitHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { + Ship::Context::GetInstance()->GetWindow()->Close(); return 0; } -static bool SaveStateHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool SaveStateHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::SAVE }); @@ -517,7 +521,7 @@ static bool SaveStateHandler(std::shared_ptr Console, const std::v } } -static bool LoadStateHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool LoadStateHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::LOAD }); @@ -538,7 +542,7 @@ static bool LoadStateHandler(std::shared_ptr Console, const std::v } -static bool StateSlotSelectHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool StateSlotSelectHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -563,7 +567,7 @@ static bool StateSlotSelectHandler(std::shared_ptr Console, const return 0; } -static bool InvisibleHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool InvisibleHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -577,7 +581,7 @@ static bool InvisibleHandler(std::shared_ptr Console, const std::v return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::InvisibleLink(); + RemovableGameInteractionEffect* effect = new GameInteractionEffect::InvisibleLink(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -590,7 +594,7 @@ static bool InvisibleHandler(std::shared_ptr Console, const std::v } } -static bool GiantLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GiantLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -604,8 +608,8 @@ static bool GiantLinkHandler(std::shared_ptr Console, const std::v return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize(); - effect->parameters[0] = GI_LINK_SIZE_GIANT; + RemovableGameInteractionEffect* effect = new GameInteractionEffect::ModifyLinkSize(); + dynamic_cast(effect)->parameters[0] = GI_LINK_SIZE_GIANT; GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -618,7 +622,7 @@ static bool GiantLinkHandler(std::shared_ptr Console, const std::v } } -static bool MinishLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool MinishLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -632,8 +636,8 @@ static bool MinishLinkHandler(std::shared_ptr Console, const std:: return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize(); - effect->parameters[0] = GI_LINK_SIZE_MINISH; + RemovableGameInteractionEffect* effect = new GameInteractionEffect::ModifyLinkSize(); + dynamic_cast(effect)->parameters[0] = GI_LINK_SIZE_MINISH; GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -646,7 +650,7 @@ static bool MinishLinkHandler(std::shared_ptr Console, const std:: } } -static bool AddHeartContainerHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool AddHeartContainerHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -666,7 +670,7 @@ static bool AddHeartContainerHandler(std::shared_ptr Console, cons } GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers(); - effect->parameters[0] = hearts; + dynamic_cast(effect)->parameters[0] = hearts; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { INFO_MESSAGE("[SOH] Added %d heart containers", hearts); @@ -677,7 +681,7 @@ static bool AddHeartContainerHandler(std::shared_ptr Console, cons } } -static bool RemoveHeartContainerHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool RemoveHeartContainerHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -697,7 +701,7 @@ static bool RemoveHeartContainerHandler(std::shared_ptr Console, c } GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers(); - effect->parameters[0] = -hearts; + dynamic_cast(effect)->parameters[0] = -hearts; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { INFO_MESSAGE("[SOH] Removed %d heart containers", hearts); @@ -708,7 +712,7 @@ static bool RemoveHeartContainerHandler(std::shared_ptr Console, c } } -static bool GravityHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GravityHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -717,7 +721,7 @@ static bool GravityHandler(std::shared_ptr Console, const std::vec GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyGravity(); try { - effect->parameters[0] = LUS::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY); + dynamic_cast(effect)->parameters[0] = Ship::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY); } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Gravity value must be a number."); return 1; @@ -733,7 +737,7 @@ static bool GravityHandler(std::shared_ptr Console, const std::vec } } -static bool NoUIHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool NoUIHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -747,7 +751,7 @@ static bool NoUIHandler(std::shared_ptr Console, const std::vector return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::NoUI(); + RemovableGameInteractionEffect* effect = new GameInteractionEffect::NoUI(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -761,7 +765,7 @@ static bool NoUIHandler(std::shared_ptr Console, const std::vector } } -static bool FreezeHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool FreezeHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::FreezePlayer(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -774,7 +778,7 @@ static bool FreezeHandler(std::shared_ptr Console, const std::vect } } -static bool DefenseModifierHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool DefenseModifierHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -782,7 +786,7 @@ static bool DefenseModifierHandler(std::shared_ptr Console, const GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyDefenseModifier(); try { - effect->parameters[0] = std::stoi(args[1], nullptr, 10); + dynamic_cast(effect)->parameters[0] = std::stoi(args[1], nullptr, 10); } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Defense modifier value must be a number."); return 1; @@ -790,7 +794,7 @@ static bool DefenseModifierHandler(std::shared_ptr Console, const GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { - INFO_MESSAGE("[SOH] Defense modifier set to %d", effect->parameters[0]); + INFO_MESSAGE("[SOH] Defense modifier set to %d", dynamic_cast(effect)->parameters[0]); return 0; } else { INFO_MESSAGE("[SOH] Command failed: Could not set defense modifier."); @@ -798,7 +802,7 @@ static bool DefenseModifierHandler(std::shared_ptr Console, const } } -static bool DamageHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool DamageHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -812,7 +816,7 @@ static bool DamageHandler(std::shared_ptr Console, const std::vect return 1; } - effect->parameters[0] = -value; + dynamic_cast(effect)->parameters[0] = -value; } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Damage value must be a number."); return 1; @@ -828,7 +832,7 @@ static bool DamageHandler(std::shared_ptr Console, const std::vect } } -static bool HealHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool HealHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -842,7 +846,7 @@ static bool HealHandler(std::shared_ptr Console, const std::vector return 1; } - effect->parameters[0] = value; + dynamic_cast(effect)->parameters[0] = value; } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Damage value must be a number."); return 1; @@ -858,7 +862,7 @@ static bool HealHandler(std::shared_ptr Console, const std::vector } } -static bool FillMagicHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool FillMagicHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::FillMagic(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -871,7 +875,7 @@ static bool FillMagicHandler(std::shared_ptr Console, const std::v } } -static bool EmptyMagicHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool EmptyMagicHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::EmptyMagic(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -884,7 +888,7 @@ static bool EmptyMagicHandler(std::shared_ptr Console, const std:: } } -static bool NoZHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool NoZHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -898,7 +902,7 @@ static bool NoZHandler(std::shared_ptr Console, const std::vector< return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::DisableZTargeting(); + RemovableGameInteractionEffect* effect = new GameInteractionEffect::DisableZTargeting(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -912,7 +916,7 @@ static bool NoZHandler(std::shared_ptr Console, const std::vector< } } -static bool OneHitKOHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool OneHitKOHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -926,7 +930,7 @@ static bool OneHitKOHandler(std::shared_ptr Console, const std::ve return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::OneHitKO(); + RemovableGameInteractionEffect* effect = new GameInteractionEffect::OneHitKO(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -940,7 +944,7 @@ static bool OneHitKOHandler(std::shared_ptr Console, const std::ve } } -static bool PacifistHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool PacifistHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -954,7 +958,7 @@ static bool PacifistHandler(std::shared_ptr Console, const std::ve return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::PacifistMode(); + RemovableGameInteractionEffect* effect = new GameInteractionEffect::PacifistMode(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -968,7 +972,7 @@ static bool PacifistHandler(std::shared_ptr Console, const std::ve } } -static bool PaperLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool PaperLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -982,8 +986,8 @@ static bool PaperLinkHandler(std::shared_ptr Console, const std::v return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize(); - effect->parameters[0] = GI_LINK_SIZE_PAPER; + RemovableGameInteractionEffect* effect = new GameInteractionEffect::ModifyLinkSize(); + dynamic_cast(effect)->parameters[0] = GI_LINK_SIZE_PAPER; GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -997,7 +1001,7 @@ static bool PaperLinkHandler(std::shared_ptr Console, const std::v } } -static bool RainstormHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool RainstormHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1011,7 +1015,7 @@ static bool RainstormHandler(std::shared_ptr Console, const std::v return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::WeatherRainstorm(); + RemovableGameInteractionEffect* effect = new GameInteractionEffect::WeatherRainstorm(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -1025,7 +1029,7 @@ static bool RainstormHandler(std::shared_ptr Console, const std::v } } -static bool ReverseControlsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ReverseControlsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1039,7 +1043,7 @@ static bool ReverseControlsHandler(std::shared_ptr Console, const return 1; } - GameInteractionEffectBase* effect = new GameInteractionEffect::ReverseControls(); + RemovableGameInteractionEffect* effect = new GameInteractionEffect::ReverseControls(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -1054,7 +1058,7 @@ static bool ReverseControlsHandler(std::shared_ptr Console, const } } -static bool UpdateRupeesHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool UpdateRupeesHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1062,7 +1066,7 @@ static bool UpdateRupeesHandler(std::shared_ptr Console, const std GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRupees(); try { - effect->parameters[0] = std::stoi(args[1], nullptr, 10); + dynamic_cast(effect)->parameters[0] = std::stoi(args[1], nullptr, 10); } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Rupee value must be a number."); return 1; @@ -1078,7 +1082,7 @@ static bool UpdateRupeesHandler(std::shared_ptr Console, const std } } -static bool SpeedModifierHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool SpeedModifierHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1086,7 +1090,7 @@ static bool SpeedModifierHandler(std::shared_ptr Console, const st GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRunSpeedModifier(); try { - effect->parameters[0] = std::stoi(args[1], nullptr, 10); + dynamic_cast(effect)->parameters[0] = std::stoi(args[1], nullptr, 10); } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Speed modifier value must be a number."); return 1; @@ -1108,7 +1112,7 @@ const static std::map boots { { "hover", EQUIP_VALUE_BOOTS_HOVER }, }; -static bool BootsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BootsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1121,7 +1125,7 @@ static bool BootsHandler(std::shared_ptr Console, const std::vecto } GameInteractionEffectBase* effect = new GameInteractionEffect::ForceEquipBoots(); - effect->parameters[0] = it->second; + dynamic_cast(effect)->parameters[0] = it->second; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -1139,7 +1143,7 @@ const static std::map shields { { "mirror", ITEM_SHIELD_MIRROR }, }; -static bool GiveShieldHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GiveShieldHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1152,7 +1156,7 @@ static bool GiveShieldHandler(std::shared_ptr Console, const std:: } GameInteractionEffectBase* effect = new GameInteractionEffect::GiveOrTakeShield(); - effect->parameters[0] = it->second; + dynamic_cast(effect)->parameters[0] = it->second; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -1164,7 +1168,7 @@ static bool GiveShieldHandler(std::shared_ptr Console, const std:: } } -static bool TakeShieldHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool TakeShieldHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1177,7 +1181,7 @@ static bool TakeShieldHandler(std::shared_ptr Console, const std:: } GameInteractionEffectBase* effect = new GameInteractionEffect::GiveOrTakeShield(); - effect->parameters[0] = it->second * -1; + dynamic_cast(effect)->parameters[0] = it->second * -1; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { @@ -1189,7 +1193,7 @@ static bool TakeShieldHandler(std::shared_ptr Console, const std:: } } -static bool KnockbackHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool KnockbackHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1203,7 +1207,7 @@ static bool KnockbackHandler(std::shared_ptr Console, const std::v return 1; } - effect->parameters[0] = value; + dynamic_cast(effect)->parameters[0] = value; } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Knockback value must be a number."); return 1; @@ -1219,7 +1223,7 @@ static bool KnockbackHandler(std::shared_ptr Console, const std::v } } -static bool ElectrocuteHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ElectrocuteHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::ElectrocutePlayer(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -1232,7 +1236,7 @@ static bool ElectrocuteHandler(std::shared_ptr Console, const std: } } -static bool BurnHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BurnHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::BurnPlayer(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -1245,7 +1249,7 @@ static bool BurnHandler(std::shared_ptr Console, const std::vector } } -static bool CuccoStormHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool CuccoStormHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { GameInteractionEffectQueryResult result = GameInteractor::RawAction::SpawnActor(ACTOR_EN_NIW, 0); if (result == GameInteractionEffectQueryResult::Possible) { @@ -1257,7 +1261,7 @@ static bool CuccoStormHandler(std::shared_ptr Console, const std:: } } -static bool GenerateRandoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GenerateRandoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() == 1) { if (GenerateRandomizer()) { return 0; @@ -1285,16 +1289,58 @@ static bool GenerateRandoHandler(std::shared_ptr Console, const st return 1; } -static bool CosmeticsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static constexpr std::array, COSMETICS_GROUP_MAX> cosmetic_groups = {{ + {"link", COSMETICS_GROUP_LINK}, + {"mirror_shield", COSMETICS_GROUP_MIRRORSHIELD}, + {"swords", COSMETICS_GROUP_SWORDS}, + {"gloves", COSMETICS_GROUP_GLOVES}, + {"equipment", COSMETICS_GROUP_EQUIPMENT}, + {"consumable", COSMETICS_GROUP_CONSUMABLE}, + {"hud", COSMETICS_GROUP_HUD}, + {"kaleido", COSMETICS_GROUP_KALEIDO}, + {"title", COSMETICS_GROUP_TITLE}, + {"npc", COSMETICS_GROUP_NPC}, + {"world", COSMETICS_GROUP_WORLD}, + {"magic", COSMETICS_GROUP_MAGIC}, + {"arrows", COSMETICS_GROUP_ARROWS}, + {"spin_attack", COSMETICS_GROUP_SPIN_ATTACK}, + {"trials", COSMETICS_GROUP_TRAILS}, + {"navi", COSMETICS_GROUP_NAVI}, + {"ivan", COSMETICS_GROUP_IVAN}, +}}; + +static bool CosmeticsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; } if (args[1].compare("reset") == 0) { - CosmeticsEditor_ResetAll(); + if (args.size() == 2) { + CosmeticsEditor_ResetAll(); + } else { + for (const auto& [key, value] : cosmetic_groups) { + if (args[2].compare(key) == 0) { + CosmeticsEditor_ResetGroup(value); + return 0; + } + } + ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name"); + return 1; + } } else if (args[1].compare("randomize") == 0) { - CosmeticsEditor_RandomizeAll(); + if (args.size() == 2) { + CosmeticsEditor_RandomizeAll(); + } else { + for (const auto& [key, value] : cosmetic_groups) { + if (args[2].compare(key) == 0) { + CosmeticsEditor_RandomizeGroup(value); + return 0; + } + } + ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name"); + return 1; + } } else { ERROR_MESSAGE("[SOH] Invalid argument passed, must be 'reset' or 'randomize'"); return 1; @@ -1303,16 +1349,50 @@ static bool CosmeticsHandler(std::shared_ptr Console, const std::v return 0; } -static bool SfxHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static std::map sfx_groups = { + {"bgm", SEQ_BGM_WORLD}, + {"fanfares", SEQ_FANFARE}, + {"events", SEQ_BGM_EVENT}, + {"battle", SEQ_BGM_BATTLE}, + {"ocarina", SEQ_OCARINA}, + {"instruments", SEQ_INSTRUMENT}, + {"sfx", SEQ_SFX}, + {"voices", SEQ_VOICE}, + {"custom", SEQ_BGM_CUSTOM}, +}; + +static bool SfxHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; } if (args[1].compare("reset") == 0) { - AudioEditor_ResetAll(); + if (args.size() == 2) { + AudioEditor_ResetAll(); + } else { + for (const auto& [key, value] : sfx_groups) { + if (args[2].compare(key) == 0) { + AudioEditor_ResetGroup(value); + return 0; + } + } + ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name"); + return 1; + } } else if (args[1].compare("randomize") == 0) { - AudioEditor_RandomizeAll(); + if (args.size() == 2) { + AudioEditor_RandomizeAll(); + } else { + for (const auto& [key, value] : sfx_groups) { + if (args[2].compare(key) == 0) { + AudioEditor_RandomizeGroup(value); + return 0; + } + } + ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name"); + return 1; + } } else { ERROR_MESSAGE("[SOH] Invalid argument passed, must be 'reset' or 'randomize'"); return 1; @@ -1331,17 +1411,17 @@ void DebugConsole_Init(void) { CMD_REGISTER("save_state", {SaveStateHandler, "Save a state."}); CMD_REGISTER("load_state", {LoadStateHandler, "Load a state."}); CMD_REGISTER("set_slot", {StateSlotSelectHandler, "Selects a SaveState slot", { - {"Slot number", LUS::ArgumentType::NUMBER,} + {"Slot number", Ship::ArgumentType::NUMBER,} }}); // Map & Location CMD_REGISTER("void", {VoidHandler, "Voids out of the current map."}); CMD_REGISTER("reload", {ReloadHandler, "Reloads the current map."}); CMD_REGISTER("fw", {FWHandler, "Spawns the player where Farore's Wind is set.", { - {"clear|warp|backup", LUS::ArgumentType::TEXT} + {"clear|warp|backup", Ship::ArgumentType::TEXT} }}); CMD_REGISTER("entrance", {EntranceHandler, "Sends player to the entered entrance (hex)", { - {"entrance", LUS::ArgumentType::NUMBER} + {"entrance", Ship::ArgumentType::NUMBER} }}); // Gameplay @@ -1350,64 +1430,64 @@ void DebugConsole_Init(void) { CMD_REGISTER("map", {LoadSceneHandler, "Load up kak?"}); CMD_REGISTER("rupee", {RupeeHandler, "Set your rupee counter.", { - {"amount", LUS::ArgumentType::NUMBER} + {"amount", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("bItem", {BHandler, "Set an item to the B button.", { - {"Item ID", LUS::ArgumentType::NUMBER} + {"Item ID", Ship::ArgumentType::NUMBER} }}); - CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor name/id", LUS::ArgumentType::NUMBER }, // TODO there should be an actor_id arg type - {"data", LUS::ArgumentType::NUMBER}, - {"x", LUS::ArgumentType::NUMBER, true}, - {"y", LUS::ArgumentType::NUMBER, true}, - {"z", LUS::ArgumentType::NUMBER, true}, - {"rx", LUS::ArgumentType::NUMBER, true}, - {"ry", LUS::ArgumentType::NUMBER, true}, - {"rz", LUS::ArgumentType::NUMBER, true} + CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor name/id", Ship::ArgumentType::NUMBER }, // TODO there should be an actor_id arg type + {"data", Ship::ArgumentType::NUMBER}, + {"x", Ship::ArgumentType::NUMBER, true}, + {"y", Ship::ArgumentType::NUMBER, true}, + {"z", Ship::ArgumentType::NUMBER, true}, + {"rx", Ship::ArgumentType::NUMBER, true}, + {"ry", Ship::ArgumentType::NUMBER, true}, + {"rz", Ship::ArgumentType::NUMBER, true} }}); CMD_REGISTER("pos", {SetPosHandler, "Sets the position of the player.", { - {"x", LUS::ArgumentType::NUMBER, true}, - {"y", LUS::ArgumentType::NUMBER, true}, - {"z", LUS::ArgumentType::NUMBER, true} + {"x", Ship::ArgumentType::NUMBER, true}, + {"y", Ship::ArgumentType::NUMBER, true}, + {"z", Ship::ArgumentType::NUMBER, true} }}); CMD_REGISTER("addammo", {AddAmmoHandler, "Adds ammo of an item.", { - {"sticks|nuts|bombs|seeds|arrows|bombchus|beans", LUS::ArgumentType::TEXT}, - {"count", LUS::ArgumentType::NUMBER} + {"sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT}, + {"count", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("takeammo", {TakeAmmoHandler, "Removes ammo of an item.", { - {"sticks|nuts|bombs|seeds|arrows|bombchus|beans", LUS::ArgumentType::TEXT}, - {"count", LUS::ArgumentType::NUMBER} + {"sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT}, + {"count", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("bottle", {BottleHandler, "Changes item in a bottle slot.", { - {"item", LUS::ArgumentType::TEXT}, - {"slot", LUS::ArgumentType::NUMBER} + {"item", Ship::ArgumentType::TEXT}, + {"slot", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("give_item", {GiveItemHandler, "Gives an item to the player as if it was given from an actor", { - {"vanilla|randomizer", LUS::ArgumentType::TEXT}, - {"giveItemID", LUS::ArgumentType::NUMBER} + {"vanilla|randomizer", Ship::ArgumentType::TEXT}, + {"giveItemID", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("item", {ItemHandler, "Sets item ID in arg 1 into slot arg 2. No boundary checks. Use with caution.", { - {"slot", LUS::ArgumentType::NUMBER}, - {"item id", LUS::ArgumentType::NUMBER} + {"slot", Ship::ArgumentType::NUMBER}, + {"item id", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("invisible", {InvisibleHandler, "Activate Link's Elvish cloak, making him appear invisible.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("giant_link", {GiantLinkHandler, "Turn Link into a giant Lonky boi.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("minish_link", {MinishLinkHandler, "Turn Link into a minish boi.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("add_heart_container", @@ -1417,25 +1497,25 @@ void DebugConsole_Init(void) { {RemoveHeartContainerHandler, "Remove a heart from Link. The minimal amount of hearts is 3."}); CMD_REGISTER("gravity", {GravityHandler, "Set gravity level.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("no_ui", {NoUIHandler, "Disables the UI.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("freeze", {FreezeHandler, "Freezes Link in place"}); CMD_REGISTER("defense_modifier", {DefenseModifierHandler, "Sets the defense modifier.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("damage", {DamageHandler, "Deal damage to Link.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("heal", {HealHandler, "Heals Link.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("fill_magic", {FillMagicHandler, "Fills magic."}); @@ -1443,50 +1523,50 @@ void DebugConsole_Init(void) { CMD_REGISTER("empty_magic", {EmptyMagicHandler, "Empties magic."}); CMD_REGISTER("no_z", {NoZHandler, "Disables Z-button presses.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("ohko", {OneHitKOHandler, "Activates one hit KO. Any damage kills Link and he cannot gain health in this mode.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("pacifist", {PacifistHandler, "Activates pacifist mode. Prevents Link from using his weapon.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("paper_link", {PaperLinkHandler, "Link but made out of paper.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("rainstorm", {RainstormHandler, "Activates rainstorm."}); CMD_REGISTER("reverse_controls", {ReverseControlsHandler, "Reverses the controls.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("update_rupees", {UpdateRupeesHandler, "Adds rupees.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("speed_modifier", {SpeedModifierHandler, "Sets the speed modifier.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("boots", {BootsHandler, "Activates boots.", { - {"kokiri|iron|hover", LUS::ArgumentType::TEXT}, + {"kokiri|iron|hover", Ship::ArgumentType::TEXT}, }}); CMD_REGISTER("giveshield", {GiveShieldHandler, "Gives a shield and equips it when Link is the right age for it.", { - {"deku|hylian|mirror", LUS::ArgumentType::TEXT}, + {"deku|hylian|mirror", Ship::ArgumentType::TEXT}, }}); CMD_REGISTER("takeshield", {TakeShieldHandler, "Takes a shield and unequips it if Link is wearing it.", { - {"deku|hylian|mirror", LUS::ArgumentType::TEXT}, + {"deku|hylian|mirror", Ship::ArgumentType::TEXT}, }}); CMD_REGISTER("knockback", {KnockbackHandler, "Knocks Link back.", { - {"value", LUS::ArgumentType::NUMBER} + {"value", Ship::ArgumentType::NUMBER} }}); CMD_REGISTER("electrocute", {ElectrocuteHandler, "Electrocutes Link."}); @@ -1496,16 +1576,18 @@ void DebugConsole_Init(void) { CMD_REGISTER("cucco_storm", {CuccoStormHandler, "Cucco Storm"}); CMD_REGISTER("gen_rando", {GenerateRandoHandler, "Generate a randomizer seed", { - {"seed|count", LUS::ArgumentType::NUMBER, true}, - {"testing", LUS::ArgumentType::NUMBER, true}, + {"seed|count", Ship::ArgumentType::NUMBER, true}, + {"testing", Ship::ArgumentType::NUMBER, true}, }}); CMD_REGISTER("cosmetics", {CosmeticsHandler, "Change cosmetics.", { - {"reset|randomize", LUS::ArgumentType::TEXT}, + {"reset|randomize", Ship::ArgumentType::TEXT}, + {"group name", Ship::ArgumentType::TEXT, true}, }}); CMD_REGISTER("sfx", {SfxHandler, "Change SFX.", { - {"reset|randomize", LUS::ArgumentType::TEXT}, + {"reset|randomize", Ship::ArgumentType::TEXT}, + {"group_name", Ship::ArgumentType::TEXT, true}, }}); CVarSave(); diff --git a/soh/soh/Enhancements/debugger/MessageViewer.cpp b/soh/soh/Enhancements/debugger/MessageViewer.cpp new file mode 100644 index 000000000..a9a6b613e --- /dev/null +++ b/soh/soh/Enhancements/debugger/MessageViewer.cpp @@ -0,0 +1,271 @@ +#include "MessageViewer.h" + +#include +#include + +#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(calloc(MAX_STRING_SIZE, sizeof(char))); + mTextIdBuf = static_cast(calloc(MAX_STRING_SIZE, sizeof(char))); + mCustomMessageBuf = static_cast(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(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(&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(font->msgLength); + const uintptr_t src = font->msgOffset; + memcpy(font->msgBuf, reinterpret_cast(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(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); +} + + diff --git a/soh/soh/Enhancements/debugger/MessageViewer.h b/soh/soh/Enhancements/debugger/MessageViewer.h new file mode 100644 index 000000000..43ae55aa7 --- /dev/null +++ b/soh/soh/Enhancements/debugger/MessageViewer.h @@ -0,0 +1,62 @@ +#ifndef CUSTOMMESSAGEDEBUGGER_H +#define CUSTOMMESSAGEDEBUGGER_H +#include "z64.h" + +#ifdef __cplusplus +#include "GuiWindow.h" +#include +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 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 diff --git a/soh/soh/Enhancements/debugger/actorViewer.cpp b/soh/soh/Enhancements/debugger/actorViewer.cpp index f83449efe..3e4d271a8 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.cpp +++ b/soh/soh/Enhancements/debugger/actorViewer.cpp @@ -8,9 +8,11 @@ #include #include #include +#include #include #include #include +#include "soh/OTRGlobals.h" extern "C" { #include @@ -24,6 +26,7 @@ extern PlayState* gPlayState; #include "textures/icon_item_24_static/icon_item_24_static.h" } +#define DEKUNUTS_FLOWER 10 #define DEBUG_ACTOR_NAMETAG_TAG "debug_actor_viewer" typedef struct { @@ -107,8 +110,785 @@ void PopulateActorDropdown(int i, std::vector& data) { } } +//actors that don't use params at all +static std::vector 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> 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 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 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) { - 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); std::string tag; @@ -163,6 +943,9 @@ void ActorViewerWindow::DrawElement() { static std::string filler = "Please select"; static std::vector list; static u16 lastSceneId = 0; + static char searchString[64] = ""; + static s16 currentSelectedInDropdown; + static std::vector actors; if (gPlayState != nullptr) { needs_reset = lastSceneId != gPlayState->sceneNum; @@ -173,6 +956,11 @@ void ActorViewerWindow::DrawElement() { filler = "Please Select"; list.clear(); needs_reset = false; + for (size_t i = 0; i < ARRAY_COUNT(searchString); i += 1) { + searchString[i] = 0; + } + currentSelectedInDropdown = -1; + actors.clear(); } lastSceneId = gPlayState->sceneNum; if (ImGui::BeginCombo("Actor Type", acMapping[category])) { @@ -316,9 +1104,48 @@ void ActorViewerWindow::DrawElement() { if (ImGui::TreeNode("New...")) { 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::InputScalar("ID", ImGuiDataType_S16, &newActor.id, &one); - ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &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); + } 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); @@ -388,7 +1215,7 @@ void ActorViewerWindow::DrawElement() { UIWidgets::Spacer(0); 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); ActorViewer_AddTagForAllActors(); } @@ -401,6 +1228,11 @@ void ActorViewerWindow::DrawElement() { filler = "Please Select"; list.clear(); needs_reset = false; + for (size_t i = 0; i < ARRAY_COUNT(searchString); i += 1) { + searchString[i] = 0; + } + currentSelectedInDropdown = -1; + actors.clear(); } } diff --git a/soh/soh/Enhancements/debugger/actorViewer.h b/soh/soh/Enhancements/debugger/actorViewer.h index 6eceaa92d..2f4ca680a 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.h +++ b/soh/soh/Enhancements/debugger/actorViewer.h @@ -2,7 +2,7 @@ #include -class ActorViewerWindow : public LUS::GuiWindow { +class ActorViewerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index 135dcb0f0..159e27128 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "soh/OTRGlobals.h" extern "C" { #include @@ -57,17 +58,17 @@ void ColViewerWindow::DrawElement() { ImGui::End(); return; } - UIWidgets::EnhancementCheckbox("Enabled", "gColViewerEnabled"); + UIWidgets::EnhancementCheckbox("Enabled", CVAR_DEVELOPER_TOOLS("ColViewer.Enabled")); - UIWidgets::LabeledRightAlignedEnhancementCombobox("Scene", "gColViewerScene", ColRenderSettingNames, COLVIEW_DISABLED); - UIWidgets::LabeledRightAlignedEnhancementCombobox("Bg Actors", "gColViewerBgActors", ColRenderSettingNames, COLVIEW_DISABLED); - UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", "gColViewerColCheck", ColRenderSettingNames, COLVIEW_DISABLED); - UIWidgets::LabeledRightAlignedEnhancementCombobox("Waterbox", "gColViewerWaterbox", ColRenderSettingNames, COLVIEW_DISABLED); + UIWidgets::LabeledRightAlignedEnhancementCombobox("Scene", CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), ColRenderSettingNames, COLVIEW_DISABLED); + UIWidgets::LabeledRightAlignedEnhancementCombobox("Bg Actors", CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), ColRenderSettingNames, COLVIEW_DISABLED); + UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), 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 " "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."); // 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")) { UIWidgets::InsertHelpHoverText(colorHelpText); - UIWidgets::EnhancementColor("Normal", "gColViewerColorNormal", scene_col, ImVec4(255, 255, 255, 255), false); - UIWidgets::EnhancementColor("Hookshot", "gColViewerColorHookshot", hookshot_col, ImVec4(128, 128, 255, 255), + UIWidgets::EnhancementColor("Normal", CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), scene_col, ImVec4(255, 255, 255, 255), false); + UIWidgets::EnhancementColor("Hookshot", CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), hookshot_col, ImVec4(128, 128, 255, 255), false); - UIWidgets::EnhancementColor("Entrance", "gColViewerColorEntrance", entrance_col, ImVec4(0, 255, 0, 255), false); - UIWidgets::EnhancementColor("Special Surface (Grass/Sand/Etc)", "gColViewerColorSpecialSurface", + UIWidgets::EnhancementColor("Entrance", CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), entrance_col, ImVec4(0, 255, 0, 255), false); + UIWidgets::EnhancementColor("Special Surface (Grass/Sand/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), 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); - UIWidgets::EnhancementColor("Slope", "gColViewerColorSlope", slope_col, ImVec4(255, 255, 128, 255), false); - UIWidgets::EnhancementColor("Void", "gColViewerColorVoid", void_col, ImVec4(255, 0, 0, 255), false); - UIWidgets::EnhancementColor("OC", "gColViewerColorOC", oc_col, ImVec4(255, 255, 255, 255), false); - UIWidgets::EnhancementColor("AC", "gColViewerColorAC", ac_col, ImVec4(0, 0, 255, 255), false); - UIWidgets::EnhancementColor("AT", "gColViewerColorAT", at_col, ImVec4(255, 0, 0, 255), false); - UIWidgets::EnhancementColor("Waterbox", "gColViewerColorWaterbox", waterbox_col, ImVec4(0, 0, 255, 255), false); + UIWidgets::EnhancementColor("Slope", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), slope_col, ImVec4(255, 255, 128, 255), false); + UIWidgets::EnhancementColor("Void", CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), void_col, ImVec4(255, 0, 0, 255), false); + UIWidgets::EnhancementColor("OC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), oc_col, ImVec4(255, 255, 255, 255), false); + UIWidgets::EnhancementColor("AC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), ac_col, ImVec4(0, 0, 255, 255), false); + UIWidgets::EnhancementColor("AT", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), at_col, ImVec4(255, 0, 0, 255), false); + UIWidgets::EnhancementColor("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), waterbox_col, ImVec4(0, 0, 255, 255), false); ImGui::TreePop(); } else { @@ -308,7 +309,7 @@ void InitGfx(std::vector& gfx, ColRenderSetting setting) { alpha = 0xFF; } - if (CVarGetInteger("gColViewerDecal", 0) != 0) { + if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), 0) != 0) { rm |= ZMODE_DEC; } else if (setting == ColRenderSetting::Transparent) { rm |= ZMODE_XLU; @@ -320,7 +321,7 @@ void InitGfx(std::vector& gfx, ColRenderSetting setting) { gfx.push_back(gsDPSetCycleType(G_CYC_1CYCLE)); 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(gsSPLoadGeometryMode(G_CULL_BACK | G_ZBUFFER | G_LIGHTING)); } else { @@ -333,16 +334,13 @@ void InitGfx(std::vector& gfx, ColRenderSetting setting) { // Draws a dynapoly structure (scenes or Bg Actors) void DrawDynapoly(std::vector& dl, CollisionHeader* col, int32_t bgId) { - uint32_t colorR = CVarGetInteger("gColViewerColorNormalR", 255); - uint32_t colorG = CVarGetInteger("gColViewerColorNormalG", 255); - uint32_t colorB = CVarGetInteger("gColViewerColorNormalB", 255); - uint32_t colorA = 255; + Color_RGBA8 color = {255, 255, 255, 255}; - uint32_t lastColorR = colorR; - uint32_t lastColorG = colorG; - uint32_t lastColorB = colorB; + uint32_t lastColorR = color.r; + uint32_t lastColorG = color.g; + 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 saves several hundred commands in larger scenes @@ -352,49 +350,35 @@ void DrawDynapoly(std::vector& dl, CollisionHeader* col, int32_t bgId) { CollisionPoly* poly = &col->polyList[i]; if (SurfaceType_IsHookshotSurface(&gPlayState->colCtx, poly, bgId)) { - colorR = CVarGetInteger("gColViewerColorHookshotR", 128); - colorG = CVarGetInteger("gColViewerColorHookshotG", 128); - colorB = CVarGetInteger("gColViewerColorHookshotB", 255); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), { 128, 128, 255, 255 }); } else if (func_80041D94(&gPlayState->colCtx, poly, bgId) > 0x01) { - colorR = CVarGetInteger("gColViewerColorInteractableR", 192); - colorG = CVarGetInteger("gColViewerColorInteractableG", 0); - colorB = CVarGetInteger("gColViewerColorInteractableB", 192); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"), {192, 0, 192, 255}); } else if (func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x0C) { - colorR = CVarGetInteger("gColViewerColorVoidR", 255); - colorG = CVarGetInteger("gColViewerColorVoidG", 0); - colorB = CVarGetInteger("gColViewerColorVoidB", 0); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), { 255, 0, 0, 255 }); } else if (SurfaceType_GetSceneExitIndex(&gPlayState->colCtx, poly, bgId) || func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x05) { - colorR = CVarGetInteger("gColViewerColorEntranceR", 0); - colorG = CVarGetInteger("gColViewerColorEntranceG", 255); - colorB = CVarGetInteger("gColViewerColorEntranceB", 0); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), { 0, 255, 0, 255 }); } else if (func_80041D4C(&gPlayState->colCtx, poly, bgId) != 0 || SurfaceType_IsWallDamage(&gPlayState->colCtx, poly, bgId)) { - colorR = CVarGetInteger("gColViewerColorSpecialSurfaceR", 192); - colorG = CVarGetInteger("gColViewerColorSpecialSurfaceG", 255); - colorB = CVarGetInteger("gColViewerColorSpecialSurfaceB", 192); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), { 192, 255, 192, 255 }); } else if (SurfaceType_GetSlope(&gPlayState->colCtx, poly, bgId) == 0x01) { - colorR = CVarGetInteger("gColViewerColorSlopeR", 255); - colorG = CVarGetInteger("gColViewerColorSlopeG", 255); - colorB = CVarGetInteger("gColViewerColorSlopeB", 128); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), { 255, 255, 128, 255 }); } else { - colorR = CVarGetInteger("gColViewerColorNormalR", 255); - colorG = CVarGetInteger("gColViewerColorNormalG", 255); - colorB = CVarGetInteger("gColViewerColorNormalB", 255); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), { 255, 255, 255, 255 }); } - if (colorR != lastColorR || colorG != lastColorG || colorB != lastColorB) { + if (color.r != lastColorR || color.g != lastColorG || color.b != lastColorB) { // Color changed, flush previous poly if (previousPoly) { dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0)); dl.push_back(gsSP1Triangle(0, 1, 2, 0)); 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; - lastColorG = colorG; - lastColorB = colorB; + lastColorR = color.r; + lastColorG = color.g; + lastColorB = color.b; Vec3s* va = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)]; Vec3s* vb = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)]; @@ -428,9 +412,9 @@ void DrawDynapoly(std::vector& dl, CollisionHeader* col, int32_t bgId) { // Draws the scene 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; } @@ -443,8 +427,8 @@ void DrawSceneCollision() { // Draws all Bg Actors void DrawBgActorCollision() { - ColRenderSetting showBgActorSetting = (ColRenderSetting)CVarGetInteger("gColViewerBgActors", COLVIEW_DISABLED); - if (showBgActorSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) { + ColRenderSetting showBgActorSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_DISABLED); + if (showBgActorSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) { return; } @@ -568,8 +552,8 @@ void DrawColCheckList(std::vector& dl, Collider** objects, int32_t count) { // Draws all Col Check objects void DrawColCheckCollision() { - ColRenderSetting showColCheckSetting = (ColRenderSetting)CVarGetInteger("gColViewerColCheck", COLVIEW_DISABLED); - if (showColCheckSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) { + ColRenderSetting showColCheckSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_DISABLED); + if (showColCheckSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) { return; } @@ -578,15 +562,14 @@ void DrawColCheckCollision() { dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); CollisionCheckContext& col = gPlayState->colChkCtx; - - dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorOCR", 255), CVarGetInteger("gColViewerColorOCG", 255), - CVarGetInteger("gColViewerColorOCB", 255), 255)); + Color_RGBA8 color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), { 255, 255, 255, 255 }); + dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); DrawColCheckList(dl, col.colOC, col.colOCCount); - dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorACR", 0), CVarGetInteger("gColViewerColorACG", 0), - CVarGetInteger("gColViewerColorACB", 255), 255)); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), { 0, 0, 255, 255 }); + dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); DrawColCheckList(dl, col.colAC, col.colACCount); - dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorATR", 255), CVarGetInteger("gColViewerColorATG", 0), - CVarGetInteger("gColViewerColorATB", 0), 255)); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), { 0, 0, 255, 255 }); + dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); DrawColCheckList(dl, col.colAT, col.colATCount); } @@ -621,8 +604,8 @@ extern "C" f32 zdWaterBoxMinY; // Draws all waterboxes void DrawWaterboxList() { - ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVarGetInteger("gColViewerWaterbox", COLVIEW_DISABLED); - if (showWaterboxSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) { + ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_DISABLED); + if (showWaterboxSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) { return; } @@ -630,9 +613,9 @@ void DrawWaterboxList() { InitGfx(dl, showWaterboxSetting); dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); - dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorWaterboxR", 0), - CVarGetInteger("gColViewerColorWaterboxG", 0), - CVarGetInteger("gColViewerColorWaterboxB", 255), 255)); + Color_RGBA8 color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), { 0, 0, 255, 255 }); + + dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); CollisionHeader* col = gPlayState->colCtx.colHeader; for (int32_t waterboxIndex = 0; waterboxIndex < col->numWaterBoxes; waterboxIndex++) { @@ -693,7 +676,7 @@ extern "C" void DrawColViewer() { 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 if (mirroredWorld) { gSPSetExtraGeometryMode(POLY_OPA_DISP++, G_EX_INVERT_CULLING); diff --git a/soh/soh/Enhancements/debugger/colViewer.h b/soh/soh/Enhancements/debugger/colViewer.h index 98f0b6f0a..5252bc950 100644 --- a/soh/soh/Enhancements/debugger/colViewer.h +++ b/soh/soh/Enhancements/debugger/colViewer.h @@ -14,7 +14,7 @@ typedef enum { } ColViewerRenderSetting; #ifdef __cplusplus -class ColViewerWindow : public LUS::GuiWindow { +class ColViewerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 9af4eadb7..216e0e12f 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -515,7 +515,7 @@ void DrawInfoTab() { UIWidgets::InsertHelpHoverText("Z-Targeting behavior"); 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."); } @@ -614,7 +614,7 @@ void DrawInfoTab() { void DrawBGSItemFlag(uint8_t 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(); int tradeIndex = itemID - ITEM_POCKET_EGG; bool hasItem = (gSaveContext.adultTradeItems & (1 << tradeIndex)) != 0; @@ -656,7 +656,7 @@ void DrawInventoryTab() { uint8_t item = gSaveContext.inventory.items[index]; if (item != ITEM_NONE) { 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)) { selectedIndex = index; ImGui::OpenPopup(itemPopupPicker); @@ -704,7 +704,7 @@ void DrawInventoryTab() { ImGui::SameLine(); } 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)) { gSaveContext.inventory.items[selectedIndex] = slotEntry.id; // 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::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::EndGroup(); @@ -1157,7 +1157,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const uint8_t item = items[CUR_UPG_VALUE(categoryId)]; if (item != ITEM_NONE) { 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)) { ImGui::OpenPopup(upgradePopupPicker); } @@ -1185,7 +1185,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const UIWidgets::SetLastItemHoverText("None"); } else { 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)) { Inventory_ChangeUpgrade(categoryId, pickerIndex); ImGui::CloseCurrentPopup(); @@ -1222,7 +1222,7 @@ void DrawEquipmentTab() { bool hasEquip = (bitMask & gSaveContext.inventory.equipment) != 0; const ItemMapEntry& entry = itemMapping[equipmentValues[i]]; 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)) { if (hasEquip) { gSaveContext.inventory.equipment &= ~bitMask; @@ -1321,7 +1321,7 @@ void DrawQuestItemButton(uint32_t item) { uint32_t bitMask = 1 << entry.id; bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 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)) { if (hasQuestItem) { 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 bool hasItem = (bitMask & gSaveContext.inventory.dungeonItems[scene]) != 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)) { if (hasItem) { gSaveContext.inventory.dungeonItems[scene] &= ~bitMask; @@ -1386,7 +1386,7 @@ void DrawQuestStatusTab() { uint32_t bitMask = 1 << entry.id; bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 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)) { if (hasQuestItem) { gSaveContext.inventory.questItems &= ~bitMask; @@ -1449,7 +1449,7 @@ void DrawQuestStatusTab() { if (dungeonItemsScene != SCENE_JABU_JABU_BOSS) { 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(); if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, 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); 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"); ImGui::InputScalar("Invincibility Timer", ImGuiDataType_S8, &player->invincibilityTimer); @@ -1705,7 +1705,7 @@ void DrawPlayerTab() { ImGui::SameLine(); 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::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 @@ -1793,34 +1793,34 @@ void SaveEditorWindow::DrawElement() { void SaveEditorWindow::InitElement() { // Load item icons into ImGui for (const auto& entry : itemMapping) { - LUS::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.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } for (const auto& entry : gregMapping) { ImVec4 gregGreen = ImVec4(42.0f / 255.0f, 169.0f / 255.0f, 40.0f / 255.0f, 1.0f); ImVec4 gregFadedGreen = gregGreen; gregFadedGreen.w = 0.3f; - LUS::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.name, entry.second.texturePath, gregGreen); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen); } for (const auto& entry : triforcePieceMapping) { - LUS::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.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } for (const auto& entry : questMapping) { - LUS::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.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } 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; 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) { - 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; fadedCol.w = 0.3f; - LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol); } } diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 42c9c91c0..1de852e35 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -505,6 +505,7 @@ const std::vector flagTables = { { RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" }, { RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" }, { RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" }, + { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" }, } }, }; @@ -589,7 +590,7 @@ const std::vector state3 = { "Travelling to Hook Target" }; -class SaveEditorWindow : public LUS::GuiWindow { +class SaveEditorWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; diff --git a/soh/soh/Enhancements/debugger/dlViewer.cpp b/soh/soh/Enhancements/debugger/dlViewer.cpp index 2fce8860a..790f426df 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.cpp +++ b/soh/soh/Enhancements/debugger/dlViewer.cpp @@ -18,15 +18,13 @@ extern "C" { #include "variables.h" #include "functions.h" #include "macros.h" -extern PlayState* gPlayState; - -char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize); } char searchString[64] = ""; -int displayListsSearchResultsCount; -char** displayListsSearchResults; -char* activeDisplayList = nullptr; +std::string activeDisplayList = ""; +std::vector displayListSearchResults; +int16_t searchDebounceFrames = -1; +bool doSearch = false; std::map cmdMap = { { G_SETPRIMCOLOR, "gsDPSetPrimColor" }, @@ -36,8 +34,61 @@ std::map cmdMap = { { G_SETINTENSITY, "gsDPSetGrayscaleColor" }, { G_LOADTLUT, "gsDPLoadTLUT" }, { G_ENDDL, "gsSPEndDisplayList" }, + { G_TEXTURE, "gsSPTexture" }, + { G_SETTIMG, "gsDPSetTextureImage" }, + { G_SETTIMG_OTR_HASH, "gsDPSetTextureImage" }, + { G_SETTIMG_OTR_FILEPATH, "gsDPSetTextureImage" }, + { G_RDPTILESYNC, "gsDPTileSync" }, + { G_SETTILE, "gsDPSetTile" }, + { G_RDPLOADSYNC, "gsDPLoadSync" }, + { G_LOADBLOCK, "gsDPLoadBlock" }, + { G_SETTILESIZE, "gsDPSetTileSize" }, + { G_DL, "gsSPDisplayList" }, + { G_DL_OTR_FILEPATH, "gsSPDisplayList" }, + { G_DL_OTR_HASH, "gsSPDisplayList" }, + { G_MTX, "gsSPMatrix" }, + { G_MTX_OTR, "gsSPMatrix" }, + { G_VTX, "gsSPVertex" }, + { G_VTX_OTR_FILEPATH, "gsSPVertex" }, + { G_VTX_OTR_HASH, "gsSPVertex" }, + { G_GEOMETRYMODE, "gsSPSetGeometryMode" }, + { G_SETOTHERMODE_H, "gsSPSetOtherMode_H" }, + { G_SETOTHERMODE_L, "gsSPSetOtherMode_L" }, + { G_TRI1, "gsSP1Triangle" }, + { G_TRI1_OTR, "gsSP1Triangle" }, + { G_TRI2, "gsSP2Triangles" }, + { G_SETCOMBINE, "gsDPSetCombineLERP" }, + { G_CULLDL, "gsSPCullDisplayList" }, + { G_NOOP, "gsDPNoOp" }, + { G_SPNOOP, "gsSPNoOp" }, + { G_MARKER, "LUS Custom Marker" }, }; +void PerformDisplayListSearch() { + auto result = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles("*" + std::string(searchString) + "*DL*"); + + displayListSearchResults.clear(); + + // Filter the file results even further as StormLib can only use wildcard searching + for (size_t i = 0; i < result->size(); i++) { + std::string val = result->at(i); + if (val.ends_with("DL") || val.find("DL_") != std::string::npos) { + displayListSearchResults.push_back(val); + } + } + + // Sort the final list + std::sort(displayListSearchResults.begin(), displayListSearchResults.end(), [](const std::string& a, const std::string& b) { + return std::lexicographical_compare( + a.begin(), a.end(), + b.begin(), b.end(), + [](char c1, char c2) { + return std::tolower(c1) < std::tolower(c2); + } + ); + }); +} + void DLViewerWindow::DrawElement() { ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Display List Viewer", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { @@ -45,22 +96,48 @@ void DLViewerWindow::DrawElement() { return; } + // Debounce the search field as listing otr files is expensive if (ImGui::InputText("Search Display Lists", searchString, ARRAY_COUNT(searchString))) { - displayListsSearchResults = ResourceMgr_ListFiles(("*" + std::string(searchString) + "*DL").c_str(), &displayListsSearchResultsCount); + doSearch = true; + searchDebounceFrames = 30; } - if (ImGui::BeginCombo("Active Display List", activeDisplayList)) { - for (int i = 0; i < displayListsSearchResultsCount; i++) { - if (ImGui::Selectable(displayListsSearchResults[i])) { - activeDisplayList = displayListsSearchResults[i]; + if (doSearch) { + if (searchDebounceFrames == 0) { + doSearch = false; + PerformDisplayListSearch(); + } + + searchDebounceFrames--; + } + + if (ImGui::BeginCombo("Active Display List", activeDisplayList.c_str())) { + for (size_t i = 0; i < displayListSearchResults.size(); i++) { + if (ImGui::Selectable(displayListSearchResults[i].c_str())) { + activeDisplayList = displayListSearchResults[i]; break; } } ImGui::EndCombo(); } - if (activeDisplayList != nullptr) { - auto res = std::static_pointer_cast(LUS::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList)); - for (int i = 0; i < res->Instructions.size(); i++) { + + if (activeDisplayList == "") { + ImGui::End(); + return; + } + + try { + auto res = std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList)); + + if (res->GetInitData()->Type != static_cast(LUS::ResourceType::DisplayList)) { + ImGui::Text("Resource type is not a Display List. Please choose another."); + ImGui::End(); + return; + } + + ImGui::Text("Total Instruction Size: %lu", res->Instructions.size()); + + for (size_t i = 0; i < res->Instructions.size(); i++) { std::string id = "##CMD" + std::to_string(i); Gfx* gfx = (Gfx*)&res->Instructions[i]; int cmd = gfx->words.w0 >> 24; @@ -70,10 +147,11 @@ void DLViewerWindow::DrawElement() { ImGui::BeginGroup(); ImGui::PushItemWidth(25.0f); - ImGui::Text("%d", i); + ImGui::Text("%lu", i); ImGui::PopItemWidth(); ImGui::SameLine(); - ImGui::PushItemWidth(150.0f); + ImGui::PushItemWidth(175.0f); + if (ImGui::BeginCombo(("CMD" + id).c_str(), cmdLabel.c_str())) { if (ImGui::Selectable("gsDPSetPrimColor") && cmd != G_SETPRIMCOLOR) { *gfx = gsDPSetPrimColor(0, 0, 0, 0, 0, 255); @@ -92,8 +170,10 @@ void DLViewerWindow::DrawElement() { } ImGui::EndCombo(); } + ImGui::PopItemWidth(); - if (gfx->words.w0 >> 24 == G_SETPRIMCOLOR || gfx->words.w0 >> 24 == G_SETINTENSITY || gfx->words.w0 >> 24 == G_SETENVCOLOR) { + + if (cmd == G_SETPRIMCOLOR || cmd == G_SETINTENSITY || cmd == G_SETENVCOLOR) { uint8_t r = _SHIFTR(gfx->words.w1, 24, 8); uint8_t g = _SHIFTR(gfx->words.w1, 16, 8); uint8_t b = _SHIFTR(gfx->words.w1, 8, 8); @@ -117,21 +197,141 @@ void DLViewerWindow::DrawElement() { } ImGui::PopItemWidth(); } - if (gfx->words.w0 >> 24 == G_RDPPIPESYNC) { + if (cmd == G_RDPPIPESYNC) { } - if (gfx->words.w0 >> 24 == G_SETGRAYSCALE) { + if (cmd == G_SETGRAYSCALE) { bool* state = (bool*)&gfx->words.w1; ImGui::SameLine(); if (ImGui::Checkbox(("state" + id).c_str(), state)) { // } } + if (cmd == G_SETTILE) { + ImGui::SameLine(); + ImGui::Text("FMT: %u", _SHIFTR(gfx->words.w0, 21, 3)); + ImGui::SameLine(); + ImGui::Text("SIZ: %u", _SHIFTR(gfx->words.w0, 19, 2)); + ImGui::SameLine(); + ImGui::Text("LINE: %u", _SHIFTR(gfx->words.w0, 9, 9)); + ImGui::SameLine(); + ImGui::Text("TMEM: %u", _SHIFTR(gfx->words.w0, 0, 9)); + ImGui::SameLine(); + ImGui::Text("TILE: %u", _SHIFTR(gfx->words.w1, 24, 3)); + ImGui::SameLine(); + ImGui::Text("PAL: %u", _SHIFTR(gfx->words.w1, 20, 4)); + ImGui::SameLine(); + ImGui::Text("CMT: %u", _SHIFTR(gfx->words.w1, 18, 2)); + ImGui::SameLine(); + ImGui::Text("MASKT: %u", _SHIFTR(gfx->words.w1, 14, 4)); + ImGui::SameLine(); + ImGui::Text("SHIFT: %u", _SHIFTR(gfx->words.w1, 10, 4)); + ImGui::SameLine(); + ImGui::Text("CMS: %u", _SHIFTR(gfx->words.w1, 8, 2)); + ImGui::SameLine(); + ImGui::Text("MASKS: %u", _SHIFTR(gfx->words.w1, 4, 4)); + ImGui::SameLine(); + ImGui::Text("SHIFTS: %u", _SHIFTR(gfx->words.w1, 0, 4)); + } + if (cmd == G_SETTIMG) { + ImGui::SameLine(); + ImGui::Text("FMT: %u", _SHIFTR(gfx->words.w0, 21, 3)); + ImGui::SameLine(); + ImGui::Text("SIZ: %u", _SHIFTR(gfx->words.w0, 19, 2)); + ImGui::SameLine(); + ImGui::Text("WIDTH: %u", _SHIFTR(gfx->words.w0, 0, 10)); + ImGui::SameLine(); + } + if (cmd == G_SETTIMG_OTR_HASH) { + gfx++; + uint64_t hash = ((uint64_t)gfx->words.w0 << 32) + (uint64_t)gfx->words.w1; + const char* fileName = ResourceGetNameByCrc(hash); + + gfx--; + ImGui::SameLine(); + ImGui::Text("FMT: %u", _SHIFTR(gfx->words.w0, 21, 3)); + ImGui::SameLine(); + ImGui::Text("SIZ: %u", _SHIFTR(gfx->words.w0, 19, 2)); + ImGui::SameLine(); + ImGui::Text("WIDTH: %u", _SHIFTR(gfx->words.w0, 0, 10)); + ImGui::SameLine(); + ImGui::Text("Texture Name: %s", fileName); + } + if (cmd == G_SETTIMG_OTR_FILEPATH) { + char* fileName = (char*)gfx->words.w1; + gfx++; + ImGui::SameLine(); + ImGui::Text("FMT: %u", _SHIFTR(gfx->words.w0, 21, 3)); + ImGui::SameLine(); + ImGui::Text("SIZ: %u", _SHIFTR(gfx->words.w0, 19, 2)); + ImGui::SameLine(); + ImGui::Text("WIDTH: %u", _SHIFTR(gfx->words.w0, 0, 10)); + ImGui::SameLine(); + ImGui::Text("Texture Name: %s", fileName); + } + if (cmd == G_VTX) { + ImGui::SameLine(); + ImGui::Text("Num VTX: %u", _SHIFTR(gfx->words.w0, 12, 8)); + ImGui::SameLine(); + ImGui::Text("Offset: %u", _SHIFTR(gfx->words.w0, 1, 7) - _SHIFTR(gfx->words.w0, 12, 8)); + } + if (cmd == G_VTX_OTR_HASH) { + gfx++; + uint64_t hash = ((uint64_t)gfx->words.w0 << 32) + (uint64_t)gfx->words.w1; + const char* fileName = ResourceGetNameByCrc(hash); + + gfx--; + ImGui::SameLine(); + ImGui::Text("Num VTX: %u", _SHIFTR(gfx->words.w0, 12, 8)); + ImGui::SameLine(); + ImGui::Text("Offset: %u", _SHIFTR(gfx->words.w0, 1, 7) - _SHIFTR(gfx->words.w0, 12, 8)); + + ImGui::SameLine(); + ImGui::Text("Vertex Name: %s", fileName); + } + if (cmd == G_VTX_OTR_FILEPATH) { + char* fileName = (char*)gfx->words.w1; + + gfx++; + ImGui::SameLine(); + ImGui::Text("Num VTX: %u", _SHIFTR(gfx->words.w0, 12, 8)); + ImGui::SameLine(); + ImGui::Text("Offset: %u", _SHIFTR(gfx->words.w0, 1, 7) - _SHIFTR(gfx->words.w0, 12, 8)); + + ImGui::SameLine(); + ImGui::Text("Vertex Name: %s", fileName); + } + if (cmd == G_DL) { + } + if (cmd == G_DL_OTR_HASH) { + gfx++; + uint64_t hash = ((uint64_t)gfx->words.w0 << 32) + (uint64_t)gfx->words.w1; + const char* fileName = ResourceGetNameByCrc(hash); + ImGui::SameLine(); + ImGui::Text("DL Name: %s", fileName); + } + if (cmd == G_DL_OTR_FILEPATH) { + char* fileName = (char*)gfx->words.w1; + ImGui::SameLine(); + ImGui::Text("DL Name: %s", fileName); + } + + // Skip second half of instructions that are over 128-bit wide + if (cmd == G_SETTIMG_OTR_HASH || cmd == G_DL_OTR_HASH || cmd == G_VTX_OTR_HASH || + cmd == G_BRANCH_Z_OTR || cmd == G_MARKER || cmd == G_MTX_OTR) { + i++; + ImGui::Text("%lu - Reserved - Second half of %s", i, cmdLabel.c_str()); + } ImGui::EndGroup(); } + } catch (const std::exception& e) { + ImGui::Text("Error displaying DL instructions."); + ImGui::End(); + return; } + ImGui::End(); } void DLViewerWindow::InitElement() { - displayListsSearchResults = ResourceMgr_ListFiles("*DL", &displayListsSearchResultsCount); + PerformDisplayListSearch(); } diff --git a/soh/soh/Enhancements/debugger/dlViewer.h b/soh/soh/Enhancements/debugger/dlViewer.h index 348372a49..9d2785456 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.h +++ b/soh/soh/Enhancements/debugger/dlViewer.h @@ -2,7 +2,7 @@ #include -class DLViewerWindow : public LUS::GuiWindow { +class DLViewerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp new file mode 100644 index 000000000..97bf85164 --- /dev/null +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -0,0 +1,220 @@ +#include "valueViewer.h" +#include "../../UIWidgets.hpp" +#include "soh/OTRGlobals.h" + +extern "C" { +#include +#include "variables.h" +#include "functions.h" +#include "macros.h" +extern PlayState* gPlayState; +void GfxPrint_SetColor(GfxPrint* printer, u32 r, u32 g, u32 b, u32 a); +void GfxPrint_SetPos(GfxPrint* printer, s32 x, s32 y); +s32 GfxPrint_Printf(GfxPrint* printer, const char* fmt, ...); +} + +ImVec4 WHITE = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + +std::vector valueTable = { + { "Time", "gSaveContext.dayTime", "TIME:", TYPE_U16, false, []() -> void* { return &gSaveContext.dayTime; }, WHITE }, + { "Age", "gSaveContext.linkAge", "AGE:", TYPE_S32, false, []() -> void* { return &gSaveContext.linkAge; }, WHITE }, + { "Health", "gSaveContext.health", "HP:", TYPE_S16, false, []() -> void* { return &gSaveContext.health; }, WHITE }, + { "Navi Timer", "gSaveContext.naviTimer", "NAVI:", TYPE_U16, false, []() -> void* { return &gSaveContext.naviTimer; }, WHITE }, + { "Scene ID", "play->sceneNum", "SCENE:", TYPE_S16, true, []() -> void* { return &gPlayState->sceneNum; }, WHITE }, + { "Room ID", "play->roomCtx.curRoom.num", "ROOM:", TYPE_S8, true, []() -> void* { return &gPlayState->roomCtx.curRoom.num; }, WHITE }, + { "Entrance ID", "gSaveContext.entranceIndex", "ENTR:", TYPE_S32, false, []() -> void* { return &gSaveContext.entranceIndex; }, WHITE }, + { "Cutscene ID", "gSaveContext.cutsceneIndex", "CUTS:", TYPE_S32, false, []() -> void* { return &gSaveContext.cutsceneIndex; }, WHITE }, + { "Link X", "Player->actor.world.pos.x", "X:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.x; }, WHITE }, + { "Link Y", "Player->actor.world.pos.y", "Y:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.y; }, WHITE }, + { "Link Z", "Player->actor.world.pos.z", "Z:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.pos.z; }, WHITE }, + { "Link Yaw", "Player->actor.world.rot.y", "ROT:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.world.rot.y; }, WHITE }, + { "Link Velocity", "Player->linearVelocity", "V:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->linearVelocity; }, WHITE }, + { "Link X Velocity", "Player->actor.velocity.x", "XV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.x; }, WHITE }, + { "Link Y Velocity", "Player->actor.velocity.y", "YV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.y; }, WHITE }, + { "Link Z Velocity", "Player->actor.velocity.z", "ZV:", TYPE_FLOAT, true, []() -> void* { return &GET_PLAYER(gPlayState)->actor.velocity.z; }, WHITE }, + { "Text ID", "play->msgCtx.textId", "TEXTID:", TYPE_U16, true, []() -> void* { return &gPlayState->msgCtx.textId; }, WHITE }, + { "Analog Stick X", "play->state.input->cur.stick_x", "AX:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_x; }, WHITE }, + { "Analog Stick Y", "play->state.input->cur.stick_y", "AY:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_y; }, WHITE }, + /* TODO: Find these (from GZ) + "XZ Units Traveled (Camera based speed variable)" f32 0x801C9018 + "Movement Angle" x16 0x801DBB1C + "Camera Angle" u16 0x801C907C + "Time of Day" x16 0x8011AC8C + "Global Frame Counter" s32 0x801C8DFC + "Lit Deku Stick Timer" u16 0x801DBB40 + "Cutscene Pointer" u32 0x801CAAC8 + "Get Item Value" s8 0x801DB714 + "Last RNG Value" x32 0x80105A80 + "Last Item Button Pressed" u8 0x801DB430 + "Last Damage Value" x32 0x801DB7DC + "Temp B Value" u8 0x8011C062 + "Framerate Divisor" u8 0x801C7861 + "Heads Up Display (HUD)" u16 0x8011C068 + "Analog Stick Angle" s16 0x803AA698 + "Deku Tree Warp Timer (Reload Room)" u16 0x801F0352 + "Dodongo's Cavern Warp Timer" u16 0x801E30B2 + "Jabu-Jabu Warp Timer" u16 0x802008B2 + "Forest Temple Warp Timer" u16 0x801EC5B2 + "Fire Temple Warp Timer" u16 0x801F3E42 + "Water Temple Warp Timer" u16 0x801F8762 + "Shadow Temple Warp Timer" u16 0x801F48A2 + "Spirit Temple Warp Timer" u16 0x801FD562 + "Deku Tree Warp Timer" u16 0x801F83A2 + */ +}; + +extern "C" void ValueViewer_Draw(GfxPrint* printer) { + for (int i = 0; i < valueTable.size(); i++) { + ValueTableElement& element = valueTable[i]; + if (!element.isActive || !element.isPrinted || (gPlayState == NULL && element.requiresPlayState)) continue; + GfxPrint_SetColor(printer, element.color.x * 255, element.color.y * 255, element.color.z * 255, element.color.w * 255); + GfxPrint_SetPos(printer, element.x, element.y); + switch (element.type) { + case TYPE_S8: + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), *(s8*)element.valueFn()); + break; + case TYPE_U8: + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), *(u8*)element.valueFn()); + break; + case TYPE_S16: + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), *(s16*)element.valueFn()); + break; + case TYPE_U16: + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), *(u16*)element.valueFn()); + break; + case TYPE_S32: + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), *(s32*)element.valueFn()); + break; + case TYPE_U32: + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), *(u32*)element.valueFn()); + break; + case TYPE_CHAR: + GfxPrint_Printf(printer, "%s%c", element.prefix.c_str(), *(char*)element.valueFn()); + break; + case TYPE_STRING: + GfxPrint_Printf(printer, "%s%s", element.prefix.c_str(), (char*)element.valueFn()); + break; + case TYPE_FLOAT: + GfxPrint_Printf(printer, (element.typeFormat ? "%s%4.1f" : "%s%f"), element.prefix.c_str(), *(float*)element.valueFn()); + break; + } + } +} + +void ValueViewerWindow::DrawElement() { + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Value Viewer", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { + ImGui::End(); + return; + } + + UIWidgets::PaddedEnhancementCheckbox("Enable Printing", CVAR_DEVELOPER_TOOLS("ValueViewerEnablePrinting")); + + ImGui::BeginGroup(); + static int selectedElement = -1; + std::string selectedElementText = (selectedElement == -1) ? "Select a value" : ( + std::string(valueTable[selectedElement].name) + " (" + std::string(valueTable[selectedElement].path) + ")" + ); + if (ImGui::BeginCombo("##valueViewerElement", selectedElementText.c_str())) { + for (int i = 0; i < valueTable.size(); i++) { + if (valueTable[i].isActive) continue; + bool isSelected = (selectedElement == i); + std::string elementText = ( + std::string(valueTable[i].name) + " (" + std::string(valueTable[i].path) + ")" + ); + if (ImGui::Selectable(elementText.c_str(), isSelected)) { + selectedElement = i; + } + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + if (selectedElement != -1 && ImGui::Button("+")) { + valueTable[selectedElement].isActive = true; + selectedElement = -1; + } + ImGui::EndGroup(); + + for (int i = 0; i < valueTable.size(); i++) { + ValueTableElement& element = valueTable[i]; + if (!element.isActive || (gPlayState == NULL && element.requiresPlayState)) continue; + if (ImGui::Button(("x##" + std::string(element.name)).c_str())) { + element.isActive = false; + element.isPrinted = false; + } + ImGui::SameLine(); + ImGui::Text("%s:", element.name); + ImGui::SameLine(); + switch (element.type) { + case TYPE_S8: + ImGui::Text(element.typeFormat ? "0x%x" : "%d", *(s8*)element.valueFn()); + break; + case TYPE_U8: + ImGui::Text(element.typeFormat ? "0x%x" : "%u", *(u8*)element.valueFn()); + break; + case TYPE_S16: + ImGui::Text(element.typeFormat ? "0x%x" : "%d", *(s16*)element.valueFn()); + break; + case TYPE_U16: + ImGui::Text(element.typeFormat ? "0x%x" : "%u", *(u16*)element.valueFn()); + break; + case TYPE_S32: + ImGui::Text(element.typeFormat ? "0x%x" : "%d", *(s32*)element.valueFn()); + break; + case TYPE_U32: + ImGui::Text(element.typeFormat ? "0x%x" : "%u", *(u32*)element.valueFn()); + break; + case TYPE_CHAR: + ImGui::Text("%c", *(char*)element.valueFn()); + break; + case TYPE_STRING: + ImGui::Text("%s", (char*)element.valueFn()); + break; + case TYPE_FLOAT: + ImGui::Text(element.typeFormat ? "%4.1f" : "%f", *(float*)element.valueFn()); + break; + } + ImGui::SameLine(); + + if (element.type <= TYPE_U32) { + ImGui::Checkbox(("Hex##" + std::string(element.name)).c_str(), &element.typeFormat); + ImGui::SameLine(); + } else if (element.type == TYPE_FLOAT) { + ImGui::Checkbox(("Trim##" + std::string(element.name)).c_str(), &element.typeFormat); + ImGui::SameLine(); + } + + ImGui::BeginGroup(); + if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ValueViewerEnablePrinting"), 0)) { + ImGui::Checkbox(("Print##" + std::string(element.name)).c_str(), &element.isPrinted); + if (element.isPrinted) { + char* prefix = (char*)element.prefix.c_str(); + ImGui::SameLine(); + ImGui::SetNextItemWidth(80.0f); + if (ImGui::InputText(("Prefix##" + std::string(element.name)).c_str(), prefix, 10)) { + element.prefix = prefix; + } + ImGui::SameLine(); + ImGui::ColorEdit3(("##color" + std::string(element.name)).c_str(), (float*)&element.color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); + ImGui::SameLine(); + if (ImGui::Button(("Position##" + std::string(element.name)).c_str())) { + ImGui::OpenPopup(("Position Picker##" + std::string(element.name)).c_str()); + } + if (ImGui::BeginPopup(("Position Picker##" + std::string(element.name)).c_str())) { + ImGui::DragInt("X", (int*)&element.x, 1.0f, 0, 44); + ImGui::DragInt("Y", (int*)&element.y, 1.0f, 0, 29); + ImGui::EndPopup(); + } + } + } + ImGui::EndGroup(); + } + + ImGui::End(); +} + +void ValueViewerWindow::InitElement() { +} diff --git a/soh/soh/Enhancements/debugger/valueViewer.h b/soh/soh/Enhancements/debugger/valueViewer.h new file mode 100644 index 000000000..747d39018 --- /dev/null +++ b/soh/soh/Enhancements/debugger/valueViewer.h @@ -0,0 +1,53 @@ +#pragma once + +#ifdef __cplusplus + +#include + +typedef enum { + TYPE_S8, + TYPE_U8, + TYPE_S16, + TYPE_U16, + TYPE_S32, + TYPE_U32, + TYPE_CHAR, + TYPE_STRING, + TYPE_FLOAT, +} ValueType; + +typedef void* (*ValueFn)(); + +typedef struct { + const char* name; + const char* path; + std::string prefix; + ValueType type; + bool requiresPlayState; + ValueFn valueFn; + ImVec4 color; + bool isActive; + bool isPrinted; + bool typeFormat; + uint32_t x; + uint32_t y; +} ValueTableElement; + +class ValueViewerWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override; + void DrawElement() override; + void UpdateElement() override {}; +}; + +extern "C" { +#include +#endif + +void ValueViewer_Draw(GfxPrint* printer); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/soh/soh/Enhancements/enemyrandomizer.cpp b/soh/soh/Enhancements/enemyrandomizer.cpp index a89400844..67fd202b2 100644 --- a/soh/soh/Enhancements/enemyrandomizer.cpp +++ b/soh/soh/Enhancements/enemyrandomizer.cpp @@ -4,6 +4,7 @@ #include "soh/Enhancements/randomizer/3drando/random.hpp" #include "soh/Enhancements/enhancementTypes.h" #include "variables.h" +#include "soh/OTRGlobals.h" extern "C" { #include @@ -233,7 +234,7 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *po } EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) { - if (CVarGetInteger("gRandomizedEnemies", ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) { + if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) { uint32_t finalSeed = seed + (IS_RANDO ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt); Random_Init(finalSeed); } diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index c8461bbf1..56160567a 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -78,4 +78,10 @@ typedef enum { DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE, } DekuStickType; +typedef enum { + SWORD_TOGGLE_NONE, + SWORD_TOGGLE_CHILD, + SWORD_TOGGLE_BOTH_AGES, +} SwordToggleMode; + #endif diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp index 206b26426..a0469d0c3 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp @@ -31,11 +31,11 @@ GameInteractionEffectQueryResult GameInteractionEffectBase::Apply() { } /// For most effects, CanBeRemoved is the same as CanBeApplied. When its not: please override `CanBeRemoved`. -GameInteractionEffectQueryResult GameInteractionEffectBase::CanBeRemoved() { +GameInteractionEffectQueryResult RemovableGameInteractionEffect::CanBeRemoved() { return CanBeApplied(); } -GameInteractionEffectQueryResult GameInteractionEffectBase::Remove() { +GameInteractionEffectQueryResult RemovableGameInteractionEffect::Remove() { GameInteractionEffectQueryResult result = CanBeRemoved(); if (result != GameInteractionEffectQueryResult::Possible) { return result; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h index c4a7f7eac..ebc1b6fac 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h @@ -15,38 +15,46 @@ enum GameInteractionEffectQueryResult { class GameInteractionEffectBase { public: virtual GameInteractionEffectQueryResult CanBeApplied() = 0; - virtual GameInteractionEffectQueryResult CanBeRemoved(); GameInteractionEffectQueryResult Apply(); - GameInteractionEffectQueryResult Remove(); - int32_t parameters[3]; - - protected: +protected: virtual void _Apply() = 0; +}; + +class RemovableGameInteractionEffect: public GameInteractionEffectBase { +public: + virtual GameInteractionEffectQueryResult CanBeRemoved(); + GameInteractionEffectQueryResult Remove(); +protected: virtual void _Remove() {}; }; +class ParameterizedGameInteractionEffect { +public: + int32_t parameters[3]; +}; + namespace GameInteractionEffect { - class SetSceneFlag: public GameInteractionEffectBase { + class SetSceneFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class UnsetSceneFlag: public GameInteractionEffectBase { + class UnsetSceneFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class SetFlag: public GameInteractionEffectBase { + class SetFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class UnsetFlag: public GameInteractionEffectBase { + class UnsetFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class ModifyHeartContainers: public GameInteractionEffectBase { + class ModifyHeartContainers: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; @@ -61,29 +69,29 @@ namespace GameInteractionEffect { void _Apply() override; }; - class ModifyRupees: public GameInteractionEffectBase { + class ModifyRupees: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class NoUI: public GameInteractionEffectBase { + class NoUI: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class ModifyGravity: public GameInteractionEffectBase { + class ModifyGravity: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class ModifyHealth: public GameInteractionEffectBase { + class ModifyHealth: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class SetPlayerHealth: public GameInteractionEffectBase { + class SetPlayerHealth: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; @@ -103,98 +111,98 @@ namespace GameInteractionEffect { void _Apply() override; }; - class KnockbackPlayer: public GameInteractionEffectBase { + class KnockbackPlayer: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class ModifyLinkSize: public GameInteractionEffectBase { + class ModifyLinkSize: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class InvisibleLink : public GameInteractionEffectBase { + class InvisibleLink : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class PacifistMode : public GameInteractionEffectBase { + class PacifistMode : public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class DisableZTargeting: public GameInteractionEffectBase { + class DisableZTargeting: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class WeatherRainstorm: public GameInteractionEffectBase { + class WeatherRainstorm: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class ReverseControls: public GameInteractionEffectBase { + class ReverseControls: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class ForceEquipBoots: public GameInteractionEffectBase { + class ForceEquipBoots: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class ModifyRunSpeedModifier: public GameInteractionEffectBase { + class ModifyRunSpeedModifier: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class OneHitKO : public GameInteractionEffectBase { + class OneHitKO : public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class ModifyDefenseModifier: public GameInteractionEffectBase { + class ModifyDefenseModifier: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class GiveOrTakeShield: public GameInteractionEffectBase { + class GiveOrTakeShield: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class TeleportPlayer: public GameInteractionEffectBase { + class TeleportPlayer: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class ClearAssignedButtons: public GameInteractionEffectBase { + class ClearAssignedButtons: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class SetTimeOfDay: public GameInteractionEffectBase { + class SetTimeOfDay: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class SetCollisionViewer: public GameInteractionEffectBase { + class SetCollisionViewer: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class SetCosmeticsColor: public GameInteractionEffectBase { + class SetCosmeticsColor: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; @@ -204,52 +212,52 @@ namespace GameInteractionEffect { void _Apply() override; }; - class PressButton: public GameInteractionEffectBase { + class PressButton: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class PressRandomButton: public GameInteractionEffectBase { + class PressRandomButton: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class AddOrTakeAmmo: public GameInteractionEffectBase { + class AddOrTakeAmmo: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; - class RandomBombFuseTimer: public GameInteractionEffectBase { + class RandomBombFuseTimer: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class DisableLedgeGrabs: public GameInteractionEffectBase { + class DisableLedgeGrabs: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class RandomWind: public GameInteractionEffectBase { + class RandomWind: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class RandomBonks: public GameInteractionEffectBase { + class RandomBonks: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class PlayerInvincibility: public GameInteractionEffectBase { + class PlayerInvincibility: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; }; - class SlipperyFloor: public GameInteractionEffectBase { + class SlipperyFloor: public RemovableGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; void _Remove() override; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor.cpp index 5a0d0efd3..dbb4782fd 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.cpp @@ -31,7 +31,7 @@ GameInteractionEffectQueryResult GameInteractor::ApplyEffect(GameInteractionEffe return effect->Apply(); } -GameInteractionEffectQueryResult GameInteractor::RemoveEffect(GameInteractionEffectBase* effect) { +GameInteractionEffectQueryResult GameInteractor::RemoveEffect(RemovableGameInteractionEffect* effect) { return effect->Remove(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index b56a001d2..7503dbd78 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -5,6 +5,12 @@ #include "GameInteractionEffect.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h" +#include + +typedef enum { + GI_SCHEME_SAIL, + GI_SCHEME_CROWD_CONTROL, +} GIScheme; typedef enum { /* 0x00 */ GI_LINK_SIZE_NORMAL, @@ -52,13 +58,13 @@ typedef enum { } GIColors; typedef enum { - /* */ GI_TP_DEST_LINKSHOUSE = 187, - /* */ GI_TP_DEST_MINUET = 1536, - /* */ GI_TP_DEST_BOLERO = 1270, - /* */ GI_TP_DEST_SERENADE = 1540, - /* */ GI_TP_DEST_REQUIEM = 497, - /* */ GI_TP_DEST_NOCTURNE = 1384, - /* */ GI_TP_DEST_PRELUDE = 1524, + /* */ GI_TP_DEST_LINKSHOUSE = ENTR_LINKS_HOUSE_0, + /* */ GI_TP_DEST_MINUET = ENTR_SACRED_FOREST_MEADOW_2, + /* */ GI_TP_DEST_BOLERO = ENTR_DEATH_MOUNTAIN_CRATER_4, + /* */ GI_TP_DEST_SERENADE = ENTR_LAKE_HYLIA_8, + /* */ GI_TP_DEST_REQUIEM = ENTR_DESERT_COLOSSUS_5, + /* */ GI_TP_DEST_NOCTURNE = ENTR_GRAVEYARD_7, + /* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_7, } GITeleportDestinations; #ifdef __cplusplus @@ -91,11 +97,16 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state); #ifdef __cplusplus - +#include #include #include #include +#ifdef ENABLE_REMOTE_CONTROL +#include +#include +#endif + #define DEFINE_HOOK(name, type) \ struct name { \ typedef std::function fn; \ @@ -132,17 +143,50 @@ public: static void SetPacifistMode(bool active); }; + #ifdef ENABLE_REMOTE_CONTROL + bool isRemoteInteractorEnabled; + bool isRemoteInteractorConnected; + + void EnableRemoteInteractor(); + void DisableRemoteInteractor(); + void RegisterRemoteDataHandler(std::function method); + void RegisterRemoteJsonHandler(std::function method); + void RegisterRemoteConnectedHandler(std::function method); + void RegisterRemoteDisconnectedHandler(std::function method); + void TransmitDataToRemote(const char* payload); + void TransmitJsonToRemote(nlohmann::json packet); + #endif + // Effects static GameInteractionEffectQueryResult CanApplyEffect(GameInteractionEffectBase* effect); static GameInteractionEffectQueryResult ApplyEffect(GameInteractionEffectBase* effect); - static GameInteractionEffectQueryResult RemoveEffect(GameInteractionEffectBase* effect); + static GameInteractionEffectQueryResult RemoveEffect(RemovableGameInteractionEffect* effect); // Game Hooks - template struct RegisteredGameHooks { inline static std::vector functions; }; - template void RegisterGameHook(typename H::fn h) { RegisteredGameHooks::functions.push_back(h); } + uint32_t nextHookId = 1; + template struct RegisteredGameHooks { inline static std::unordered_map functions; }; + template struct HooksToUnregister { inline static std::vector hooks; }; + template uint32_t RegisterGameHook(typename H::fn h) { + // Ensure hook id is unique and not 0, which is reserved for invalid hooks + if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1; + while (RegisteredGameHooks::functions.find(this->nextHookId) != RegisteredGameHooks::functions.end()) { + this->nextHookId++; + } + + RegisteredGameHooks::functions[this->nextHookId] = h; + return this->nextHookId++; + } + template void UnregisterGameHook(uint32_t id) { + HooksToUnregister::hooks.push_back(id); + } + template void ExecuteHooks(Args&&... args) { - for (auto& fn : RegisteredGameHooks::functions) { - fn(std::forward(args)...); + for (auto& hookId : HooksToUnregister::hooks) { + RegisteredGameHooks::functions.erase(hookId); + } + HooksToUnregister::hooks.clear(); + for (auto& hook : RegisteredGameHooks::functions) { + hook.second(std::forward(args)...); } } @@ -196,6 +240,7 @@ public: DEFINE_HOOK(OnFileDropped, void(std::string filePath)); DEFINE_HOOK(OnAssetAltChange, void()); + DEFINE_HOOK(OnKaleidoUpdate, void()); // Helpers static bool IsSaveLoaded(bool allowDbgSave = false); @@ -239,6 +284,21 @@ public: static GameInteractionEffectQueryResult SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams); static GameInteractionEffectQueryResult SpawnActor(uint32_t actorId, int32_t actorParams); }; + + private: + #ifdef ENABLE_REMOTE_CONTROL + IPaddress remoteIP; + TCPsocket remoteSocket; + std::thread remoteThreadReceive; + std::function remoteDataHandler; + std::function remoteJsonHandler; + std::function remoteConnectedHandler; + std::function remoteDisconnectedHandler; + + void ReceiveFromServer(); + void HandleRemoteData(char payload[512]); + void HandleRemoteJson(std::string payload); + #endif }; #endif /* __cplusplus */ diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 4bd5354a6..911c47a71 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -187,3 +187,9 @@ void GameInteractor_ExecuteOnSetGameLanguage() { void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) { GameInteractor::Instance->RegisterGameHook(fn); } + +//MARK: Pause Menu + +void GameInteractor_ExecuteOnKaleidoUpdate() { + GameInteractor::Instance->ExecuteHooks(); +} diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 7b7b226fa..5c86cb39b 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -60,6 +60,9 @@ void GameInteractor_ExecuteOnSetGameLanguage(); // MARK: - System void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)); +//Mark: - Pause Menu +void GameInteractor_ExecuteOnKaleidoUpdate(); + #ifdef __cplusplus } #endif diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp index 54a3b8e7b..5e61f704d 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp @@ -111,9 +111,9 @@ void GameInteractor::RawAction::FreezePlayer() { void GameInteractor::RawAction::BurnPlayer() { Player* player = GET_PLAYER(gPlayState); for (int i = 0; i < 18; i++) { - player->flameTimers[i] = Rand_S16Offset(0, 200); + player->bodyFlameTimers[i] = Rand_S16Offset(0, 200); } - player->isBurning = true; + player->bodyIsBurning = true; func_80837C0C(gPlayState, player, 0, 0, 0, 0, 0); } @@ -326,9 +326,9 @@ void GameInteractor::RawAction::UpdateActor(void* refActor) { void GameInteractor::RawAction::TeleportPlayer(int32_t nextEntrance) { Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); gPlayState->nextEntranceIndex = nextEntrance; - gPlayState->sceneLoadFlag = 0x14; - gPlayState->fadeTransition = 2; - gSaveContext.nextTransitionType = 2; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; } void GameInteractor::RawAction::ClearAssignedButtons(uint8_t buttonSet) { @@ -353,19 +353,19 @@ void GameInteractor::RawAction::SetTimeOfDay(uint32_t time) { } void GameInteractor::RawAction::SetCollisionViewer(bool active) { - CVarSetInteger("gColViewerEnabled", active); - CVarSetInteger("gColViewerDecal", active); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), active); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), active); if (active) { - CVarSetInteger("gColViewerScene", COLVIEW_TRANSPARENT); - CVarSetInteger("gColViewerBgActors", COLVIEW_TRANSPARENT); - CVarSetInteger("gColViewerColCheck", COLVIEW_TRANSPARENT); - CVarSetInteger("gColViewerWaterbox", COLVIEW_TRANSPARENT); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_TRANSPARENT); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_TRANSPARENT); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_TRANSPARENT); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_TRANSPARENT); } else { - CVarSetInteger("gColViewerScene", COLVIEW_DISABLED); - CVarSetInteger("gColViewerBgActors", COLVIEW_DISABLED); - CVarSetInteger("gColViewerColCheck", COLVIEW_DISABLED); - CVarSetInteger("gColViewerWaterbox", COLVIEW_DISABLED); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_DISABLED); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_DISABLED); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_DISABLED); + CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_DISABLED); } } @@ -428,55 +428,55 @@ void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint switch (cosmeticCategory) { case GI_COSMETICS_TUNICS: - CVarSetColor("gCosmetics.Link_KokiriTunic.Value", newColor); - CVarSetInteger("gCosmetics.Link_KokiriTunic.Changed", 1); - CVarSetColor("gCosmetics.Link_GoronTunic.Value", newColor); - CVarSetInteger("gCosmetics.Link_GoronTunic.Changed", 1); - CVarSetColor("gCosmetics.Link_ZoraTunic.Value", newColor); - CVarSetInteger("gCosmetics.Link_ZoraTunic.Changed", 1); + CVarSetColor(CVAR_COSMETIC("Link.KokiriTunic.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Link.KokiriTunic.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Link.GoronTunic.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Link.GoronTunic.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Link.ZoraTunic.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Link.ZoraTunic.Changed"), 1); break; case GI_COSMETICS_NAVI: - CVarSetColor("gCosmetics.Navi_EnemyPrimary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_EnemyPrimary.Changed", 1); - CVarSetColor("gCosmetics.Navi_EnemySecondary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_EnemySecondary.Changed", 1); - CVarSetColor("gCosmetics.Navi_IdlePrimary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_IdlePrimary.Changed", 1); - CVarSetColor("gCosmetics.Navi_IdleSecondary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_IdleSecondary.Changed", 1); - CVarSetColor("gCosmetics.Navi_NPCPrimary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_NPCPrimary.Changed", 1); - CVarSetColor("gCosmetics.Navi_NPCSecondary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_NPCSecondary.Changed", 1); - CVarSetColor("gCosmetics.Navi_PropsPrimary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_PropsPrimary.Changed", 1); - CVarSetColor("gCosmetics.Navi_PropsSecondary.Value", newColor); - CVarSetInteger("gCosmetics.Navi_PropsSecondary.Changed", 1); + CVarSetColor(CVAR_COSMETIC("Navi.EnemyPrimary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.EnemyPrimary.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Navi.EnemySecondary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.EnemySecondary.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Navi.IdlePrimary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.IdlePrimary.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Navi.IdleSecondary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.IdleSecondary.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Navi.NPCPrimary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.NPCPrimary.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Navi.NPCSecondary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.NPCSecondary.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Navi.PropsPrimary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.PropsPrimary.Changed"), 1); + CVarSetColor(CVAR_COSMETIC("Navi.PropsSecondary.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Navi.PropsSecondary.Changed"), 1); break; case GI_COSMETICS_HAIR: - CVarSetColor("gCosmetics.Link_Hair.Value", newColor); - CVarSetInteger("gCosmetics.Link_Hair.Changed", 1); + CVarSetColor(CVAR_COSMETIC("Link.Hair.Value"), newColor); + CVarSetInteger(CVAR_COSMETIC("Link.Hair.Changed"), 1); break; } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); ApplyOrResetCustomGfxPatches(); } void GameInteractor::RawAction::RandomizeCosmeticsColors(bool excludeBiddingWarColors) { const char* cvarsToLock[12] = { - "gCosmetics.Link_KokiriTunic.Locked", - "gCosmetics.Link_GoronTunic.Locked", - "gCosmetics.Link_ZoraTunic.Locked", - "gCosmetics.Navi_EnemyPrimary.Locked", - "gCosmetics.Navi_EnemySecondary.Locked", - "gCosmetics.Navi_IdlePrimary.Locked", - "gCosmetics.Navi_IdleSecondary.Locked", - "gCosmetics.Navi_NPCPrimary.Locked", - "gCosmetics.Navi_NPCSecondary.Locked", - "gCosmetics.Navi_PropsPrimary.Locked", - "gCosmetics.Navi_PropsSecondary.Locked", - "gCosmetics.Link_Hair.Locked" + CVAR_COSMETIC("Link.KokiriTunic.Locked"), + CVAR_COSMETIC("Link.GoronTunic.Locked"), + CVAR_COSMETIC("Link.ZoraTunic.Locked"), + CVAR_COSMETIC("Navi.EnemyPrimary.Locked"), + CVAR_COSMETIC("Navi.EnemySecondary.Locked"), + CVAR_COSMETIC("Navi.IdlePrimary.Locked"), + CVAR_COSMETIC("Navi.IdleSecondary.Locked"), + CVAR_COSMETIC("Navi.NPCPrimary.Locked"), + CVAR_COSMETIC("Navi.NPCSecondary.Locked"), + CVAR_COSMETIC("Navi.PropsPrimary.Locked"), + CVAR_COSMETIC("Navi.PropsSecondary.Locked"), + CVAR_COSMETIC("Link.Hair.Locked") }; if (excludeBiddingWarColors) { @@ -520,7 +520,7 @@ void GameInteractor::RawAction::SetRandomWind(bool active) { if (active) { GameInteractor::State::RandomWindActive = 1; if (GameInteractor::State::RandomWindSecondsSinceLastDirectionChange == 0) { - player->windDirection = (rand() % 49152) - 32767; + player->pushedYaw = (rand() % 49152) - 32767; GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 5; } else { GameInteractor::State::RandomWindSecondsSinceLastDirectionChange--; @@ -528,8 +528,8 @@ void GameInteractor::RawAction::SetRandomWind(bool active) { } else { GameInteractor::State::RandomWindActive = 0; GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 0; - player->windSpeed = 0.0f; - player->windDirection = 0.0f; + player->pushedSpeed = 0.0f; + player->pushedYaw = 0.0f; } } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Remote.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Remote.cpp new file mode 100644 index 000000000..662d2ea78 --- /dev/null +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Remote.cpp @@ -0,0 +1,183 @@ +#ifdef ENABLE_REMOTE_CONTROL + +#include "GameInteractor.h" +#include +#include +#include +#include +#include +#include +#include +#include "soh/OTRGlobals.h" + +// MARK: - Remote + +void GameInteractor::EnableRemoteInteractor() { + if (isRemoteInteractorEnabled) { + return; + } + + if (SDLNet_ResolveHost(&remoteIP, CVarGetString(CVAR_REMOTE("IP"), "127.0.0.1"), CVarGetInteger(CVAR_REMOTE("Port"), 43384)) == -1) { + SPDLOG_ERROR("[GameInteractor] SDLNet_ResolveHost: {}", SDLNet_GetError()); + } + + isRemoteInteractorEnabled = true; + + // First check if there is a thread running, if so, join it + if (remoteThreadReceive.joinable()) { + remoteThreadReceive.join(); + } + + remoteThreadReceive = std::thread(&GameInteractor::ReceiveFromServer, this); +} + +/** + * Raw data handler + * + * If you are developing a new remote, you should probably use the json methods instead. This + * method requires you to parse the data and ensure packets are complete manually, we cannot + * gaurentee that the data will be complete, or that it will only contain one packet with this + */ +void GameInteractor::RegisterRemoteDataHandler(std::function method) { + remoteDataHandler = method; +} + +/** + * Json handler + * + * This method will be called when a complete json packet is received. All json packets must + * be delimited by a null terminator (\0). + */ +void GameInteractor::RegisterRemoteJsonHandler(std::function method) { + remoteJsonHandler = method; +} + +void GameInteractor::RegisterRemoteConnectedHandler(std::function method) { + remoteConnectedHandler = method; +} + +void GameInteractor::RegisterRemoteDisconnectedHandler(std::function method) { + remoteDisconnectedHandler = method; +} + +void GameInteractor::DisableRemoteInteractor() { + if (!isRemoteInteractorEnabled) { + return; + } + + isRemoteInteractorEnabled = false; + remoteThreadReceive.join(); + remoteDataHandler = nullptr; + remoteJsonHandler = nullptr; + remoteConnectedHandler = nullptr; + remoteDisconnectedHandler = nullptr; +} + +void GameInteractor::TransmitDataToRemote(const char* payload) { + SDLNet_TCP_Send(remoteSocket, payload, strlen(payload) + 1); +} + +// Appends a newline character to the end of the json payload and sends it to the remote +void GameInteractor::TransmitJsonToRemote(nlohmann::json payload) { + TransmitDataToRemote(payload.dump().c_str()); +} + +// MARK: - Private + +std::string receivedData; + +void GameInteractor::ReceiveFromServer() { + while (isRemoteInteractorEnabled) { + while (!isRemoteInteractorConnected && isRemoteInteractorEnabled) { + SPDLOG_TRACE("[GameInteractor] Attempting to make connection to server..."); + remoteSocket = SDLNet_TCP_Open(&remoteIP); + + if (remoteSocket) { + isRemoteInteractorConnected = true; + SPDLOG_INFO("[GameInteractor] Connection to server established!"); + + if (remoteConnectedHandler) { + remoteConnectedHandler(); + } + break; + } + } + + SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1); + if (remoteSocket) { + SDLNet_TCP_AddSocket(socketSet, remoteSocket); + } + + // Listen to socket messages + while (isRemoteInteractorConnected && remoteSocket && isRemoteInteractorEnabled) { + // 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("[GameInteractor] SDLNet_CheckSockets: {}", SDLNet_GetError()); + break; + } + + if (socketsReady == 0) { + continue; + } + + char remoteDataReceived[512]; + memset(remoteDataReceived, 0, sizeof(remoteDataReceived)); + int len = SDLNet_TCP_Recv(remoteSocket, &remoteDataReceived, sizeof(remoteDataReceived)); + if (!len || !remoteSocket || len == -1) { + SPDLOG_ERROR("[GameInteractor] SDLNet_TCP_Recv: {}", SDLNet_GetError()); + break; + } + + HandleRemoteData(remoteDataReceived); + + receivedData.append(remoteDataReceived, len); + + // Proess all complete packets + size_t delimiterPos = receivedData.find('\0'); + while (delimiterPos != std::string::npos) { + // Extract the complete packet until the delimiter + std::string packet = receivedData.substr(0, delimiterPos); + // Remove the packet (including the delimiter) from the received data + receivedData.erase(0, delimiterPos + 1); + HandleRemoteJson(packet); + // Find the next delimiter + delimiterPos = receivedData.find('\0'); + } + } + + if (isRemoteInteractorConnected) { + SDLNet_TCP_Close(remoteSocket); + isRemoteInteractorConnected = false; + if (remoteDisconnectedHandler) { + remoteDisconnectedHandler(); + } + SPDLOG_INFO("[GameInteractor] Ending receiving thread..."); + } + } +} + +void GameInteractor::HandleRemoteData(char payload[512]) { + if (remoteDataHandler) { + remoteDataHandler(payload); + return; + } +} + +void GameInteractor::HandleRemoteJson(std::string payload) { + nlohmann::json jsonPayload; + try { + jsonPayload = nlohmann::json::parse(payload); + } catch (const std::exception& e) { + SPDLOG_ERROR("[GameInteractor] Failed to parse json: \n{}\n{}\n", payload, e.what()); + return; + } + + if (remoteJsonHandler) { + remoteJsonHandler(jsonPayload); + return; + } +} + +#endif diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Sail.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Sail.cpp new file mode 100644 index 000000000..77d48dc80 --- /dev/null +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Sail.cpp @@ -0,0 +1,471 @@ +#ifdef ENABLE_REMOTE_CONTROL + +#include "GameInteractor_Sail.h" +#include +#include +#include + +template +bool IsType(const SrcType* src) { + return dynamic_cast(src) != nullptr; +} + +void GameInteractorSail::Enable() { + if (isEnabled) { + return; + } + + isEnabled = true; + GameInteractor::Instance->EnableRemoteInteractor(); + GameInteractor::Instance->RegisterRemoteJsonHandler([&](nlohmann::json payload) { + HandleRemoteJson(payload); + }); + GameInteractor::Instance->RegisterRemoteConnectedHandler([&]() { + RegisterHooks(); + }); +} + +void GameInteractorSail::Disable() { + if (!isEnabled) { + return; + } + + isEnabled = false; + GameInteractor::Instance->DisableRemoteInteractor(); +} + +void GameInteractorSail::HandleRemoteJson(nlohmann::json payload) { + SPDLOG_INFO("[GameInteractorSail] Received payload: \n{}", payload.dump()); + + nlohmann::json responsePayload; + responsePayload["type"] = "result"; + responsePayload["status"] = "failure"; + + try { + if (!payload.contains("id")) { + SPDLOG_ERROR("[GameInteractorSail] Received payload without ID"); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + responsePayload["id"] = payload["id"]; + + if (!payload.contains("type")) { + SPDLOG_ERROR("[GameInteractorSail] Received payload without type"); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + std::string payloadType = payload["type"].get(); + + if (payloadType == "command") { + if (!payload.contains("command")) { + SPDLOG_ERROR("[GameInteractorSail] Received command payload without command"); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + std::string command = payload["command"].get(); + std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch(command); + responsePayload["status"] = "success"; + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } else if (payloadType == "effect") { + if (!payload.contains("effect") || !payload["effect"].contains("type")) { + SPDLOG_ERROR("[GameInteractorSail] Received effect payload without effect type"); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + std::string effectType = payload["effect"]["type"].get(); + + // Special case for "command" effect, so we can also run commands from the `simple_twitch_sail` script + if (effectType == "command") { + if (!payload["effect"].contains("command")) { + SPDLOG_ERROR("[GameInteractorSail] Received command effect payload without command"); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + std::string command = payload["effect"]["command"].get(); + std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch(command); + responsePayload["status"] = "success"; + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + if (effectType != "apply" && effectType != "remove") { + SPDLOG_ERROR("[GameInteractorSail] Received effect payload with unknown effect type: {}", effectType); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + if (!GameInteractor::IsSaveLoaded()) { + responsePayload["status"] = "try_again"; + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + GameInteractionEffectBase* giEffect = EffectFromJson(payload["effect"]); + if (giEffect) { + GameInteractionEffectQueryResult result; + if (effectType == "remove") { + if (IsType(giEffect)) { + result = dynamic_cast(giEffect)->Remove(); + } else { + result = GameInteractionEffectQueryResult::NotPossible; + } + } else { + result = giEffect->Apply(); + } + + if (result == GameInteractionEffectQueryResult::Possible) { + responsePayload["status"] = "success"; + } else if (result == GameInteractionEffectQueryResult::TemporarilyNotPossible) { + responsePayload["status"] = "try_again"; + } + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + } else { + SPDLOG_ERROR("[GameInteractorSail] Unknown payload type: {}", payloadType); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + return; + } + + // If we get here, something went wrong, send the failure response + SPDLOG_ERROR("[GameInteractorSail] Failed to handle remote JSON, sending failure response"); + GameInteractor::Instance->TransmitJsonToRemote(responsePayload); + } catch (const std::exception& e) { + SPDLOG_ERROR("[GameInteractorSail] Exception handling remote JSON: {}", e.what()); + } catch (...) { + SPDLOG_ERROR("[GameInteractorSail] Unknown exception handling remote JSON"); + } +} + +GameInteractionEffectBase* GameInteractorSail::EffectFromJson(nlohmann::json payload) { + if (!payload.contains("name")) { + return nullptr; + } + + std::string name = payload["name"].get(); + + if (name == "SetSceneFlag") { + auto effect = new GameInteractionEffect::SetSceneFlag(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + effect->parameters[1] = payload["parameters"][1].get(); + effect->parameters[2] = payload["parameters"][2].get(); + } + return effect; + } else if (name == "UnsetSceneFlag") { + auto effect = new GameInteractionEffect::UnsetSceneFlag(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + effect->parameters[1] = payload["parameters"][1].get(); + effect->parameters[2] = payload["parameters"][2].get(); + } + return effect; + } else if (name == "SetFlag") { + auto effect = new GameInteractionEffect::SetFlag(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + effect->parameters[1] = payload["parameters"][1].get(); + } + return effect; + } else if (name == "UnsetFlag") { + auto effect = new GameInteractionEffect::UnsetFlag(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + effect->parameters[1] = payload["parameters"][1].get(); + } + return effect; + } else if (name == "ModifyHeartContainers") { + auto effect = new GameInteractionEffect::ModifyHeartContainers(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "FillMagic") { + return new GameInteractionEffect::FillMagic(); + } else if (name == "EmptyMagic") { + return new GameInteractionEffect::EmptyMagic(); + } else if (name == "ModifyRupees") { + auto effect = new GameInteractionEffect::ModifyRupees(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "NoUI") { + return new GameInteractionEffect::NoUI(); + } else if (name == "ModifyGravity") { + auto effect = new GameInteractionEffect::ModifyGravity(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "ModifyHealth") { + auto effect = new GameInteractionEffect::ModifyHealth(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "SetPlayerHealth") { + auto effect = new GameInteractionEffect::SetPlayerHealth(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "FreezePlayer") { + return new GameInteractionEffect::FreezePlayer(); + } else if (name == "BurnPlayer") { + return new GameInteractionEffect::BurnPlayer(); + } else if (name == "ElectrocutePlayer") { + return new GameInteractionEffect::ElectrocutePlayer(); + } else if (name == "KnockbackPlayer") { + auto effect = new GameInteractionEffect::KnockbackPlayer(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "ModifyLinkSize") { + auto effect = new GameInteractionEffect::ModifyLinkSize(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "InvisibleLink") { + return new GameInteractionEffect::InvisibleLink(); + } else if (name == "PacifistMode") { + return new GameInteractionEffect::PacifistMode(); + } else if (name == "DisableZTargeting") { + return new GameInteractionEffect::DisableZTargeting(); + } else if (name == "WeatherRainstorm") { + return new GameInteractionEffect::WeatherRainstorm(); + } else if (name == "ReverseControls") { + return new GameInteractionEffect::ReverseControls(); + } else if (name == "ForceEquipBoots") { + auto effect = new GameInteractionEffect::ForceEquipBoots(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "ModifyRunSpeedModifier") { + auto effect = new GameInteractionEffect::ModifyRunSpeedModifier(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "OneHitKO") { + return new GameInteractionEffect::OneHitKO(); + } else if (name == "ModifyDefenseModifier") { + auto effect = new GameInteractionEffect::ModifyDefenseModifier(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "GiveOrTakeShield") { + auto effect = new GameInteractionEffect::GiveOrTakeShield(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "TeleportPlayer") { + auto effect = new GameInteractionEffect::TeleportPlayer(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "ClearAssignedButtons") { + auto effect = new GameInteractionEffect::ClearAssignedButtons(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "SetTimeOfDay") { + auto effect = new GameInteractionEffect::SetTimeOfDay(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "SetCollisionViewer") { + return new GameInteractionEffect::SetCollisionViewer(); + } else if (name == "SetCosmeticsColor") { + auto effect = new GameInteractionEffect::SetCosmeticsColor(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + effect->parameters[1] = payload["parameters"][1].get(); + } + return effect; + } else if (name == "RandomizeCosmetics") { + return new GameInteractionEffect::RandomizeCosmetics(); + } else if (name == "PressButton") { + auto effect = new GameInteractionEffect::PressButton(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "PressRandomButton") { + auto effect = new GameInteractionEffect::PressRandomButton(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + } + return effect; + } else if (name == "AddOrTakeAmmo") { + auto effect = new GameInteractionEffect::AddOrTakeAmmo(); + if (payload.contains("parameters")) { + effect->parameters[0] = payload["parameters"][0].get(); + effect->parameters[1] = payload["parameters"][1].get(); + } + return effect; + } else if (name == "RandomBombFuseTimer") { + return new GameInteractionEffect::RandomBombFuseTimer(); + } else if (name == "DisableLedgeGrabs") { + return new GameInteractionEffect::DisableLedgeGrabs(); + } else if (name == "RandomWind") { + return new GameInteractionEffect::RandomWind(); + } else if (name == "RandomBonks") { + return new GameInteractionEffect::RandomBonks(); + } else if (name == "PlayerInvincibility") { + return new GameInteractionEffect::PlayerInvincibility(); + } else if (name == "SlipperyFloor") { + return new GameInteractionEffect::SlipperyFloor(); + } else { + SPDLOG_INFO("[GameInteractorSail] Unknown effect name: {}", name); + return nullptr; + } +} + +// Workaround until we have a way to unregister hooks +static bool hasRegisteredHooks = false; + +void GameInteractorSail::RegisterHooks() { + if (hasRegisteredHooks) { + return; + } + hasRegisteredHooks = true; + + GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnTransitionEnd"; + payload["hook"]["sceneNum"] = sceneNum; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnLoadGame"; + payload["hook"]["fileNum"] = fileNum; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnExitGame"; + payload["hook"]["fileNum"] = fileNum; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnItemReceive"; + payload["hook"]["tableId"] = itemEntry.tableId; + payload["hook"]["getItemId"] = itemEntry.getItemId; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + Actor* actor = (Actor*)refActor; + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnEnemyDefeat"; + payload["hook"]["actorId"] = actor->id; + payload["hook"]["params"] = actor->params; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + Actor* actor = (Actor*)refActor; + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnActorInit"; + payload["hook"]["actorId"] = actor->id; + payload["hook"]["params"] = actor->params; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](int16_t flagType, int16_t flag) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnFlagSet"; + payload["hook"]["flagType"] = flagType; + payload["hook"]["flag"] = flag; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](int16_t flagType, int16_t flag) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnFlagUnset"; + payload["hook"]["flagType"] = flagType; + payload["hook"]["flag"] = flag; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum, int16_t flagType, int16_t flag) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnSceneFlagSet"; + payload["hook"]["flagType"] = flagType; + payload["hook"]["flag"] = flag; + payload["hook"]["sceneNum"] = sceneNum; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum, int16_t flagType, int16_t flag) { + if (!GameInteractor::Instance->isRemoteInteractorConnected || !GameInteractor::IsSaveLoaded()) return; + + nlohmann::json payload; + payload["id"] = std::rand(); + payload["type"] = "hook"; + payload["hook"]["type"] = "OnSceneFlagUnset"; + payload["hook"]["flagType"] = flagType; + payload["hook"]["flag"] = flag; + payload["hook"]["sceneNum"] = sceneNum; + + GameInteractor::Instance->TransmitJsonToRemote(payload); + }); +} + +#endif diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Sail.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Sail.h new file mode 100644 index 000000000..cb90c65c7 --- /dev/null +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Sail.h @@ -0,0 +1,29 @@ +#ifdef ENABLE_REMOTE_CONTROL + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "./GameInteractor.h" + +class GameInteractorSail { + private: + bool isEnabled; + + void HandleRemoteJson(nlohmann::json payload); + GameInteractionEffectBase* EffectFromJson(nlohmann::json payload); + void RegisterHooks(); + public: + static GameInteractorSail* Instance; + void Enable(); + void Disable(); +}; +#endif +#endif diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index efcf44efb..61eb88a6f 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -14,6 +14,7 @@ extern "C" { #include #include #include "soh/Enhancements/enhancementTypes.h" +#include "soh/OTRGlobals.h" extern "C" { #include @@ -387,7 +388,7 @@ void GameplayStatsRow(const char* label, const std::string& value, ImVec4 color } bool compareTimestampInfoByTime(const TimestampInfo& a, const TimestampInfo& b) { - return CVarGetInteger("gGameplayStats.TimestampsReverse", 0) ? a.time > b.time : a.time < b.time; + return CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ReverseTimestamps"), 0) ? a.time > b.time : a.time < b.time; } const char* ResolveSceneID(int sceneID, int roomID){ @@ -442,13 +443,13 @@ void DrawGameplayStatsHeader() { } else { GameplayStatsRow("Total Game Time:", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.sohStats.gameComplete ? COLOR_GREEN : COLOR_WHITE); } - if (CVarGetInteger("gGameplayStats.ShowAdditionalTimers", 0)) { // !Only display total game time + if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ShowAdditionalTimers"), 0)) { // !Only display total game time GameplayStatsRow("Gameplay Time:", formatTimestampGameplayStat(gSaveContext.sohStats.playTimer / 2), COLOR_GREY); GameplayStatsRow("Pause Menu Time:", formatTimestampGameplayStat(gSaveContext.sohStats.pauseTimer / 3), COLOR_GREY); GameplayStatsRow("Time in scene:", formatTimestampGameplayStat(gSaveContext.sohStats.sceneTimer / 2), COLOR_LIGHT_BLUE); GameplayStatsRow("Time in room:", formatTimestampGameplayStat(gSaveContext.sohStats.roomTimer / 2), COLOR_LIGHT_BLUE); } - if (gPlayState != NULL && CVarGetInteger("gGameplayStats.ShowDebugInfo", 0)) { // && display debug info + if (gPlayState != NULL && CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ShowDebugInfo"), 0)) { // && display debug info GameplayStatsRow("play->sceneNum:", formatHexGameplayStat(gPlayState->sceneNum), COLOR_YELLOW); GameplayStatsRow("gSaveContext.entranceIndex:", formatHexGameplayStat(gSaveContext.entranceIndex), COLOR_YELLOW); GameplayStatsRow("gSaveContext.cutsceneIndex:", formatHexOnlyGameplayStat(gSaveContext.cutsceneIndex), COLOR_YELLOW); @@ -538,7 +539,7 @@ void DrawGameplayStatsCountsTab() { GameplayStatsRow("Sword Swings:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_SWORD_SWINGS])); GameplayStatsRow("Steps Taken:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_STEPS])); // If using MM Bunny Hood enhancement, show how long it's been equipped (not counting pause time) - if (CVarGetInteger("gMMBunnyHood", BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) { + if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) { GameplayStatsRow("Bunny Hood Time:", formatTimestampGameplayStat(gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] / 2)); } GameplayStatsRow("Rolls:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_ROLLS])); @@ -566,13 +567,13 @@ void DrawGameplayStatsBreakdownTab() { for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) { std::string sceneName = ResolveSceneID(gSaveContext.sohStats.sceneTimestamps[i].scene, gSaveContext.sohStats.sceneTimestamps[i].room); std::string name; - if (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) && gSaveContext.sohStats.sceneTimestamps[i].scene != SCENE_GROTTOS) { + if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.sohStats.sceneTimestamps[i].scene != SCENE_GROTTOS) { name = fmt::format("{:s} Room {:d}", sceneName, gSaveContext.sohStats.sceneTimestamps[i].room); } else { name = sceneName; } strcpy(sceneTimestampDisplay[i].name, name.c_str()); - sceneTimestampDisplay[i].time = CVarGetInteger("gGameplayStats.RoomBreakdown", 0) ? + sceneTimestampDisplay[i].time = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) ? gSaveContext.sohStats.sceneTimestamps[i].roomTime : gSaveContext.sohStats.sceneTimestamps[i].sceneTime; sceneTimestampDisplay[i].color = COLOR_GREY; sceneTimestampDisplay[i].isRoom = gSaveContext.sohStats.sceneTimestamps[i].isRoom; @@ -583,13 +584,13 @@ void DrawGameplayStatsBreakdownTab() { ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) { TimestampInfo tsInfo = sceneTimestampDisplay[i]; - bool canShow = !tsInfo.isRoom || CVarGetInteger("gGameplayStats.RoomBreakdown", 0); + bool canShow = !tsInfo.isRoom || CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0); if (tsInfo.time > 0 && strnlen(tsInfo.name, 40) > 1 && canShow) { GameplayStatsRow(tsInfo.name, formatTimestampGameplayStat(tsInfo.time), tsInfo.color); } } std::string toPass; - if (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) && gSaveContext.sohStats.sceneNum != SCENE_GROTTOS) { + if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.sohStats.sceneNum != SCENE_GROTTOS) { toPass = fmt::format("{:s} Room {:d}", ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum), gSaveContext.sohStats.roomNum); } else { toPass = ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum); @@ -600,21 +601,21 @@ void DrawGameplayStatsBreakdownTab() { } void DrawGameplayStatsOptionsTab() { - UIWidgets::PaddedEnhancementCheckbox("Show in-game total timer", "gGameplayStats.ShowIngameTimer", true, false); + UIWidgets::PaddedEnhancementCheckbox("Show in-game total timer", CVAR_ENHANCEMENT("GameplayStats.ShowIngameTimer"), true, false); UIWidgets::InsertHelpHoverText("Keep track of the timer as an in-game HUD element. The position of the timer can be changed in the Cosmetics Editor."); - UIWidgets::PaddedEnhancementCheckbox("Show latest timestamps on top", "gGameplayStats.TimestampsReverse", true, false); - UIWidgets::PaddedEnhancementCheckbox("Room Breakdown", "gGameplayStats.RoomBreakdown", true, false); + UIWidgets::PaddedEnhancementCheckbox("Show latest timestamps on top", CVAR_ENHANCEMENT("GameplayStats.ReverseTimestamps"), true, false); + UIWidgets::PaddedEnhancementCheckbox("Room Breakdown", CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), true, false); ImGui::SameLine(); UIWidgets::InsertHelpHoverText("Allows a more in-depth perspective of time spent in a certain map."); - UIWidgets::PaddedEnhancementCheckbox("RTA Timing on new files", "gGameplayStats.RTATiming", true, false); + UIWidgets::PaddedEnhancementCheckbox("RTA Timing on new files", CVAR_ENHANCEMENT("GameplayStats.RTATiming"), true, false); ImGui::SameLine(); UIWidgets::InsertHelpHoverText( "Timestamps are relative to starting timestamp rather than in game time, usually necessary for races/speedruns.\n\n" "Starting timestamp is on first non-c-up input after intro cutscene.\n\n" "NOTE: THIS NEEDS TO BE SET BEFORE CREATING A FILE TO TAKE EFFECT" ); - UIWidgets::PaddedEnhancementCheckbox("Show additional detail timers", "gGameplayStats.ShowAdditionalTimers", true, false); - UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", "gGameplayStats.ShowDebugInfo"); + UIWidgets::PaddedEnhancementCheckbox("Show additional detail timers", CVAR_ENHANCEMENT("GameplayStats.ShowAdditionalTimers"), true, false); + UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", CVAR_ENHANCEMENT("GameplayStats.ShowDebugInfo")); } void GameplayStatsWindow::DrawElement() { @@ -656,7 +657,7 @@ void InitStats(bool isDebug) { for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys); dungeon++) { gSaveContext.sohStats.dungeonKeys[dungeon] = isDebug ? 8 : 0; } - gSaveContext.sohStats.rtaTiming = CVarGetInteger("gGameplayStats.RTATiming", 0); + gSaveContext.sohStats.rtaTiming = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RTATiming"), 0); gSaveContext.sohStats.fileCreatedAt = 0; gSaveContext.sohStats.playTimer = 0; gSaveContext.sohStats.pauseTimer = 0; diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index 8772dd37f..528da33f9 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -12,7 +12,7 @@ (!gSaveContext.sohStats.fileCreatedAt ? 0 : ((GetUnixTimestamp() - gSaveContext.sohStats.fileCreatedAt) / 100)) :\ (gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON])) :\ (gSaveContext.sohStats.playTimer / 2 + gSaveContext.sohStats.pauseTimer / 3)) -#define CURRENT_MODE_TIMER (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) ?\ +#define CURRENT_MODE_TIMER (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) ?\ gSaveContext.sohStats.roomTimer :\ gSaveContext.sohStats.sceneTimer) diff --git a/soh/soh/Enhancements/gameplaystatswindow.h b/soh/soh/Enhancements/gameplaystatswindow.h index 2a3786415..453b24559 100644 --- a/soh/soh/Enhancements/gameplaystatswindow.h +++ b/soh/soh/Enhancements/gameplaystatswindow.h @@ -1,7 +1,7 @@ #include #include "gameplaystats.h" -class GameplayStatsWindow : public LUS::GuiWindow { +class GameplayStatsWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; diff --git a/soh/soh/Enhancements/item-tables/ItemTableTypes.h b/soh/soh/Enhancements/item-tables/ItemTableTypes.h index f16762db9..6282275b1 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableTypes.h +++ b/soh/soh/Enhancements/item-tables/ItemTableTypes.h @@ -30,10 +30,13 @@ typedef enum GetItemCategory { } GetItemCategory; #define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, getItemId) \ - { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, NULL } + { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, modIndex, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, NULL } + +#define GET_ITEM_CUSTOM_TABLE(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, tableId, getItemId) \ + { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, tableId, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, NULL } #define GET_ITEM_NONE \ - { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, NULL } + { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, NULL } typedef struct PlayState PlayState; typedef struct GetItemEntry GetItemEntry; @@ -46,7 +49,8 @@ typedef struct GetItemEntry { /* 0x02 */ int16_t gi; // defines the draw id and chest opening animation /* 0x03 */ uint16_t textId; /* 0x04 */ uint16_t objectId; - /* 0x06 */ uint16_t modIndex; // 0 = Vanilla, 1 = Randomizer, future mods will increment up? + /* 0x06 */ uint16_t modIndex; // Primarily used for determining whether to use Item_Give or Randomizer_Item_Give + /* 0x07 */ uint16_t tableId; // GetItemEntry table this entry is in (usually the same as modIndex, but not always) /* 0x08 */ int16_t getItemId; /* 0x0A */ uint16_t gid; // Stores the GID value unmodified for future reference. /* 0x0C */ uint16_t collectable; // determines whether the item can be collected on the overworld. Will be true in most cases. diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 258fbba42..9a3988e39 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -23,32 +23,50 @@ #include "src/overlays/actors/ovl_En_Tp/z_en_tp.h" #include "src/overlays/actors/ovl_En_Firefly/z_en_firefly.h" #include "src/overlays/actors/ovl_En_Xc/z_en_xc.h" +#include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h" +#include "objects/object_link_boy/object_link_boy.h" +#include "objects/object_link_child/object_link_child.h" extern "C" { #include +#include "align_asset_macro.h" #include "macros.h" #include "functions.h" #include "variables.h" #include "functions.h" +#include "src/overlays/actors/ovl_En_Door/z_en_door.h" +void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); +void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName); + extern SaveContext gSaveContext; extern PlayState* gPlayState; extern void Overlay_DisplayText(float duration, const char* text); uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); } +// GreyScaleEndDlist +#define dgEndGrayscaleAndEndDlistDL "__OTR__helpers/cosmetics/gEndGrayscaleAndEndDlistDL" +static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL; + +// This is used for the Temple of Time Medalions' color +#define dtokinoma_room_0DL_007A70 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007A70" +static const ALIGN_ASSET(2) char tokinoma_room_0DL_007A70[] = dtokinoma_room_0DL_007A70; +#define dtokinoma_room_0DL_007FD0 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007FD0" +static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL_007FD0; + // TODO: When there's more uses of something like this, create a new GI::RawAction? void ReloadSceneTogglingLinkAge() { gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; - gPlayState->sceneLoadFlag = 0x14; - gPlayState->fadeTransition = 42; // Fade Out - gSaveContext.nextTransitionType = 42; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); // Fade Out + gSaveContext.nextTransitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); gPlayState->linkAgeOnLoad ^= 1; // toggle linkAgeOnLoad } void RegisterInfiniteMoney() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gInfiniteMoney", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("InfiniteMoney"), 0) != 0) { if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) { gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET); } @@ -59,7 +77,7 @@ void RegisterInfiniteMoney() { void RegisterInfiniteHealth() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gInfiniteHealth", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("InfiniteHealth"), 0) != 0) { if (gSaveContext.health < gSaveContext.healthCapacity) { gSaveContext.health = gSaveContext.healthCapacity; } @@ -70,7 +88,7 @@ void RegisterInfiniteHealth() { void RegisterInfiniteAmmo() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gInfiniteAmmo", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("InfiniteAmmo"), 0) != 0) { // Deku Sticks if (AMMO(ITEM_STICK) < CUR_CAPACITY(UPG_STICKS)) { AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); @@ -107,7 +125,7 @@ void RegisterInfiniteAmmo() { void RegisterInfiniteMagic() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gInfiniteMagic", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("InfiniteMagic"), 0) != 0) { if (gSaveContext.isMagicAcquired && gSaveContext.magic != (gSaveContext.isDoubleMagicAcquired + 1) * 0x30) { gSaveContext.magic = (gSaveContext.isDoubleMagicAcquired + 1) * 0x30; } @@ -118,7 +136,7 @@ void RegisterInfiniteMagic() { void RegisterInfiniteNayrusLove() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gInfiniteNayru", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("InfiniteNayru"), 0) != 0) { gSaveContext.nayrusLoveTimer = 0x44B; } }); @@ -128,7 +146,7 @@ void RegisterMoonJumpOnL() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gMoonJumpOnL", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("MoonJumpOnL"), 0) != 0) { Player* player = GET_PLAYER(gPlayState); if (CHECK_BTN_ANY(gPlayState->state.input[0].cur.button, BTN_L)) { @@ -143,7 +161,7 @@ void RegisterInfiniteISG() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gEzISG", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("EasyISG"), 0) != 0) { Player* player = GET_PLAYER(gPlayState); player->meleeWeaponState = 1; } @@ -155,7 +173,7 @@ void RegisterEzQPA() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gEzQPA", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("EasyQPA"), 0) != 0) { Player* player = GET_PLAYER(gPlayState); player->meleeWeaponQuads[0].info.toucher.dmgFlags = 0x16171617; player->meleeWeaponQuads[1].info.toucher.dmgFlags = 0x16171617; @@ -167,7 +185,7 @@ void RegisterUnrestrictedItems() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger("gNoRestrictItems", 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("NoRestrictItems"), 0) != 0) { u8 sunsBackup = gPlayState->interfaceCtx.restrictions.sunsSong; memset(&gPlayState->interfaceCtx.restrictions, 0, sizeof(gPlayState->interfaceCtx.restrictions)); gPlayState->interfaceCtx.restrictions.sunsSong = sunsBackup; @@ -177,15 +195,15 @@ void RegisterUnrestrictedItems() { void RegisterFreezeTime() { GameInteractor::Instance->RegisterGameHook([]() { - if (CVarGetInteger("gFreezeTime", 0) != 0) { - if (CVarGetInteger("gPrevTime", -1) == -1) { - CVarSetInteger("gPrevTime", gSaveContext.dayTime); + if (CVarGetInteger(CVAR_CHEAT("FreezeTime"), 0) != 0) { + if (CVarGetInteger(CVAR_GENERAL("PrevTime"), -1) == -1) { + CVarSetInteger(CVAR_GENERAL("PrevTime"), gSaveContext.dayTime); } - int32_t prevTime = CVarGetInteger("gPrevTime", gSaveContext.dayTime); + int32_t prevTime = CVarGetInteger(CVAR_GENERAL("PrevTime"), gSaveContext.dayTime); gSaveContext.dayTime = prevTime; } else { - CVarClear("gPrevTime"); + CVarClear(CVAR_GENERAL("PrevTime")); } }); } @@ -196,7 +214,7 @@ void RegisterSwitchAge() { static bool warped = false; if (!GameInteractor::IsSaveLoaded(true)) { - CVarClear("gSwitchAge"); + CVarClear(CVAR_GENERAL("SwitchAge")); warped = false; return; } @@ -206,7 +224,7 @@ void RegisterSwitchAge() { static RoomContext* roomCtx; static s32 roomNum; - if (CVarGetInteger("gSwitchAge", 0) && !warped) { + if (CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) && !warped) { playerPos = GET_PLAYER(gPlayState)->actor.world.pos; playerYaw = GET_PLAYER(gPlayState)->actor.shape.rot.y; roomCtx = &gPlayState->roomCtx; @@ -215,8 +233,8 @@ void RegisterSwitchAge() { warped = true; } - if (warped && gPlayState->sceneLoadFlag != 0x0014 && - gSaveContext.nextTransitionType == 255) { + if (warped && gPlayState->transitionTrigger != TRANS_TRIGGER_START && + gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) { GET_PLAYER(gPlayState)->actor.shape.rot.y = playerYaw; GET_PLAYER(gPlayState)->actor.world.pos = playerPos; if (roomNum != roomCtx->curRoom.num) { @@ -225,7 +243,7 @@ void RegisterSwitchAge() { func_80097534(gPlayState, roomCtx); // load map for new room (unloading the previous room) } warped = false; - CVarClear("gSwitchAge"); + CVarClear(CVAR_GENERAL("SwitchAge")); } }); } @@ -235,7 +253,7 @@ void RegisterOcarinaTimeTravel() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) { - CVarClear("gTimeTravel"); + CVarClear(CVAR_ENHANCEMENT("TimeTravel")); return; } @@ -249,16 +267,16 @@ void RegisterOcarinaTimeTravel() { uint8_t hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); // If TimeTravel + Player have the Ocarina of Time + Have Master Sword + is in proper range // TODO: Once Swordless Adult is fixed: Remove the Master Sword check - if (((CVarGetInteger("gTimeTravel", 0) == 1 && hasOcarinaOfTime) || CVarGetInteger("gTimeTravel", 0) == 2) && hasMasterSword && + if (((CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 1 && hasOcarinaOfTime) || CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2) && hasMasterSword && gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyFrogs) { if (IS_RANDO) { - CVarSetInteger("gSwitchTimeline", 1); + CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1); } else if (!IS_RANDO && !nearbyDoorOfTime) { // This check is made for when Link is learning the Song Of Time in a vanilla save file that load a // Temple of Time scene where the only object present is the Door of Time - CVarSetInteger("gSwitchTimeline", 1); + CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1); } ReloadSceneTogglingLinkAge(); } @@ -271,13 +289,13 @@ void AutoSave(GetItemEntry itemEntry) { // Don't autosave immediately after buying items from shops to prevent getting them for free! // Don't autosave in the Chamber of Sages since resuming from that map breaks the game // Don't autosave during the Ganon fight when picking up the Master Sword - if ((CVarGetInteger("gAutosave", AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) && + if ((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) && (gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0) && (gPlayState->sceneNum != SCENE_GANON_BOSS) && (gPlayState->sceneNum != SCENE_CHAMBER_OF_THE_SAGES)) { - if (((CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS) || (CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_ALL_ITEMS)) && (item != ITEM_NONE)) { + if (((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS) || (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_ALL_ITEMS)) && (item != ITEM_NONE)) { // Autosave for all items performSave = true; - } else if (((CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS) || (CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_MAJOR_ITEMS)) && (item != ITEM_NONE)) { + } else if (((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS) || (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_MAJOR_ITEMS)) && (item != ITEM_NONE)) { // Autosave for major items if (itemEntry.modIndex == 0) { switch (item) { @@ -317,7 +335,7 @@ void AutoSave(GetItemEntry itemEntry) { case ITEM_BOMBCHU: case ITEM_BOMBCHUS_5: case ITEM_BOMBCHUS_20: - if (!CVarGetInteger("gBombchuDrops", 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("BombchuDrops"), 0)) { performSave = true; } break; @@ -328,9 +346,9 @@ void AutoSave(GetItemEntry itemEntry) { } else if (itemEntry.modIndex == 1 && item != RG_ICE_TRAP) { performSave = true; } - } else if (CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS || - CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS || - CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION) { + } else if (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS || + CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS || + CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION) { performSave = true; } if (performSave) { @@ -348,13 +366,13 @@ void RegisterAutoSave() { void RegisterRupeeDash() { GameInteractor::Instance->RegisterGameHook([]() { - if (!CVarGetInteger("gRupeeDash", 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("RupeeDash"), 0)) { return; } // Initialize Timer static uint16_t rupeeDashTimer = 0; - uint16_t rdmTime = CVarGetInteger("gDashInterval", 5) * 20; + uint16_t rdmTime = CVarGetInteger(CVAR_ENHANCEMENT("RupeeDashInterval"), 5) * 20; // Did time change by DashInterval? if (rupeeDashTimer >= rdmTime) { @@ -376,7 +394,7 @@ void RegisterShadowTag() { static uint16_t delayTimer = 60; GameInteractor::Instance->RegisterGameHook([]() { - if (!CVarGetInteger("gShadowTag", 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("ShadowTag"), 0)) { return; } if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && // Forest Temple Scene @@ -403,6 +421,52 @@ void RegisterShadowTag() { }); } +static bool hasAffectedHealth = false; +void UpdatePermanentHeartLossState() { + if (!GameInteractor::IsSaveLoaded()) return; + + if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) && hasAffectedHealth) { + uint8_t heartContainers = gSaveContext.sohStats.heartContainers; // each worth 16 health + uint8_t heartPieces = gSaveContext.sohStats.heartPieces; // each worth 4 health, but only in groups of 4 + uint8_t startingHealth = 16 * 3; + + + uint8_t newCapacity = startingHealth + (heartContainers * 16) + ((heartPieces - (heartPieces % 4)) * 4); + gSaveContext.healthCapacity = MAX(newCapacity, gSaveContext.healthCapacity); + gSaveContext.health = MIN(gSaveContext.health, gSaveContext.healthCapacity); + hasAffectedHealth = false; + } +} + +void RegisterPermanentHeartLoss() { + GameInteractor::Instance->RegisterGameHook([](int16_t fileNum) { + hasAffectedHealth = false; + UpdatePermanentHeartLossState(); + }); + + GameInteractor::Instance->RegisterGameHook([]() { + if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) || !GameInteractor::IsSaveLoaded()) return; + + if (gSaveContext.healthCapacity > 16 && gSaveContext.healthCapacity - gSaveContext.health >= 16) { + gSaveContext.healthCapacity -= 16; + gSaveContext.health = MIN(gSaveContext.health, gSaveContext.healthCapacity); + hasAffectedHealth = true; + } + }); +}; + +void RegisterDeleteFileOnDeath() { + GameInteractor::Instance->RegisterGameHook([]() { + if (!CVarGetInteger(CVAR_ENHANCEMENT("DeleteFileOnDeath"), 0) || !GameInteractor::IsSaveLoaded() || &gPlayState->gameOverCtx == NULL || &gPlayState->pauseCtx == NULL) return; + + if (gPlayState->gameOverCtx.state == GAMEOVER_DEATH_MENU && gPlayState->pauseCtx.state == 9) { + SaveManager::Instance->DeleteZeldaFile(gSaveContext.fileNum); + hasAffectedHealth = false; + std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch("reset"); + } + }); +} + struct DayTimeGoldSkulltulas { uint16_t scene; uint16_t room; @@ -414,7 +478,7 @@ using DayTimeGoldSkulltulasList = std::vector; void RegisterDaytimeGoldSkultullas() { GameInteractor::Instance->RegisterGameHook([]() { - if (!CVarGetInteger("gNightGSAlwaysSpawn", 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("NightGSAlwaysSpawn"), 0)) { return; } @@ -459,75 +523,98 @@ void RegisterDaytimeGoldSkultullas() { }); } -void RegisterHyperBosses() { - GameInteractor::Instance->RegisterGameHook([](void* refActor) { - // Run the update function a second time to make bosses move and act twice as fast. +bool IsHyperBossesActive() { + return CVarGetInteger(CVAR_ENHANCEMENT("HyperBosses"), 0) || + (IS_BOSS_RUSH && gSaveContext.bossRushOptions[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES); +} - Player* player = GET_PLAYER(gPlayState); - Actor* actor = static_cast(refActor); +void UpdateHyperBossesState() { + static uint32_t actorUpdateHookId = 0; + if (actorUpdateHookId != 0) { + GameInteractor::Instance->UnregisterGameHook(actorUpdateHookId); + actorUpdateHookId = 0; + } - uint8_t isBossActor = - actor->id == ACTOR_BOSS_GOMA || // Gohma - actor->id == ACTOR_BOSS_DODONGO || // King Dodongo - actor->id == ACTOR_EN_BDFIRE || // King Dodongo Fire Breath - actor->id == ACTOR_BOSS_VA || // Barinade - actor->id == ACTOR_BOSS_GANONDROF || // Phantom Ganon - actor->id == ACTOR_EN_FHG_FIRE || // Phantom Ganon/Ganondorf Energy Ball/Thunder - actor->id == ACTOR_EN_FHG || // Phantom Ganon's Horse - actor->id == ACTOR_BOSS_FD || actor->id == ACTOR_BOSS_FD2 || // Volvagia (grounded/flying) - actor->id == ACTOR_EN_VB_BALL || // Volvagia Rocks - actor->id == ACTOR_BOSS_MO || // Morpha - actor->id == ACTOR_BOSS_SST || // Bongo Bongo - actor->id == ACTOR_BOSS_TW || // Twinrova - actor->id == ACTOR_BOSS_GANON || // Ganondorf - actor->id == ACTOR_BOSS_GANON2; // Ganon + if (IsHyperBossesActive()) { + actorUpdateHookId = GameInteractor::Instance->RegisterGameHook([](void* refActor) { + // Run the update function a second time to make bosses move and act twice as fast. - uint8_t hyperBossesActive = - CVarGetInteger("gHyperBosses", 0) || - (IS_BOSS_RUSH && - gSaveContext.bossRushOptions[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES); + Player* player = GET_PLAYER(gPlayState); + Actor* actor = static_cast(refActor); - // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses. - if (hyperBossesActive && isBossActor && !Player_InBlockingCsMode(gPlayState, player)) { - // Barinade needs to be updated in sequence to avoid unintended behaviour. - if (actor->id == ACTOR_BOSS_VA) { - // params -1 is BOSSVA_BODY - if (actor->params == -1) { - Actor* actorList = gPlayState->actorCtx.actorLists[ACTORCAT_BOSS].head; - while (actorList != NULL) { - GameInteractor::RawAction::UpdateActor(actorList); - actorList = actorList->next; + uint8_t isBossActor = + actor->id == ACTOR_BOSS_GOMA || // Gohma + actor->id == ACTOR_BOSS_DODONGO || // King Dodongo + actor->id == ACTOR_EN_BDFIRE || // King Dodongo Fire Breath + actor->id == ACTOR_BOSS_VA || // Barinade + actor->id == ACTOR_BOSS_GANONDROF || // Phantom Ganon + actor->id == ACTOR_EN_FHG_FIRE || // Phantom Ganon/Ganondorf Energy Ball/Thunder + actor->id == ACTOR_EN_FHG || // Phantom Ganon's Horse + actor->id == ACTOR_BOSS_FD || actor->id == ACTOR_BOSS_FD2 || // Volvagia (grounded/flying) + actor->id == ACTOR_EN_VB_BALL || // Volvagia Rocks + actor->id == ACTOR_BOSS_MO || // Morpha + actor->id == ACTOR_BOSS_SST || // Bongo Bongo + actor->id == ACTOR_BOSS_TW || // Twinrova + actor->id == ACTOR_BOSS_GANON || // Ganondorf + actor->id == ACTOR_BOSS_GANON2; // Ganon + + // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses. + if (IsHyperBossesActive() && isBossActor && !Player_InBlockingCsMode(gPlayState, player)) { + // Barinade needs to be updated in sequence to avoid unintended behaviour. + if (actor->id == ACTOR_BOSS_VA) { + // params -1 is BOSSVA_BODY + if (actor->params == -1) { + Actor* actorList = gPlayState->actorCtx.actorLists[ACTORCAT_BOSS].head; + while (actorList != NULL) { + GameInteractor::RawAction::UpdateActor(actorList); + actorList = actorList->next; + } } + } else { + GameInteractor::RawAction::UpdateActor(actor); } - } else { - GameInteractor::RawAction::UpdateActor(actor); } - } + }); + } +} + +void RegisterHyperBosses() { + UpdateHyperBossesState(); + GameInteractor::Instance->RegisterGameHook([](int16_t fileNum) { + UpdateHyperBossesState(); }); } -void RegisterHyperEnemies() { - GameInteractor::Instance->RegisterGameHook([](void* refActor) { - // Run the update function a second time to make enemies and minibosses move and act twice as fast. +void UpdateHyperEnemiesState() { + static uint32_t actorUpdateHookId = 0; + if (actorUpdateHookId != 0) { + GameInteractor::Instance->UnregisterGameHook(actorUpdateHookId); + actorUpdateHookId = 0; + } - Player* player = GET_PLAYER(gPlayState); - Actor* actor = static_cast(refActor); + if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0)) { + actorUpdateHookId = GameInteractor::Instance->RegisterGameHook([](void* refActor) { + // Run the update function a second time to make enemies and minibosses move and act twice as fast. - // Some enemies are not in the ACTORCAT_ENEMY category, and some are that aren't really enemies. - bool isEnemy = actor->category == ACTORCAT_ENEMY || actor->id == ACTOR_EN_TORCH2; - bool isExcludedEnemy = actor->id == ACTOR_EN_FIRE_ROCK || actor->id == ACTOR_EN_ENCOUNT2; + Player* player = GET_PLAYER(gPlayState); + Actor* actor = static_cast(refActor); - // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some cutscenes. - if (CVarGetInteger("gHyperEnemies", 0) && isEnemy && !isExcludedEnemy && - !Player_InBlockingCsMode(gPlayState, player)) { - GameInteractor::RawAction::UpdateActor(actor); - } - }); + // Some enemies are not in the ACTORCAT_ENEMY category, and some are that aren't really enemies. + bool isEnemy = actor->category == ACTORCAT_ENEMY || actor->id == ACTOR_EN_TORCH2; + bool isExcludedEnemy = actor->id == ACTOR_EN_FIRE_ROCK || actor->id == ACTOR_EN_ENCOUNT2; + + // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some cutscenes. + if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0) && isEnemy && !isExcludedEnemy && + !Player_InBlockingCsMode(gPlayState, player)) { + GameInteractor::RawAction::UpdateActor(actor); + } + }); + } } void RegisterBonkDamage() { GameInteractor::Instance->RegisterGameHook([]() { - uint8_t bonkOption = CVarGetInteger("gBonkDamageMul", BONK_DAMAGE_NONE); + uint8_t bonkOption = CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE); if (bonkOption == BONK_DAMAGE_NONE) { return; } @@ -573,10 +660,10 @@ void UpdateDirtPathFixState(int32_t sceneNum) { case SCENE_HYRULE_FIELD: case SCENE_KOKIRI_FOREST: case SCENE_HYRULE_CASTLE: - CVarSetInteger("gZFightingMode", CVarGetInteger("gSceneSpecificDirtPathFix", ZFIGHT_FIX_DISABLED)); + CVarSetInteger(CVAR_Z_FIGHTING_MODE, CVarGetInteger(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), ZFIGHT_FIX_DISABLED)); return; default: - CVarClear("gZFightingMode"); + CVarClear(CVAR_Z_FIGHTING_MODE); } } @@ -590,7 +677,7 @@ void UpdateMirrorModeState(int32_t sceneNum) { static bool prevMirroredWorld = false; bool nextMirroredWorld = false; - int16_t mirroredMode = CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF); + int16_t mirroredMode = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorldMode"), MIRRORED_WORLD_OFF); int16_t inDungeon = (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_INSIDE_GANONS_CASTLE_COLLAPSE && sceneNum != SCENE_THIEVES_HIDEOUT) || (sceneNum >= SCENE_DEKU_TREE_BOSS && sceneNum <= SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) || (sceneNum == SCENE_GANON_BOSS); @@ -612,10 +699,10 @@ void UpdateMirrorModeState(int32_t sceneNum) { ((mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) && randomMirror))) ) { nextMirroredWorld = true; - CVarSetInteger("gMirroredWorld", 1); + CVarSetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 1); } else { nextMirroredWorld = false; - CVarClear("gMirroredWorld"); + CVarClear(CVAR_ENHANCEMENT("MirroredWorld")); } if (prevMirroredWorld != nextMirroredWorld) { @@ -630,6 +717,62 @@ void RegisterMirrorModeHandler() { }); } +void UpdatePatchHand() { + if ((CVarGetInteger(CVAR_ENHANCEMENT("EquimentAlwaysVisible"), 0)) && LINK_IS_CHILD) { + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer1", 92, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer2", 93, gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot1", 84, gsSPDisplayListOTRFilePath(gLinkChildRightHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot2", 85, gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingBowNearDL, "childBow1", 51, gsSPDisplayListOTRFilePath(gLinkChildRightHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingBowNearDL, "childBow2", 52, gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword1", 104, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword2", 105, gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword1", 79, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword2", 80, gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife1", 76, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife2", 77, gsSPEndDisplayList()); + + } else { + ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer1"); + ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer2"); + ResourceMgr_UnpatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot1"); + ResourceMgr_UnpatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot2"); + ResourceMgr_UnpatchGfxByName(gLinkAdultRightHandHoldingBowNearDL, "childBow1"); + ResourceMgr_UnpatchGfxByName(gLinkAdultRightHandHoldingBowNearDL, "childBow2"); + ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword1"); + ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword2"); + ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword1"); + ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword2"); + ResourceMgr_UnpatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife1"); + ResourceMgr_UnpatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife2"); + } + if ((CVarGetInteger(CVAR_ENHANCEMENT("EquimentAlwaysVisible"), 0)) && LINK_IS_ADULT) { + ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndKokiriSwordNearDL, "adultKokiriSword", 13, gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkChildRightHandHoldingSlingshotNearDL, "adultSlingshot", 13, gsSPDisplayListOTRFilePath(gLinkAdultRightHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndBoomerangNearDL, "adultBoomerang", 50, gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkChildRightFistAndDekuShieldNearDL, "adultDekuShield", 49, gsSPDisplayListOTRFilePath(gLinkAdultRightHandClosedNearDL)); + } else { + ResourceMgr_UnpatchGfxByName(gLinkChildLeftFistAndKokiriSwordNearDL, "adultKokiriSword"); + ResourceMgr_UnpatchGfxByName(gLinkChildRightHandHoldingSlingshotNearDL, "adultSlingshot"); + ResourceMgr_UnpatchGfxByName(gLinkChildLeftFistAndBoomerangNearDL, "adultBoomerang"); + ResourceMgr_UnpatchGfxByName(gLinkChildRightFistAndDekuShieldNearDL, "adultDekuShield"); + } +} + +void RegisterPatchHandHandler() { + GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { + UpdatePatchHand(); + }); +} + +void RegisterResetNaviTimer() { + GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { + if (CVarGetInteger(CVAR_ENHANCEMENT("ResetNaviTimer"), 0)) { + gSaveContext.naviTimer = 0; + } + }); +} + f32 triforcePieceScale; void RegisterTriforceHunt() { @@ -639,10 +782,10 @@ void RegisterTriforceHunt() { // Warp to credits if (GameInteractor::State::TriforceHuntCreditsWarpActive) { - gPlayState->nextEntranceIndex = 0x6B; + gPlayState->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; gSaveContext.nextCutsceneIndex = 0xFFF2; - gPlayState->sceneLoadFlag = 0x14; - gPlayState->fadeTransition = 3; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; GameInteractor::State::TriforceHuntCreditsWarpActive = 0; } @@ -655,16 +798,19 @@ void RegisterTriforceHunt() { triforcePieceScale = 0.0f; GameInteractor::State::TriforceHuntPieceGiven = 0; } + } + }); +} - uint8_t currentPieces = gSaveContext.triforcePiecesCollected; - uint8_t requiredPieces = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED); - - // Give Boss Key when player loads back into the savefile. - if (currentPieces >= requiredPieces && gPlayState->sceneLoadFlag != 0x14 && - (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0) { - GetItemEntry getItemEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY); +void RegisterGrantGanonsBossKey() { + GameInteractor::Instance->RegisterGameHook([]() { + // Triforce Hunt needs the check if the player isn't being teleported to the credits scene. + if (!GameInteractor::IsGameplayPaused() && IS_RANDO && + Flags_GetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY) && gPlayState->transitionTrigger != TRANS_TRIGGER_START && + (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0) { + GetItemEntry getItemEntry = + ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY); GiveItemEntryWithoutActor(gPlayState, getItemEntry); - } } }); } @@ -875,16 +1021,16 @@ typedef enum { } AltTrapType; const char* altTrapTypeCvars[] = { - "gAddTraps.Ice", - "gAddTraps.Burn", - "gAddTraps.Shock", - "gAddTraps.Knock", - "gAddTraps.Speed", - "gAddTraps.Bomb", - "gAddTraps.Void", - "gAddTraps.Ammo", - "gAddTraps.Kill", - "gAddTraps.Tele" + CVAR_ENHANCEMENT("ExtraTraps.Ice"), + CVAR_ENHANCEMENT("ExtraTraps.Burn"), + CVAR_ENHANCEMENT("ExtraTraps.Shock"), + CVAR_ENHANCEMENT("ExtraTraps.Knockback"), + CVAR_ENHANCEMENT("ExtraTraps.Speed"), + CVAR_ENHANCEMENT("ExtraTraps.Bomb"), + CVAR_ENHANCEMENT("ExtraTraps.Void"), + CVAR_ENHANCEMENT("ExtraTraps.Ammo"), + CVAR_ENHANCEMENT("ExtraTraps.Kill"), + CVAR_ENHANCEMENT("ExtraTraps.Teleport") }; std::vector getEnabledAddTraps () { @@ -906,7 +1052,7 @@ void RegisterAltTrapTypes() { static int eventTimer = -1; GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { - if (!CVarGetInteger("gAddTraps.enabled", 0) || itemEntry.modIndex != MOD_RANDOMIZER || itemEntry.getItemId != RG_ICE_TRAP) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) || itemEntry.modIndex != MOD_RANDOMIZER || itemEntry.getItemId != RG_ICE_TRAP) { return; } roll = RandomElement(getEnabledAddTraps()); @@ -1030,6 +1176,29 @@ void RegisterRandomizerSheikSpawn() { }); } +void UpdateHurtContainerModeState(bool newState) { + static bool hurtEnabled = false; + if (hurtEnabled == newState) { + return; + } + + hurtEnabled = newState; + uint16_t getHeartPieces = gSaveContext.sohStats.heartPieces / 4; + uint16_t getHeartContainers = gSaveContext.sohStats.heartContainers; + + if (hurtEnabled) { + gSaveContext.healthCapacity = 320 - ((getHeartPieces + getHeartContainers) * 16); + } else { + gSaveContext.healthCapacity = 48 + ((getHeartPieces + getHeartContainers) * 16); + } +} + +void RegisterHurtContainerModeHandler() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + UpdateHurtContainerModeState(CVarGetInteger(CVAR_ENHANCEMENT("HurtContainer"), 0)); + }); +} + void RegisterRandomizedEnemySizes() { GameInteractor::Instance->RegisterGameHook([](void* refActor) { // Randomized Enemy Sizes @@ -1045,7 +1214,7 @@ void RegisterRandomizedEnemySizes() { actor->id == ACTOR_BOSS_FD2 || actor->id == ACTOR_EN_DH; // Only apply to enemies and bosses. - if (!CVarGetInteger("gRandomizedEnemySizes", 0) || (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || excludedEnemy) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemySizes"), 0) || (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || excludedEnemy) { return; } @@ -1067,6 +1236,161 @@ void RegisterRandomizedEnemySizes() { } Actor_SetScale(actor, actor->scale.z * randomScale); + + if (CVarGetInteger(CVAR_ENHANCEMENT("EnemySizeScalesHealth"), 0) && (actor->category == ACTORCAT_ENEMY)) { + // Scale the health based on a smaller factor than randomScale + float healthScalingFactor = 0.8f; // Adjust this factor as needed + float scaledHealth = actor->colChkInfo.health * (randomScale * healthScalingFactor); + + // Ensure the scaled health doesn't go below zero + actor->colChkInfo.health = fmax(scaledHealth, 1.0f); + } else { + return; + } + }); +} + +void RegisterOpenAllHours() { + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + Actor* actor = static_cast(refActor); + + if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR)) { + switch (actor->params) { + case 4753: // Night Market Bazaar + case 1678: // Night Potion Shop + case 2689: // Day Bombchu Shop + case 2703: // Night Slingshot Game + case 653: // Day Chest Game + case 6801: // Night Kak Bazaar + case 7822: // Night Kak Potion Shop + case 4751: // Night Kak Archery Game + case 3728: // Night Mask Shop + { + actor->params = (actor->params & 0xFC00) | (DOOR_SCENEEXIT << 7) | 0x3F; + EnDoor* enDoor = static_cast(refActor); + EnDoor_SetupType(enDoor, gPlayState); + break; + } + default: + break; + } + } + }); +} + +void PatchToTMedallions() { + // TODO: Refactor the DemoEffect_UpdateJewelAdult and DemoEffect_UpdateJewelChild from z_demo_effect + // effects to take effect in there + if (CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale", 7, gsSPGrayscale(true)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale", 7, gsSPGrayscale(true)); + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, gsDPSetGrayscaleColor(0, 161, 255, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, gsDPSetGrayscaleColor(255, 135, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_LIGHT)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, gsDPSetGrayscaleColor(255, 255, 0, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, gsDPSetGrayscaleColor(255, 255, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, gsDPSetGrayscaleColor(0, 255, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, gsDPSetGrayscaleColor(255, 0, 0, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, gsDPSetGrayscaleColor(212, 0, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, gsDPSetGrayscaleColor(212, 0, 255, 255)); + } else { + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, gsDPSetGrayscaleColor(255, 255, 255, 255)); + } + + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist", 160, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist", 51, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + } else { + // Unpatch everything + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale"); + + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple"); + + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist"); + ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist"); + } +} + +void RegisterToTMedallions() { + GameInteractor::Instance->RegisterGameHook([](GetItemEntry _unused) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || !gPlayState || gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) { + return; + } + PatchToTMedallions(); + }); + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || sceneNum != SCENE_TEMPLE_OF_TIME) { + return; + } + PatchToTMedallions(); + }); +} + + +void RegisterFloorSwitchesHook() { + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + Actor* actor = static_cast(refActor); + if (actor->id != ACTOR_OBJ_SWITCH || !CVarGetInteger(CVAR_ENHANCEMENT("FixFloorSwitches"), 0)) { + return; + } + + ObjSwitch* switchActor = reinterpret_cast(actor); + s32 type = (switchActor->dyna.actor.params & 7); + + if (switchActor->dyna.actor.params == 0x1200 || switchActor->dyna.actor.params == 0x3A00) { + switchActor->dyna.actor.world.pos.y -= 1; + } + }); +} + +void RegisterPauseMenuHooks() { + static bool pauseWarpHooksRegistered = false; + GameInteractor::Instance->RegisterGameHook([&]() { + if (!GameInteractor::IsSaveLoaded() || !CVarGetInteger(CVAR_ENHANCEMENT("PauseWarp"), 0)) { + pauseWarpHooksRegistered = false; + return; + } + if (!pauseWarpHooksRegistered) { + GameInteractor::Instance->RegisterGameHook([]() {PauseWarp_HandleSelection();}); + GameInteractor::Instance->RegisterGameHook([]() { + PauseWarp_Execute(); + }); + pauseWarpHooksRegistered = true; + } }); } @@ -1088,15 +1412,25 @@ void InitMods() { RegisterDaytimeGoldSkultullas(); RegisterRupeeDash(); RegisterShadowTag(); + RegisterPermanentHeartLoss(); + RegisterDeleteFileOnDeath(); RegisterHyperBosses(); - RegisterHyperEnemies(); + UpdateHyperEnemiesState(); RegisterBonkDamage(); RegisterMenuPathFix(); RegisterMirrorModeHandler(); + RegisterResetNaviTimer(); RegisterTriforceHunt(); + RegisterGrantGanonsBossKey(); RegisterEnemyDefeatCounts(); RegisterAltTrapTypes(); RegisterRandomizerSheikSpawn(); RegisterRandomizedEnemySizes(); + RegisterOpenAllHours(); + RegisterToTMedallions(); NameTag_RegisterHooks(); + RegisterFloorSwitchesHook(); + RegisterPatchHandHandler(); + RegisterHurtContainerModeHandler(); + RegisterPauseMenuHooks(); } diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h index 2f0430475..2755924f2 100644 --- a/soh/soh/Enhancements/mods.h +++ b/soh/soh/Enhancements/mods.h @@ -9,7 +9,13 @@ extern "C" { void UpdateDirtPathFixState(int32_t sceneNum); void UpdateMirrorModeState(int32_t sceneNum); +void UpdateHurtContainerModeState(bool newState); +void PatchToTMedallions(); +void UpdatePermanentHeartLossState(); +void UpdateHyperEnemiesState(); +void UpdateHyperBossesState(); void InitMods(); +void UpdatePatchHand(); #ifdef __cplusplus } diff --git a/soh/soh/Enhancements/nametag.cpp b/soh/soh/Enhancements/nametag.cpp index 038ba4e1f..2adc3fffb 100644 --- a/soh/soh/Enhancements/nametag.cpp +++ b/soh/soh/Enhancements/nametag.cpp @@ -5,6 +5,7 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/OTRGlobals.h" extern "C" { #include "z64.h" @@ -70,11 +71,11 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) { Color_RGBA8 textboxColor = { 0, 0, 0, 80}; Color_RGBA8 textColor = { 255, 255, 255, 255 }; - if (CVarGetInteger("gCosmetics.Hud_NameTagActorBackground.Changed", 0)) { - textboxColor = CVarGetColor("gCosmetics.Hud_NameTagActorBackground.Value", textboxColor); + if (CVarGetInteger(CVAR_COSMETIC("HUD.NameTagActorBackground.Changed"), 0)) { + textboxColor = CVarGetColor(CVAR_COSMETIC("HUD.NameTagActorBackground.Value"), textboxColor); } - if (CVarGetInteger("gCosmetics.Hud_NameTagActorText.Changed", 0)) { - textColor = CVarGetColor("gCosmetics.Hud_NameTagActorText.Value", textColor); + if (CVarGetInteger(CVAR_COSMETIC("HUD.NameTagActorText.Changed"), 0)) { + textColor = CVarGetColor(CVAR_COSMETIC("HUD.NameTagActorText.Value"), textColor); } FrameInterpolation_RecordOpenChild(nameTag->actor, 10); @@ -90,7 +91,7 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) { // Set position, billboard effect, scale (with mirror mode), then center nametag Matrix_Translate(nameTag->actor->world.pos.x, posY, nameTag->actor->world.pos.z, MTXMODE_NEW); Matrix_ReplaceRotation(&play->billboardMtxF); - Matrix_Scale(scale * (CVarGetInteger("gMirroredWorld", 0) ? -1 : 1), -scale, 1.0f, MTXMODE_APPLY); + Matrix_Scale(scale * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? -1 : 1), -scale, 1.0f, MTXMODE_APPLY); Matrix_Translate(-(float)nameTag->width / 2, -nameTag->height, 0, MTXMODE_APPLY); Matrix_ToMtx(nameTag->mtx, (char*)__FILE__, __LINE__); diff --git a/soh/soh/Enhancements/pausewarp.c b/soh/soh/Enhancements/pausewarp.c new file mode 100644 index 000000000..5538e7ad4 --- /dev/null +++ b/soh/soh/Enhancements/pausewarp.c @@ -0,0 +1,93 @@ +#include "custom-message/CustomMessageTypes.h" +#include "global.h" +#include "z64.h" +#include "game-interactor/GameInteractor.h" + +static const int songMessageMap[] = { + TEXT_WARP_MINUET_OF_FOREST, + TEXT_WARP_BOLERO_OF_FIRE, + TEXT_WARP_SERENADE_OF_WATER, + TEXT_WARP_REQUIEM_OF_SPIRIT, + TEXT_WARP_NOCTURNE_OF_SHADOW, + TEXT_WARP_PRELUDE_OF_LIGHT +}; + +static const int ocarinaSongMap[] = { + OCARINA_SONG_MINUET, + OCARINA_SONG_BOLERO, + OCARINA_SONG_SERENADE, + OCARINA_SONG_REQUIEM, + OCARINA_SONG_NOCTURNE, + OCARINA_SONG_PRELUDE +}; + +static const int entranceIndexMap[] = { + ENTR_SACRED_FOREST_MEADOW_2, // Minuet + ENTR_DEATH_MOUNTAIN_CRATER_4, // Bolero + ENTR_LAKE_HYLIA_8, // Serenade + ENTR_DESERT_COLOSSUS_5, // Requiem + ENTR_GRAVEYARD_7, // Nocturne + ENTR_TEMPLE_OF_TIME_7 // Prelude +}; + +static const int songAudioMap[] = { + NA_BGM_OCA_MINUET, + NA_BGM_OCA_BOLERO, + NA_BGM_OCA_SERENADE, + NA_BGM_OCA_REQUIEM, + NA_BGM_OCA_NOCTURNE, + NA_BGM_OCA_LIGHT +}; + +static bool isWarpActive = false; + +void PauseWarp_Execute() { + if (!isWarpActive || gPlayState->msgCtx.msgMode != MSGMODE_NONE) { + return; + } + isWarpActive = false; + GET_PLAYER(gPlayState)->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; + if (gPlayState->msgCtx.choiceIndex != 0) { + return; + } + if (IS_RANDO) { + Entrance_SetWarpSongEntrance(); + return; + } + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_FADE_WHITE_FAST; + for (int i = 0; i < ARRAY_COUNT(ocarinaSongMap); i++) { + if (gPlayState->msgCtx.lastPlayedSong == ocarinaSongMap[i]) { + gPlayState->nextEntranceIndex = entranceIndexMap[i]; + return; + } + } + gPlayState->transitionTrigger = TRANS_TRIGGER_OFF; +} + +void ActivateWarp(PauseContext* pauseCtx, int song) { + Audio_OcaSetInstrument(0); + Interface_SetDoAction(gPlayState, DO_ACTION_NONE); + pauseCtx->state = 0x12; + WREG(2) = -6240; + func_800F64E0(0); + pauseCtx->unk_1E4 = 0; + int idx = song - QUEST_SONG_MINUET; + gPlayState->msgCtx.lastPlayedSong = ocarinaSongMap[idx]; + Audio_SetSoundBanksMute(0x20); + Audio_PlayFanfare(songAudioMap[idx]); + Message_StartTextbox(gPlayState, songMessageMap[idx], NULL); + GET_PLAYER(gPlayState)->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; + isWarpActive = true; +} + +void PauseWarp_HandleSelection() { + if (gSaveContext.inventory.items[SLOT_OCARINA] != ITEM_NONE) { + int aButtonPressed = CHECK_BTN_ALL(gPlayState->state.input->press.button, BTN_A); + int song = gPlayState->pauseCtx.cursorPoint[PAUSE_QUEST]; + if (aButtonPressed && CHECK_QUEST_ITEM(song) && song >= QUEST_SONG_MINUET && song <= QUEST_SONG_PRELUDE && + gPlayState->pauseCtx.pageIndex == PAUSE_QUEST && gPlayState->pauseCtx.state == 6) { + ActivateWarp(&gPlayState->pauseCtx, song); + } + } +} diff --git a/soh/soh/Enhancements/presets.cpp b/soh/soh/Enhancements/presets.cpp index 726863e05..57bfd689c 100644 --- a/soh/soh/Enhancements/presets.cpp +++ b/soh/soh/Enhancements/presets.cpp @@ -40,7 +40,7 @@ void applyPreset(std::vector entries) { } void DrawPresetSelector(PresetType presetTypeId) { - const std::string presetTypeCvar = "gPreset" + std::to_string(presetTypeId); + const std::string presetTypeCvar = CVAR_GENERAL("SelectedPresets.") + std::to_string(presetTypeId); const PresetTypeDefinition presetTypeDef = presetTypes.at(presetTypeId); const uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0); const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(selectedPresetId); @@ -70,7 +70,7 @@ void DrawPresetSelector(PresetType presetTypeId) { if (selectedPresetId != 0) { applyPreset(selectedPresetDef.entries); } - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); } ImGui::PopStyleVar(1); } diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index cac60cdef..aea4bb1fd 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -7,6 +7,7 @@ #include #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/enhancementTypes.h" +#include "soh/OTRGlobals.h" enum PresetEntryType { PRESET_ENTRY_TYPE_S32, @@ -59,1042 +60,1060 @@ void applyPreset(std::vector entries); // TODO: Ideally everything below this point will come from one/many JSON files const std::vector enhancementsCvars = { - "gDpadPause", - "gDpadText", - "gDpadOcarina", - "gRStickOcarina", - "gDpadEquips", - "gPauseAnyCursor", - "gDpadNoDropOcarinaInput", - "gNaviOnL", - "gInvertXAxis", - "gInvertYAxis", - "gRightStickAiming", - "gDisableAutoCenterViewFirstPerson", - "gTextSpeed", - "gMweepSpeed", - "gForgeTime", - "gClimbSpeed", - "gFasterBlockPush", - "gFasterHeavyBlockLift", - "gNoForcedNavi", - "gSkulltulaFreeze", - "gMMBunnyHood", - "gAdultBunnyHood", - "gFastChests", - "gChestSizeAndTextureMatchesContents", - "gFastDrops", - "gBetterOwl", - "gFastOcarinaPlayback", - "gInstantPutaway", - "gFastBoomerang", - "gAskToEquip", - "gMaskSelect", - "gRememberSaveLocation", - "gDamageMul", - "gFallDamageMul", - "gVoidDamageMul", - "gBonkDamageMul", - "gNoRandomDrops", - "gNoHeartDrops", - "gBombchuDrops", - "gGoronPot", - "gFullHealthSpawn", - "gDampeWin", - "gRedPotionEffect", - "gRedPotionHealth", - "gRedPercentRestore", - "gGreenPotionEffect", - "gGreenPotionMana", - "gGreenPercentRestore", - "gBluePotionEffects", - "gBluePotionHealth", - "gBlueHealthPercentRestore", - "gBluePotionMana", - "gBlueManaPercentRestore", - "gMilkEffect", - "gMilkHealth", - "gMilkPercentRestore", - "gSeparateHalfMilkEffect", - "gHalfMilkHealth", - "gHalfMilkPercentRestore", - "gFairyEffect", - "gFairyHealth", - "gFairyPercentRestore", - "gFairyReviveEffect", - "gFairyReviveHealth", - "gFairyRevivePercentRestore", - "gCustomizeFishing", - "gInstantFishing", - "gGuaranteeFishingBite", - "gFishNeverEscape", - "gChildMinimumWeightFish", - "gAdultMinimumWeightFish", - "gLowHpAlarm", - "gMinimalUI", - "gDisableNaviCallAudio", - "gVisualAgony", - "gAssignableTunicsAndBoots", - "gEquipmentCanBeRemoved", - "gCowOfTime", - "gGuardVision", - "gTimeFlowFileSelect", - "gInjectItemCounts", - "gDayGravePull", - "gDampeAllNight", - "gSkipScarecrow", - "gBlueFireArrows", - "gSunlightArrows", - "gPauseLiveLinkRotation", - "gPauseLiveLink", - "gMinFrameCount", - "gN64Mode", - "gNewDrops", - "gDisableBlackBars", - "gDynamicWalletIcon", - "gAlwaysShowDungeonMinimapIcon", - "gUniformLR", - "gNGCKaleidoSwitcher", - "gFixDungeonMinimapIcon", - "gTwoHandedIdle", - "gGravediggingTourFix", - "gDekuNutUpgradeFix", - "gNaviTextFix", - "gAnubisFix", - "gCrouchStabHammerFix", - "gCrouchStabFix", - "gGerudoWarriorClothingFix", - "gFixCameraDrift", - "gFixCameraSwing", - "gFixHangingLedgeSwingRate", - "gRedGanonBlood", - "gHoverFishing", - "gN64WeirdFrames", - "gBombchusOOB", - "gQuickPutaway", - "gGsCutscene", - "gRestoreRBAValues", - "gSkipSaveConfirmation", - "gAutosave", - "gDisableCritWiggle", - "gChestSizeDependsStoneOfAgony", - "gSkipArrowAnimation", - "gSeparateArrows", - "gCustomizeShootingGallery", - "gInstantShootingGalleryWin", - "gConstantAdultGallery", - "gChildShootingGalleryAmmunition", - "gAdultShootingGalleryAmmunition", - "gCustomizeBombchuBowling", - "gBombchuBowlingNoSmallCucco", - "gBombchuBowlingNoBigCucco", - "gBombchuBowlingAmmunition", - "gCreditsFix", - "gSilverRupeeJingleExtend", - "gStaticExplosionRadius", - "gNoInputForCredits", - "gFastFarores", - "gNightGSAlwaysSpawn", - "gSkipText", - "gLinkDefaultName", - "gMarketSneak", - "gTimeTravel", - "gNutsExplodeBombs", - "gBowSlingShotAmmoFix", - "gBetterFW", - "gDisableFirstPersonChus", - "gHyperBosses", - "gRupeeDash", - "gDashInterval", - "gDogFollowsEverywhere", - "gDisableTunicWarningText", - "gDisableLOD", - "gDisableDrawDistance", - "gDisableKokiriDrawDistance", - "gLowResMode", - "gDrawLineupTick", - "gQuickBongoKill", - "gFPSGauntlets", - "gSceneSpecificDirtPathFix", - "gZFightingMode", - "gAuthenticLogo", - "gPauseLiveLinkRotationSpeed", - "gBowReticle", - "gFixTexturesOOB", - "gIvanCoopModeEnabled", - "gEnemySpawnsOverWaterboxes", - "gTreeStickDrops", - "gShadowTag", - "gRandomizedEnemySizes", - "gRandomizedEnemies", - "gMirroredWorldMode", - "gMirroredWorld", - "gHyperEnemies", - "gHookshotableReticle", - "gHideBunnyHood", - "gFixVineFall", - "gFileSelectMoreInfo", - "gEnemyHealthBar", - "gBushDropFix", - "gAllDogsRichard", - "gAddTraps.enabled", - "gAddTraps.Ammo", - "gAddTraps.Bomb", - "gAddTraps.Burn", - "gAddTraps.Ice", - "gAddTraps.Kill", - "gAddTraps.Knock", - "gAddTraps.Shock", - "gAddTraps.Speed", - "gAddTraps.Tele", - "gAddTraps.Void", + CVAR_SETTING("DPadOnPause"), + CVAR_SETTING("DpadInText"), + CVAR_SETTING("OcarinaControl.Dpad"), + CVAR_SETTING("OcarinaControl.RStick"), + CVAR_SETTING("DpadEquips"), + CVAR_SETTING("PauseAnyCursor"), + CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), + CVAR_SETTING("NaviOnL"), + CVAR_SETTING("FreeLook.InvertXAxis"), + CVAR_SETTING("FreeLook.InvertYAxis"), + CVAR_SETTING("Controls.RightStickAim"), + CVAR_SETTING("DisableFirstPersonAutoCenterView"), + CVAR_ENHANCEMENT("TextSpeed"), + CVAR_ENHANCEMENT("MweepSpeed"), + CVAR_ENHANCEMENT("ForgeTime"), + CVAR_ENHANCEMENT("ClimbSpeed"), + CVAR_ENHANCEMENT("FasterBlockPush"), + CVAR_ENHANCEMENT("CrawlSpeed"), + CVAR_ENHANCEMENT("FasterHeavyBlockLift"), + CVAR_ENHANCEMENT("NoForcedNavi"), + CVAR_ENHANCEMENT("SkulltulaFreeze"), + CVAR_ENHANCEMENT("MMBunnyHood"), + CVAR_ENHANCEMENT("AdultBunnyHood"), + CVAR_ENHANCEMENT("FastChests"), + CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), + CVAR_ENHANCEMENT("FastDrops"), + CVAR_ENHANCEMENT("BetterOwl"), + CVAR_ENHANCEMENT("FastOcarinaPlayback"), + CVAR_ENHANCEMENT("InstantPutaway"), + CVAR_ENHANCEMENT("FastBoomerang"), + CVAR_ENHANCEMENT("AskToEquip"), + CVAR_ENHANCEMENT("MaskSelect"), + CVAR_ENHANCEMENT("RememberSaveLocation"), + CVAR_ENHANCEMENT("DamageMult"), + CVAR_ENHANCEMENT("FallDamageMult"), + CVAR_ENHANCEMENT("VoidDamageMult"), + CVAR_ENHANCEMENT("BonkDamageMult"), + CVAR_ENHANCEMENT("NoRandomDrops"), + CVAR_ENHANCEMENT("NoHeartDrops"), + CVAR_ENHANCEMENT("BombchuDrops"), + CVAR_ENHANCEMENT("GoronPot"), + CVAR_ENHANCEMENT("FullHealthSpawn"), + CVAR_ENHANCEMENT("DampeWin"), + CVAR_ENHANCEMENT("RedPotionEffect"), + CVAR_ENHANCEMENT("RedPotionHealth"), + CVAR_ENHANCEMENT("RedPercentRestore"), + CVAR_ENHANCEMENT("GreenPotionEffect"), + CVAR_ENHANCEMENT("GreenPotionMana"), + CVAR_ENHANCEMENT("GreenPercentRestore"), + CVAR_ENHANCEMENT("BluePotionEffects"), + CVAR_ENHANCEMENT("BluePotionHealth"), + CVAR_ENHANCEMENT("BlueHealthPercentRestore"), + CVAR_ENHANCEMENT("BluePotionMana"), + CVAR_ENHANCEMENT("BlueManaPercentRestore"), + CVAR_ENHANCEMENT("MilkEffect"), + CVAR_ENHANCEMENT("MilkHealth"), + CVAR_ENHANCEMENT("MilkPercentRestore"), + CVAR_ENHANCEMENT("SeparateHalfMilkEffect"), + CVAR_ENHANCEMENT("HalfMilkHealth"), + CVAR_ENHANCEMENT("HalfMilkPercentRestore"), + CVAR_ENHANCEMENT("FairyEffect"), + CVAR_ENHANCEMENT("FairyHealth"), + CVAR_ENHANCEMENT("FairyPercentRestore"), + CVAR_ENHANCEMENT("FairyReviveEffect"), + CVAR_ENHANCEMENT("FairyReviveHealth"), + CVAR_ENHANCEMENT("FairyRevivePercentRestore"), + CVAR_ENHANCEMENT("CustomizeFishing"), + CVAR_ENHANCEMENT("InstantFishing"), + CVAR_ENHANCEMENT("GuaranteeFishingBite"), + CVAR_ENHANCEMENT("FishNeverEscape"), + CVAR_ENHANCEMENT("MinimumFishWeightChild"), + CVAR_ENHANCEMENT("MinimumFishWeightAdult"), + CVAR_ENHANCEMENT("LowHpAlarm"), + CVAR_ENHANCEMENT("MinimalUI"), + CVAR_ENHANCEMENT("DisableNaviCallAudio"), + CVAR_ENHANCEMENT("VisualAgony"), + CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), + CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), + CVAR_ENHANCEMENT("CowOfTime"), + CVAR_ENHANCEMENT("GuardVision"), + CVAR_ENHANCEMENT("TimeFlowFileSelect"), + CVAR_ENHANCEMENT("InjectItemCounts"), + CVAR_ENHANCEMENT("DayGravePull"), + CVAR_ENHANCEMENT("DampeAllNight"), + CVAR_ENHANCEMENT("QuitFishingAtDoor"), + CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"), + CVAR_ENHANCEMENT("InstantScarecrow"), + CVAR_ENHANCEMENT("BlueFireArrows"), + CVAR_ENHANCEMENT("SunlightArrows"), + CVAR_ENHANCEMENT("PauseLiveLinkRotation"), + CVAR_ENHANCEMENT("PauseLiveLink"), + CVAR_ENHANCEMENT("MinFrameCount"), + CVAR_ENHANCEMENT("NewDrops"), + CVAR_ENHANCEMENT("DisableBlackBars"), + CVAR_ENHANCEMENT("DynamicWalletIcon"), + CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), + CVAR_ENHANCEMENT("FixMenuLR"), + CVAR_ENHANCEMENT("NGCKaleidoSwitcher"), + CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), + CVAR_ENHANCEMENT("TwoHandedIdle"), + CVAR_ENHANCEMENT("GravediggingTourFix"), + CVAR_ENHANCEMENT("DekuNutUpgradeFix"), + CVAR_ENHANCEMENT("NaviTextFix"), + CVAR_ENHANCEMENT("AnubixFix"), + CVAR_ENHANCEMENT("CrouchStabHammerFix"), + CVAR_ENHANCEMENT("CrouchStabFix"), + CVAR_ENHANCEMENT("GerudoWarriorClothingFix"), + CVAR_ENHANCEMENT("FixCameraDrift"), + CVAR_ENHANCEMENT("FixCameraSwing"), + CVAR_ENHANCEMENT("FixHangingLedgeSwingRate"), + CVAR_ENHANCEMENT("RedGanonBlood"), + CVAR_ENHANCEMENT("HoverFishing"), + CVAR_ENHANCEMENT("N64WeirdFrames"), + CVAR_ENHANCEMENT("BombchusOOB"), + CVAR_ENHANCEMENT("QuickPutaway"), + CVAR_ENHANCEMENT("GSCutscene"), + CVAR_ENHANCEMENT("RestoreRBAValues"), + CVAR_ENHANCEMENT("SkipSaveConfirmation"), + CVAR_ENHANCEMENT("Autosave"), + CVAR_ENHANCEMENT("DisableCritWiggle"), + CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), + CVAR_ENHANCEMENT("SkipArrowAnimation"), + CVAR_ENHANCEMENT("SeparateArrows"), + CVAR_ENHANCEMENT("CustomizeShootingGallery"), + CVAR_ENHANCEMENT("InstantShootingGalleryWin"), + CVAR_ENHANCEMENT("ConstantAdultGallery"), + CVAR_ENHANCEMENT("ShootingGalleryAmmoChild"), + CVAR_ENHANCEMENT("ShootingGalleryAmmoAdult"), + CVAR_ENHANCEMENT("CustomizeBombchuBowling"), + CVAR_ENHANCEMENT("BombchuBowlingNoSmallCucco"), + CVAR_ENHANCEMENT("BombchuBowlingNoBigCucco"), + CVAR_ENHANCEMENT("BombchuBowlingAmmo"), + CVAR_ENHANCEMENT("CustomizeOcarinaGame"), + CVAR_ENHANCEMENT("InstantOcarinaGameWin"), + CVAR_ENHANCEMENT("OcarinaGame.NoteSpeed"), + CVAR_ENHANCEMENT("OcarinaUnlimitedFailTime"), + CVAR_ENHANCEMENT("OcarinaGame.StartingNotes"), + CVAR_ENHANCEMENT("OcarinaGame.RoundOneNotes"), + CVAR_ENHANCEMENT("OcarinaGame.RoundTwoNotes"), + CVAR_ENHANCEMENT("OcarinaGame.RoundThreeNotes"), + CVAR_ENHANCEMENT("CreditsFix"), + CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), + CVAR_ENHANCEMENT("StaticExplosionRadius"), + CVAR_ENHANCEMENT("NoInputForCredits"), + CVAR_ENHANCEMENT("FastFarores"), + CVAR_ENHANCEMENT("NightGSAlwaysSpawn"), + CVAR_ENHANCEMENT("SkipText"), + CVAR_ENHANCEMENT("LinkDefaultName"), + CVAR_ENHANCEMENT("MarketSneak"), + CVAR_ENHANCEMENT("TimeTravel"), + CVAR_ENHANCEMENT("NutsExplodeBombs"), + CVAR_ENHANCEMENT("BowSlingshotAmmoFix"), + CVAR_ENHANCEMENT("BetterFarore"), + CVAR_ENHANCEMENT("DisableFirstPersonChus"), + CVAR_ENHANCEMENT("HyperBosses"), + CVAR_ENHANCEMENT("RupeeDash"), + CVAR_ENHANCEMENT("RupeeDashInterval"), + CVAR_ENHANCEMENT("DogFollowsEverywhere"), + CVAR_ENHANCEMENT("DisableTunicWarningText"), + CVAR_ENHANCEMENT("DisableLOD"), + CVAR_ENHANCEMENT("DisableDrawDistance"), + CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), + CVAR_LOW_RES_MODE, + CVAR_ENHANCEMENT("DrawLineupTick"), + CVAR_ENHANCEMENT("QuickBongoKill"), + CVAR_ENHANCEMENT("FirstPersonGauntlets"), + CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), + CVAR_Z_FIGHTING_MODE, + CVAR_ENHANCEMENT("AuthenticLogo"), + CVAR_ENHANCEMENT("PauseLiveLinkRotationSpeed"), + CVAR_ENHANCEMENT("BowReticle"), + CVAR_ENHANCEMENT("FixTexturesOOB"), + CVAR_ENHANCEMENT("IvanCoopModeEnabled"), + CVAR_ENHANCEMENT("EnemySpawnsOverWaterboxes"), + CVAR_ENHANCEMENT("TreesDropSticks"), + CVAR_ENHANCEMENT("ShadowTag"), + CVAR_ENHANCEMENT("RandomizedEnemySizes"), + CVAR_ENHANCEMENT("RandomizedEnemies"), + CVAR_ENHANCEMENT("MirroredWorldMode"), + CVAR_ENHANCEMENT("MirroredWorld"), + CVAR_ENHANCEMENT("HyperEnemies"), + CVAR_ENHANCEMENT("HookshotableReticle"), + CVAR_ENHANCEMENT("HideBunnyHood"), + CVAR_ENHANCEMENT("FixVineFall"), + CVAR_ENHANCEMENT("FileSelectMoreInfo"), + CVAR_ENHANCEMENT("EnemyHealthBar"), + CVAR_ENHANCEMENT("BushDropFix"), + CVAR_ENHANCEMENT("AllDogsRichard"), + CVAR_ENHANCEMENT("ExtraTraps.Enabled"), + CVAR_ENHANCEMENT("ExtraTraps.Ammo"), + CVAR_ENHANCEMENT("ExtraTraps.Bomb"), + CVAR_ENHANCEMENT("ExtraTraps.Burn"), + CVAR_ENHANCEMENT("ExtraTraps.Ice"), + CVAR_ENHANCEMENT("ExtraTraps.Kill"), + CVAR_ENHANCEMENT("ExtraTraps.Knockback"), + CVAR_ENHANCEMENT("ExtraTraps.Shock"), + CVAR_ENHANCEMENT("ExtraTraps.Speed"), + CVAR_ENHANCEMENT("ExtraTraps.Teleport"), + CVAR_ENHANCEMENT("ExtraTraps.Void"), + CVAR_ENHANCEMENT("ToTMedallionsColors"), + CVAR_ENHANCEMENT("CuccoStayDurationMult"), + CVAR_ENHANCEMENT("DeleteFileOnDeath"), + CVAR_ENHANCEMENT("EnemySizeScalesHealth"), + CVAR_ENHANCEMENT("BetterAmmoRendering"), + CVAR_ENHANCEMENT("EquimentAlwaysVisible"), + CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"), + CVAR_ENHANCEMENT("OpenAllHours"), + CVAR_ENHANCEMENT("ResetNaviTimer"), + CVAR_ENHANCEMENT("ScaleAdultEquimentAsChild"), + CVAR_ENHANCEMENT("LeeverSpawnRate"), + CVAR_ENHANCEMENT("SwordToggle"), + CVAR_ENHANCEMENT("FixFloorSwitches"), + CVAR_ENHANCEMENT("FixZoraHintDialogue"), + CVAR_ENHANCEMENT("HurtContainer"), + CVAR_ENHANCEMENT("PauseWarp"), + CVAR_ENHANCEMENT("PermanentHeartLoss"), + CVAR_ENHANCEMENT("RemoveExplosiveLimit"), + CVAR_ENHANCEMENT("ToggleStrength"), }; const std::vector cheatCvars = { - "gConsoleEnabled", - "gActorViewerEnabled", - "gCollisionViewerEnabled", - "gDLViewerEnabled", - "gSaveEditorEnabled", - "gEnableWalkModify", - "gWalkSpeedToggle", - "gWalkModifierOne", - "gWalkModifierTwo", - "gGoronPot", - "gDampeWin", - "gCustomizeShootingGallery", - "gCustomizeBombchuBowling", - "gCustomizeFishing", - "gInfiniteAmmo", - "gInfiniteEpona", - "gInfiniteHealth", - "gInfiniteMagic", - "gInfiniteMoney", - "gInfiniteNayru", - "gNoClip", - "gClimbEverything", - "gHookshotEverything", - "gCheatHookshotReachMultiplier", - "gMoonJumpOnL", - "gSuperTunic", - "gEzISG", - "gEzQPA", - "gTimelessEquipment", - "gCheatEasyPauseBufferEnabled", - "gCheatEasyInputBufferingEnabled", - "gNoRestrictItems", - "gFreezeTime", - "gPrevTime", - "gDropsDontDie", - "gFireproofDekuShield", - "gShieldTwoHanded", - "gTimeSync", - "gDebugEnabled", - "gSkulltulaDebugEnabled", - "gSkipLogoTitle", - "gSaveFileID", - "gEnableBetaQuest", - "gBetterDebugWarpScreen", - "gSwitchAge", - "gSwitchTimeline", - "gNoRedeadFreeze", - "gBombTimerMultiplier", - "gNoFishDespawn", - "gNoBugsDespawn", - "gWalkModifierDoesntChangeJump", - "gStatsEnabled", - "gSaveStatesEnabled", - "gSaveStatePromise", - "gRegEditEnabled", - "gPreset0", - "gPreset1", - "gDekuStickCheat", - "gDebugWarpScreenTranslation", - "gDebugSaveFileMode", - "gCosmetics.Link_BodyScale.Changed", - "gCosmetics.Link_BodyScale.Value", - "gCosmetics.Link_HeadScale.Changed", - "gCosmetics.Link_HeadScale.Value", - "gCosmetics.Link_SwordScale.Changed", - "gCosmetics.Link_SwordScale.Value", + CVAR_CONSOLE_WINDOW_OPEN, + CVAR_WINDOW("ActorViewer"), + CVAR_WINDOW("CollisionViewer"), + CVAR_WINDOW("DLViewer"), + CVAR_WINDOW("SaveEditor"), + CVAR_SETTING("WalkModifier.Enabled"), + CVAR_SETTING("WalkModifier.SpeedToggle"), + CVAR_SETTING("WalkModifier.Mapping1"), + CVAR_SETTING("WalkModifier.Mapping2"), + CVAR_SETTING("WalkModifier.SwimMapping1"), + CVAR_SETTING("WalkModifier.SwimMapping2"), + CVAR_ENHANCEMENT("GoronPot"), + CVAR_ENHANCEMENT("DampeWin"), + CVAR_ENHANCEMENT("CustomizeShootingGallery"), + CVAR_ENHANCEMENT("CustomizeBombchuBowling"), + CVAR_ENHANCEMENT("CustomizeFishing"), + CVAR_CHEAT("InfiniteAmmo"), + CVAR_CHEAT("InfiniteEponaBoost"), + CVAR_CHEAT("InfiniteHealth"), + CVAR_CHEAT("InfiniteMagic"), + CVAR_CHEAT("InfiniteMoney"), + CVAR_CHEAT("InfiniteNayru"), + CVAR_CHEAT("NoClip"), + CVAR_CHEAT("ClimbEverything"), + CVAR_CHEAT("HookshotEverything"), + CVAR_CHEAT("HookshotReachMultiplier"), + CVAR_CHEAT("MoonJumpOnL"), + CVAR_CHEAT("SuperTunic"), + CVAR_CHEAT("EasyISG"), + CVAR_CHEAT("EasyQPA"), + CVAR_CHEAT("TimelessEquipment"), + CVAR_CHEAT("EasyPauseBuffer"), + CVAR_CHEAT("EasyInputBuffer"), + CVAR_CHEAT("NoRestrictItems"), + CVAR_CHEAT("FreezeTime"), + CVAR_GENERAL("PrevTime"), + CVAR_CHEAT("DropsDontDie"), + CVAR_CHEAT("FireproofDekuShield"), + CVAR_CHEAT("ShieldTwoHanded"), + CVAR_CHEAT("TimeSync"), + CVAR_DEVELOPER_TOOLS("DebugEnabled"), + CVAR_DEVELOPER_TOOLS("SkulltulaDebugEnabled"), + CVAR_DEVELOPER_TOOLS("SkipLogoTitle"), + CVAR_DEVELOPER_TOOLS("SaveFileID"), + CVAR_CHEAT("EnableBetaQuest"), + CVAR_DEVELOPER_TOOLS("BetterDebugWarpScreen"), + CVAR_GENERAL("SwitchAge"), + CVAR_GENERAL("SwitchTimeline"), + CVAR_CHEAT("NoRedeadFreeze"), + CVAR_CHEAT("NoKeeseGuayTarget"), + CVAR_CHEAT("BombTimerMultiplier"), + CVAR_CHEAT("NoFishDespawn"), + CVAR_CHEAT("NoBugsDespawn"), + CVAR_SETTING("WalkModifier.DoesntChangeJump"), + CVAR_STATS_WINDOW_OPEN, + CVAR_CHEAT("SaveStatesEnabled"), + CVAR_CHEAT("SaveStatePromise"), + CVAR_DEVELOPER_TOOLS("RegEditEnabled"), + CVAR_CHEAT("DekuStick"), + CVAR_DEVELOPER_TOOLS("DebugWarpScreenTranslation"), + CVAR_DEVELOPER_TOOLS("DebugSaveFileMode"), + CVAR_COSMETIC("Link.BodyScale.Changed"), + CVAR_COSMETIC("Link.BodyScale.Value"), + CVAR_COSMETIC("Link.HeadScale.Changed"), + CVAR_COSMETIC("Link.HeadScale.Value"), + CVAR_COSMETIC("Link.SwordScale.Changed"), + CVAR_COSMETIC("Link.SwordScale.Value"), + CVAR_ENHANCEMENT("RememberMapToggleState"), }; const std::vector randomizerCvars = { - "gRandomize10GSHint", - "gRandomize20GSHint", - "gRandomize30GSHint", - "gRandomize40GSHint", - "gRandomize50GSHint", - "gRandomizeAllLocationsReachable", - "gRandomizeAltarHint", - "gRandomizeBigPoeTargetCount", - "gRandomizeBlueFireArrows", - "gRandomizeBombchusInLogic", - "gRandomizeBossKeysanity", - "gRandomizeBridgeRewardOptions", - "gRandomizeCompleteMaskQuest", - "gRandomizeCuccosToReturn", - "gRandomizeDampeHint", - "gRandomizeDecoupleEntrances", - "gRandomizeDoorOfTime", - "gRandomizeDungeonCount", - "gRandomizeEnableBombchuDrops", - "gRandomizeEnableGlitchCutscenes", - "gRandomizeEnabledGlitches", - "gRandomizeEnabledTricks", - "gRandomizeExcludedLocations", - "gRandomizeForest", - "gRandomizeFullWallets", - "gRandomizeGanonTrial", - "gRandomizeGanonTrialCount", - "gRandomizeGerudoFortress", - "gRandomizeGerudoKeys", - "gRandomizeGossipStoneHints", - "gRandomizeGsExpectSunsSong", - "gRandomizeHintClarity", - "gRandomizeHintDistribution", - "gRandomizeIceTraps", - "gRandomizeItemPool", - "gRandomizeKakarikoGate", - "gRandomizeKeysanity", - "gRandomizeLacsDungeonCount", - "gRandomizeLacsMedallionCount", - "gRandomizeLacsRewardCount", - "gRandomizeLacsRewardOptions", - "gRandomizeLacsStoneCount", - "gRandomizeLacsTokenCount", - "gRandomizeLAHint", - "gRandomizeLinksPocket", - "gRandomizeLogicRules", - "gRandomizeMedallionCount", - "gRandomizeMixDungeons", - "gRandomizeMixedEntrances", - "gRandomizeMixGrottos", - "gRandomizeMixInteriors", - "gRandomizeMixOverworld", - "gRandomizeMqDungeonCount", - "gRandomizeMqDungeons", - "gRandomizeRainbowBridge", - "gRandomizeRewardCount", - "gRandomizeScrubText", - "gRandomizeShopsanity", - "gRandomizeShopsanityPrices", - "gRandomizeShopsanityPricesAffordable", - "gRandomizeShuffleAdultTrade", - "gRandomizeShuffleBeans", - "gRandomizeShuffleBossEntrances", - "gRandomizeShuffleCows", - "gRandomizeShuffleDungeonReward", - "gRandomizeShuffleDungeonsEntrances", - "gRandomizeShuffleFrogSongRupees", - "gRandomizeShuffleGanonBossKey", - "gRandomizeShuffleGerudoToken", - "gRandomizeShuffleGrottosEntrances", - "gRandomizeShuffleInteriorsEntrances", - "gRandomizeShuffleKeyRings", - "gRandomizeShuffleKeyRingsBottomOfTheWell", - "gRandomizeShuffleKeyRingsFireTemple", - "gRandomizeShuffleKeyRingsForestTemple", - "gRandomizeShuffleKeyRingsGanonsCastle", - "gRandomizeShuffleKeyRingsGerudoFortress", - "gRandomizeShuffleKeyRingsGTG", - "gRandomizeShuffleKeyRingsRandomCount", - "gRandomizeShuffleKeyRingsShadowTemple", - "gRandomizeShuffleKeyRingsSpiritTemple", - "gRandomizeShuffleKeyRingsWaterTemple", - "gRandomizeShuffleKokiriSword", - "gRandomizeShuffleMerchants", - "gRandomizeShuffleOcarinas", - "gRandomizeShuffleOverworldEntrances", - "gRandomizeShuffleOverworldSpawns", - "gRandomizeShuffleOwlDrops", - "gRandomizeShuffleScrubs", - "gRandomizeShuffleSongs", - "gRandomizeShuffleTokens", - "gRandomizeShuffleWarpSongs", - "gRandomizeShuffleWeirdEgg", - "gRandomizeSkipChildStealth", - "gRandomizeSkipChildZelda", - "gRandomizeSkipEponaRace", - "gRandomizeSkipScarecrowsSong", - "gRandomizeSkipTowerEscape", - "gRandomizeStartingAge", - "gRandomizeStartingConsumables", - "gRandomizeStartingBoleroOfFire", - "gRandomizeStartingDekuShield", - "gRandomizeStartingEponasSong", - "gRandomizeStartingKokiriSword", - "gRandomizeStartingMapsCompasses", - "gRandomizeStartingMinuetOfForest", - "gRandomizeStartingNocturneOfShadow", - "gRandomizeStartingOcarina", - "gRandomizeStartingPreludeOfLight", - "gRandomizeStartingRequiemOfSpirit", - "gRandomizeStartingSariasSong", - "gRandomizeStartingSerenadeOfWater", - "gRandomizeStartingSkulltulaToken", - "gRandomizeStartingSongOfStorms", - "gRandomizeStartingSongOfTime", - "gRandomizeStartingSunsSong", - "gRandomizeStartingZeldasLullaby", - "gRandomizeStoneCount", - "gRandomizeSunlightArrows", - "gRandomizeTokenCount", - "gRandomizeWarpSongText", - "gRandomizeZorasFountain", - "gRandomizeShuffle100GSReward", - "gRandomizeGregHint", - "gRandoManualSeedEntry", - "gRandomizerSettingsEnabled", - "gRandomizeTriforceHuntTotalPieces", - "gRandomizeTriforceHuntRequiredPieces", - "gRandomizeTriforceHunt", - "gRandomizeShuffleMasterSword", - "gRandomizeSariaHint", - "gRandomizeRupeeNames", - "gRandomizeFrogsHint", - "gRandoRelevantNavi", - "gRandoQuestItemFanfares", + CVAR_RANDOMIZER_SETTING("10GSHint"), + CVAR_RANDOMIZER_SETTING("20GSHint"), + CVAR_RANDOMIZER_SETTING("30GSHint"), + CVAR_RANDOMIZER_SETTING("40GSHint"), + CVAR_RANDOMIZER_SETTING("50GSHint"), + CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), + CVAR_RANDOMIZER_SETTING("AltarHint"), + CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), + CVAR_RANDOMIZER_SETTING("BlueFireArrows"), + CVAR_RANDOMIZER_SETTING("BombchusInLogic"), + CVAR_RANDOMIZER_SETTING("BossKeysanity"), + CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), + CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), + CVAR_RANDOMIZER_SETTING("CuccosToReturn"), + CVAR_RANDOMIZER_SETTING("DampeHint"), + CVAR_RANDOMIZER_SETTING("DecoupleEntrances"), + CVAR_RANDOMIZER_SETTING("DoorOfTime"), + CVAR_RANDOMIZER_SETTING("DungeonCount"), + CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), + CVAR_RANDOMIZER_SETTING("EnableGlitchCutscenes"), + CVAR_RANDOMIZER_SETTING("EnabledGlitches"), + CVAR_RANDOMIZER_SETTING("EnabledTricks"), + CVAR_RANDOMIZER_SETTING("ExcludedLocations"), + CVAR_RANDOMIZER_SETTING("Forest"), + CVAR_RANDOMIZER_SETTING("FullWallets"), + CVAR_RANDOMIZER_SETTING("GanonTrial"), + CVAR_RANDOMIZER_SETTING("GanonTrialCount"), + CVAR_RANDOMIZER_SETTING("GerudoFortress"), + CVAR_RANDOMIZER_SETTING("GerudoKeys"), + CVAR_RANDOMIZER_SETTING("GossipStoneHints"), + CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), + CVAR_RANDOMIZER_SETTING("HintClarity"), + CVAR_RANDOMIZER_SETTING("HintDistribution"), + CVAR_RANDOMIZER_SETTING("IceTraps"), + CVAR_RANDOMIZER_SETTING("ItemPool"), + CVAR_RANDOMIZER_SETTING("KakarikoGate"), + CVAR_RANDOMIZER_SETTING("Keysanity"), + CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), + CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), + CVAR_RANDOMIZER_SETTING("LacsRewardCount"), + CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), + CVAR_RANDOMIZER_SETTING("LacsStoneCount"), + CVAR_RANDOMIZER_SETTING("LacsTokenCount"), + CVAR_RANDOMIZER_SETTING("LAHint"), + CVAR_RANDOMIZER_SETTING("LinksPocket"), + CVAR_RANDOMIZER_SETTING("LogicRules"), + CVAR_RANDOMIZER_SETTING("MedallionCount"), + CVAR_RANDOMIZER_SETTING("MixDungeons"), + CVAR_RANDOMIZER_SETTING("MixedEntrances"), + CVAR_RANDOMIZER_SETTING("MixGrottos"), + CVAR_RANDOMIZER_SETTING("MixInteriors"), + CVAR_RANDOMIZER_SETTING("MixOverworld"), + CVAR_RANDOMIZER_SETTING("MQDungeonCount"), + CVAR_RANDOMIZER_SETTING("MQDungeons"), + CVAR_RANDOMIZER_SETTING("RainbowBridge"), + CVAR_RANDOMIZER_SETTING("RewardCount"), + CVAR_RANDOMIZER_SETTING("ScrubText"), + CVAR_RANDOMIZER_SETTING("Shopsanity"), + CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), + CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), + CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), + CVAR_RANDOMIZER_SETTING("ShuffleBeans"), + CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), + CVAR_RANDOMIZER_SETTING("ShuffleCows"), + CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), + CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), + CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), + CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), + CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), + CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), + CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsFireTemple"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsForestTemple"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsSpiritTemple"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"), + CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), + CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), + CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), + CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), + CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), + CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"), + CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), + CVAR_RANDOMIZER_SETTING("ShuffleSongs"), + CVAR_RANDOMIZER_SETTING("ShuffleTokens"), + CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), + CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), + CVAR_RANDOMIZER_SETTING("SkipChildStealth"), + CVAR_RANDOMIZER_SETTING("SkipChildZelda"), + CVAR_RANDOMIZER_SETTING("SkipEponaRace"), + CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), + CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), + CVAR_RANDOMIZER_SETTING("StartingAge"), + CVAR_RANDOMIZER_SETTING("StartingConsumables"), + CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"), + CVAR_RANDOMIZER_SETTING("StartingDekuShield"), + CVAR_RANDOMIZER_SETTING("StartingEponasSong"), + CVAR_RANDOMIZER_SETTING("StartingKokiriSword"), + CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), + CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"), + CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), + CVAR_RANDOMIZER_SETTING("StartingOcarina"), + CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight"), + CVAR_RANDOMIZER_SETTING("StartingRequiemOfSpirit"), + CVAR_RANDOMIZER_SETTING("StartingSariasSong"), + CVAR_RANDOMIZER_SETTING("StartingSerenadeOfWater"), + CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), + CVAR_RANDOMIZER_SETTING("StartingSongOfStorms"), + CVAR_RANDOMIZER_SETTING("StartingSongOfTime"), + CVAR_RANDOMIZER_SETTING("StartingSunsSong"), + CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), + CVAR_RANDOMIZER_SETTING("StoneCount"), + CVAR_RANDOMIZER_SETTING("SunlightArrows"), + CVAR_RANDOMIZER_SETTING("TokenCount"), + CVAR_RANDOMIZER_SETTING("WarpSongText"), + CVAR_RANDOMIZER_SETTING("ZorasFountain"), + CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), + CVAR_RANDOMIZER_SETTING("GregHint"), + CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), + CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), + CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"), + CVAR_RANDOMIZER_SETTING("TriforceHunt"), + CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), + CVAR_RANDOMIZER_SETTING("SariaHint"), + CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"), + CVAR_RANDOMIZER_SETTING("FrogsHint"), + CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"), + CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"), }; const std::vector vanillaPlusPresetEntries = { // D-pad Support in text and file select - PRESET_ENTRY_S32("gDpadText", 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1), // Play Ocarina with D-pad - PRESET_ENTRY_S32("gDpadOcarina", 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.Dpad"), 1), // Play Ocarina with Right Stick - PRESET_ENTRY_S32("gRStickOcarina", 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.RStick"), 1), // D-pad as Equip Items - PRESET_ENTRY_S32("gDpadEquips", 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadEquips"), 1), // Prevent Dropped Ocarina Inputs - PRESET_ENTRY_S32("gDpadNoDropOcarinaInput", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), 1), // Right Stick Aiming - PRESET_ENTRY_S32("gRightStickAiming", 1), + PRESET_ENTRY_S32(CVAR_SETTING("Controls.RightStickAim"), 1), // Text Speed (1 to 5) - PRESET_ENTRY_S32("gTextSpeed", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), // Skip Text - PRESET_ENTRY_S32("gSkipText", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), // King Zora Speed (1 to 5) - PRESET_ENTRY_S32("gMweepSpeed", 2), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MweepSpeed"), 2), // Faster Block Push (+0 to +5) - PRESET_ENTRY_S32("gFasterBlockPush", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5), // Better Owl - PRESET_ENTRY_S32("gBetterOwl", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1), // Assignable Tunics and Boots - PRESET_ENTRY_S32("gAssignableTunicsAndBoots", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), // Enable passage of time on file select - PRESET_ENTRY_S32("gTimeFlowFileSelect", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeFlowFileSelect"), 1), // Inject Item Counts in messages - PRESET_ENTRY_S32("gInjectItemCounts", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts"), 1), // Pause link animation (0 to 16) - PRESET_ENTRY_S32("gPauseLiveLink", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PauseLiveLink"), 1), // Dynamic Wallet Icon - PRESET_ENTRY_S32("gDynamicWalletIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DynamicWalletIcon"), 1), // Always show dungeon entrances - PRESET_ENTRY_S32("gAlwaysShowDungeonMinimapIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), 1), // Fix L&R Pause menu - PRESET_ENTRY_S32("gUniformLR", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1), // Fix Dungeon entrances - PRESET_ENTRY_S32("gFixDungeonMinimapIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1), // Fix Two Handed idle animations - PRESET_ENTRY_S32("gTwoHandedIdle", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), // Fix the Gravedigging Tour Glitch - PRESET_ENTRY_S32("gGravediggingTourFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GravediggingTourFix"), 1), // Fix Deku Nut upgrade - PRESET_ENTRY_S32("gDekuNutUpgradeFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1), // Fix Navi text HUD position - PRESET_ENTRY_S32("gNaviTextFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1), // Extend Silver Rupee Jingle - PRESET_ENTRY_S32("gSilverRupeeJingleExtend", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 1), + // Fix some Floor Switches + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixFloorSwitches"), 1), // Red Ganon blood - PRESET_ENTRY_S32("gRedGanonBlood", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RedGanonBlood"), 1), // Fish while hovering - PRESET_ENTRY_S32("gHoverFishing", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("HoverFishing"), 1), // N64 Weird Frames - PRESET_ENTRY_S32("gN64WeirdFrames", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("N64WeirdFrames"), 1), // Bombchus out of bounds - PRESET_ENTRY_S32("gBombchusOOB", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BombchusOOB"), 1), // Quick Putaway - PRESET_ENTRY_S32("gQuickPutaway", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuickPutaway"), 1), // Skip save confirmation - PRESET_ENTRY_S32("gSkipSaveConfirmation", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 1), }; const std::vector enhancedPresetEntries = { // D-pad Support in text and file select - PRESET_ENTRY_S32("gDpadText", 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1), // Play Ocarina with D-pad - PRESET_ENTRY_S32("gDpadOcarina", 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.Dpad"), 1), // Play Ocarina with Right Stick - PRESET_ENTRY_S32("gRStickOcarina", 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.RStick"), 1), // D-pad as Equip Items - PRESET_ENTRY_S32("gDpadEquips", 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadEquips"), 1), // Prevent Dropped Ocarina Inputs - PRESET_ENTRY_S32("gDpadNoDropOcarinaInput", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), 1), // Right Stick Aiming - PRESET_ENTRY_S32("gRightStickAiming", 1), + PRESET_ENTRY_S32(CVAR_SETTING("Controls.RightStickAim"), 1), // Text Speed (1 to 5) - PRESET_ENTRY_S32("gTextSpeed", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), // Skip Text - PRESET_ENTRY_S32("gSkipText", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), // King Zora Speed (1 to 5) - PRESET_ENTRY_S32("gMweepSpeed", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MweepSpeed"), 5), // Faster Block Push (+0 to +5) - PRESET_ENTRY_S32("gFasterBlockPush", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5), // Better Owl - PRESET_ENTRY_S32("gBetterOwl", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1), // Assignable Tunics and Boots - PRESET_ENTRY_S32("gAssignableTunicsAndBoots", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), // Enable passage of time on file select - PRESET_ENTRY_S32("gTimeFlowFileSelect", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeFlowFileSelect"), 1), // Inject Item Counts in messages - PRESET_ENTRY_S32("gInjectItemCounts", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts"), 1), // Pause link animation (0 to 16) - PRESET_ENTRY_S32("gPauseLiveLink", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PauseLiveLink"), 1), // Dynamic Wallet Icon - PRESET_ENTRY_S32("gDynamicWalletIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DynamicWalletIcon"), 1), // Always show dungeon entrances - PRESET_ENTRY_S32("gAlwaysShowDungeonMinimapIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), 1), // Fix L&R Pause menu - PRESET_ENTRY_S32("gUniformLR", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1), // Fix Dungeon entrances - PRESET_ENTRY_S32("gFixDungeonMinimapIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1), // Fix Two Handed idle animations - PRESET_ENTRY_S32("gTwoHandedIdle", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), // Fix the Gravedigging Tour Glitch - PRESET_ENTRY_S32("gGravediggingTourFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GravediggingTourFix"), 1), // Fix Deku Nut upgrade - PRESET_ENTRY_S32("gDekuNutUpgradeFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1), // Fix Navi text HUD position - PRESET_ENTRY_S32("gNaviTextFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1), // Extend Silver Rupee Jingle - PRESET_ENTRY_S32("gSilverRupeeJingleExtend", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 1), // Fix enemies not spawning on ground over water - PRESET_ENTRY_S32("gEnemySpawnsOverWaterboxes", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EnemySpawnsOverWaterboxes"), 1), + // Fix some Floor Switches + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixFloorSwitches"), 1), // Red Ganon blood - PRESET_ENTRY_S32("gRedGanonBlood", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RedGanonBlood"), 1), // Fish while hovering - PRESET_ENTRY_S32("gHoverFishing", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("HoverFishing"), 1), // N64 Weird Frames - PRESET_ENTRY_S32("gN64WeirdFrames", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("N64WeirdFrames"), 1), // Bombchus out of bounds - PRESET_ENTRY_S32("gBombchusOOB", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BombchusOOB"), 1), // Quick Putaway - PRESET_ENTRY_S32("gQuickPutaway", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuickPutaway"), 1), // Skip save confirmation - PRESET_ENTRY_S32("gSkipSaveConfirmation", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 1), // Biggoron Forge Time (0 to 3) - PRESET_ENTRY_S32("gForgeTime", 0), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ForgeTime"), 0), // Vine/Ladder Climb speed (+0 to +12) - PRESET_ENTRY_S32("gClimbSpeed", 3), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ClimbSpeed"), 3), // Faster Heavy Block Lift - PRESET_ENTRY_S32("gFasterHeavyBlockLift", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 1), // No Forced Navi - PRESET_ENTRY_S32("gNoForcedNavi", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoForcedNavi"), 1), // No Skulltula Freeze - PRESET_ENTRY_S32("gSkulltulaFreeze", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkulltulaFreeze"), 1), // MM Bunny Hood - PRESET_ENTRY_S32("gMMBunnyHood", BUNNY_HOOD_FAST_AND_JUMP), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP), // Adult Bunny Hood - PRESET_ENTRY_S32("gAdultBunnyHood", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), // Fast Chests - PRESET_ENTRY_S32("gFastChests", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), // Fast Drops - PRESET_ENTRY_S32("gFastDrops", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastDrops"), 1), // Fast Ocarina Playback - PRESET_ENTRY_S32("gFastOcarinaPlayback", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastOcarinaPlayback"), 1), // Instant Putaway - PRESET_ENTRY_S32("gInstantPutaway", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), // Instant Boomerang Recall - PRESET_ENTRY_S32("gFastBoomerang", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), // Nuts Explode Bombs - PRESET_ENTRY_S32("gNutsExplodeBombs", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NutsExplodeBombs"), 1), // Ask to Equip New Items - PRESET_ENTRY_S32("gAskToEquip", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AskToEquip"), 1), // Mask Select in Inventory - PRESET_ENTRY_S32("gMaskSelect", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MaskSelect"), 1), // Always Win Goron Pot - PRESET_ENTRY_S32("gGoronPot", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GoronPot"), 1), // Always Win Dampe Digging - PRESET_ENTRY_S32("gDampeWin", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeWin"), 1), // Skip Magic Arrow Equip Animation - PRESET_ENTRY_S32("gSkipArrowAnimation", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipArrowAnimation"), 1), // Equip arrows on multiple slots - PRESET_ENTRY_S32("gSeparateArrows", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1), // Disable Navi Call Audio - PRESET_ENTRY_S32("gDisableNaviCallAudio", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1), // Equipment Toggle - PRESET_ENTRY_S32("gEquipmentCanBeRemoved", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1), // Link's Cow in Both Time Periods - PRESET_ENTRY_S32("gCowOfTime", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CowOfTime"), 1), // Enable 3D Dropped items/projectiles - PRESET_ENTRY_S32("gNewDrops", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NewDrops"), 1), // Fix Anubis fireballs - PRESET_ENTRY_S32("gAnubisFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubixFix"), 1), // Autosave - PRESET_ENTRY_S32("gAutosave", AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), }; const std::vector randomizerPresetEntries = { // D-pad Support in text and file select - PRESET_ENTRY_S32("gDpadText", 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1), // Play Ocarina with D-pad - PRESET_ENTRY_S32("gDpadOcarina", 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.Dpad"), 1), // Play Ocarina with Right Stick - PRESET_ENTRY_S32("gRStickOcarina", 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.RStick"), 1), // D-pad as Equip Items - PRESET_ENTRY_S32("gDpadEquips", 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadEquips"), 1), // Prevent Dropped Ocarina Inputs - PRESET_ENTRY_S32("gDpadNoDropOcarinaInput", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), 1), // Right Stick Aiming - PRESET_ENTRY_S32("gRightStickAiming", 1), + PRESET_ENTRY_S32(CVAR_SETTING("Controls.RightStickAim"), 1), // Text Speed (1 to 5) - PRESET_ENTRY_S32("gTextSpeed", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), // Skip Text - PRESET_ENTRY_S32("gSkipText", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), // King Zora Speed (1 to 5) - PRESET_ENTRY_S32("gMweepSpeed", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MweepSpeed"), 5), // Faster Block Push (+0 to +5) - PRESET_ENTRY_S32("gFasterBlockPush", 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5), // Better Owl - PRESET_ENTRY_S32("gBetterOwl", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1), // Assignable Tunics and Boots - PRESET_ENTRY_S32("gAssignableTunicsAndBoots", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), // Enable passage of time on file select - PRESET_ENTRY_S32("gTimeFlowFileSelect", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeFlowFileSelect"), 1), // Inject Item Counts in messages - PRESET_ENTRY_S32("gInjectItemCounts", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts"), 1), // Dynamic Wallet Icon - PRESET_ENTRY_S32("gDynamicWalletIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DynamicWalletIcon"), 1), // Always show dungeon entrances - PRESET_ENTRY_S32("gAlwaysShowDungeonMinimapIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), 1), // Fix L&R Pause menu - PRESET_ENTRY_S32("gUniformLR", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1), // Fix Dungeon entrances - PRESET_ENTRY_S32("gFixDungeonMinimapIcon", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1), // Fix Two Handed idle animations - PRESET_ENTRY_S32("gTwoHandedIdle", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), // Fix the Gravedigging Tour Glitch - PRESET_ENTRY_S32("gGravediggingTourFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GravediggingTourFix"), 1), // Fix Deku Nut upgrade - PRESET_ENTRY_S32("gDekuNutUpgradeFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1), // Fix Navi text HUD position - PRESET_ENTRY_S32("gNaviTextFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1), // Extend Silver Rupee Jingle - PRESET_ENTRY_S32("gSilverRupeeJingleExtend", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 1), + // Fix some Floor Switches + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixFloorSwitches"), 1), // Red Ganon blood - PRESET_ENTRY_S32("gRedGanonBlood", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RedGanonBlood"), 1), // Fish while hovering - PRESET_ENTRY_S32("gHoverFishing", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("HoverFishing"), 1), // N64 Weird Frames - PRESET_ENTRY_S32("gN64WeirdFrames", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("N64WeirdFrames"), 1), // Bombchus out of bounds - PRESET_ENTRY_S32("gBombchusOOB", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BombchusOOB"), 1), // Quick Putaway - PRESET_ENTRY_S32("gQuickPutaway", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuickPutaway"), 1), // Skip save confirmation - PRESET_ENTRY_S32("gSkipSaveConfirmation", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 1), // Biggoron Forge Time (0 to 3) - PRESET_ENTRY_S32("gForgeTime", 0), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ForgeTime"), 0), // Vine/Ladder Climb speed (+0 to +12) - PRESET_ENTRY_S32("gClimbSpeed", 3), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ClimbSpeed"), 3), // Faster Heavy Block Lift - PRESET_ENTRY_S32("gFasterHeavyBlockLift", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 1), // No Forced Navi - PRESET_ENTRY_S32("gNoForcedNavi", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoForcedNavi"), 1), // No Skulltula Freeze - PRESET_ENTRY_S32("gSkulltulaFreeze", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkulltulaFreeze"), 1), // MM Bunny Hood - PRESET_ENTRY_S32("gMMBunnyHood", BUNNY_HOOD_FAST_AND_JUMP), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP), // Adult Bunny Hood - PRESET_ENTRY_S32("gAdultBunnyHood", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), // Fast Chests - PRESET_ENTRY_S32("gFastChests", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), // Fast Drops - PRESET_ENTRY_S32("gFastDrops", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastDrops"), 1), // Fast Ocarina Playback - PRESET_ENTRY_S32("gFastOcarinaPlayback", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastOcarinaPlayback"), 1), // Instant Putaway - PRESET_ENTRY_S32("gInstantPutaway", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), // Instant Boomerang Recall - PRESET_ENTRY_S32("gFastBoomerang", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), // Nuts Explode Bombs - PRESET_ENTRY_S32("gNutsExplodeBombs", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NutsExplodeBombs"), 1), // Ask to Equip New Items - PRESET_ENTRY_S32("gAskToEquip", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AskToEquip"), 1), // Mask Select in Inventory - PRESET_ENTRY_S32("gMaskSelect", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MaskSelect"), 1), // Always Win Goron Pot - PRESET_ENTRY_S32("gGoronPot", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GoronPot"), 1), // Always Win Dampe Digging - PRESET_ENTRY_S32("gDampeWin", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeWin"), 1), // Skip Magic Arrow Equip Animation - PRESET_ENTRY_S32("gSkipArrowAnimation", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipArrowAnimation"), 1), // Exit Market at Night - PRESET_ENTRY_S32("gMarketSneak", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MarketSneak"), 1), // Equip arrows on multiple slots - PRESET_ENTRY_S32("gSeparateArrows", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1), // Disable Navi Call Audio - PRESET_ENTRY_S32("gDisableNaviCallAudio", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1), // Equipment Toggle - PRESET_ENTRY_S32("gEquipmentCanBeRemoved", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1), // Link's Cow in Both Time Periods - PRESET_ENTRY_S32("gCowOfTime", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CowOfTime"), 1), // Enable 3D Dropped items/projectiles - PRESET_ENTRY_S32("gNewDrops", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NewDrops"), 1), // Fix Anubis fireballs - PRESET_ENTRY_S32("gAnubisFix", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubixFix"), 1), // Autosave - PRESET_ENTRY_S32("gAutosave", AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), // Customize Fishing Behaviour - PRESET_ENTRY_S32("gCustomizeFishing", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFishing"), 1), // Guarantee Bite - PRESET_ENTRY_S32("gGuaranteeFishingBite", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GuaranteeFishingBite"), 1), // Fish Never Escape - PRESET_ENTRY_S32("gFishNeverEscape", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FishNeverEscape"), 1), // Child Minimum Weight (6 to 10) - PRESET_ENTRY_S32("gChildMinimumWeightFish", 3), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 3), // Adult Minimum Weight (8 to 13) - PRESET_ENTRY_S32("gAdultMinimumWeightFish", 6), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6), + + // Customize Lost Woods Ocarina Game Behavior + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeOcarinaGame"), 1), + // Start With Five Notes + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("OcarinaGame.StartingNotes"), 5), + // Round One Notes + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("OcarinaGame.RoundOneNotes"), 5), // Visual Stone of Agony - PRESET_ENTRY_S32("gVisualAgony", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("VisualAgony"), 1), // Pull grave during the day - PRESET_ENTRY_S32("gDayGravePull", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DayGravePull"), 1), // Pull out Ocarina to Summon Scarecrow - PRESET_ENTRY_S32("gSkipScarecrow", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantScarecrow"), 1), // Chest size & texture matches contents - PRESET_ENTRY_S32("gChestSizeAndTextureMatchesContents", CSMC_BOTH), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH), + + // Color Temple of Time's Medallions + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ToTMedallionsColors"), 1), // Pause link animation (0 to 16) - PRESET_ENTRY_S32("gPauseLiveLink", 16), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PauseLiveLink"), 16), // Frames to wait - PRESET_ENTRY_S32("gMinFrameCount", 200), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinFrameCount"), 200), - PRESET_ENTRY_S32("gNoInputForCredits", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoInputForCredits"), 1), - PRESET_ENTRY_S32("gFastFarores", 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastFarores"), 1), }; const std::vector spockRacePresetEntries = { - PRESET_ENTRY_S32("gRandomizeLogicRules", 0), - PRESET_ENTRY_S32("gGameplayStats.RTATiming", 1), - PRESET_ENTRY_S32("gTextSpeed", 5), - PRESET_ENTRY_S32("gMweepSpeed", 5), - PRESET_ENTRY_S32("gClimbSpeed", 4), - PRESET_ENTRY_S32("gFasterBlockPush", 5), - PRESET_ENTRY_S32("gFasterHeavyBlockLift", 1), - PRESET_ENTRY_S32("gNoForcedNavi", 1), - PRESET_ENTRY_S32("gDisableLOD", 1), - PRESET_ENTRY_S32("gDisableNaviCallAudio", 1), - PRESET_ENTRY_S32("gFastChests", 1), - PRESET_ENTRY_S32("gFastDrops", 1), - PRESET_ENTRY_S32("gDpadText", 1), - PRESET_ENTRY_S32("gDpadOcarina", 1), - PRESET_ENTRY_S32("gRStickOcarina", 1), - PRESET_ENTRY_S32("gDpadEquips", 1), - PRESET_ENTRY_S32("gFastOcarinaPlayback", 1), - PRESET_ENTRY_S32("gSkipScarecrow", 1), - PRESET_ENTRY_S32("gMarketSneak", 1), - PRESET_ENTRY_S32("gInstantPutaway", 1), - PRESET_ENTRY_S32("gFastBoomerang", 1), - PRESET_ENTRY_S32("gDpadNoDropOcarinaInput", 1), - PRESET_ENTRY_S32("gAdultBunnyHood", 1), - PRESET_ENTRY_S32("gMMBunnyHood", BUNNY_HOOD_FAST), - PRESET_ENTRY_S32("gSeparateArrows", 1), - PRESET_ENTRY_S32("gAssignableTunicsAndBoots", 1), - PRESET_ENTRY_S32("gEquipmentCanBeRemoved", 1), - PRESET_ENTRY_S32("gDayGravePull", 1), - PRESET_ENTRY_S32("gDrawLineupTick", 1), - PRESET_ENTRY_S32("gNewDrops", 1), - PRESET_ENTRY_S32("gCreditsFix", 1), - PRESET_ENTRY_S32("gSkipText", 1), - PRESET_ENTRY_S32("gSkulltulaFreeze", 1), - PRESET_ENTRY_S32("gPauseAnyCursor", 1), - PRESET_ENTRY_S32("gHideBuildInfo", 1), - PRESET_ENTRY_S32("gSkipLogoTitle", 1), - PRESET_ENTRY_S32("gSaveFileID", 4), - PRESET_ENTRY_S32("gFastFarores", 1), - PRESET_ENTRY_S32("gNoInputForCredits", 1), - PRESET_ENTRY_S32("gMaskSelect", 1), - PRESET_ENTRY_S32("gInjectItemCounts", 1), - PRESET_ENTRY_S32("gCustomizeFishing", 1), - PRESET_ENTRY_S32("gFishNeverEscape", 1), - PRESET_ENTRY_S32("gInstantFishing", 1), - PRESET_ENTRY_S32("gGuaranteeFishingBite", 1), - PRESET_ENTRY_S32("gAdultMinimumWeightFish", 6), - PRESET_ENTRY_S32("gChildMinimumWeightFish", 3), - PRESET_ENTRY_S32("gGoronPot", 1), - PRESET_ENTRY_S32("gForgeTime", 0), - PRESET_ENTRY_S32("gDisableFirstPersonChus", 1), - PRESET_ENTRY_S32("gCheatEasyPauseBufferEnabled", 1), - PRESET_ENTRY_S32("gDampeAllNight", 1), - PRESET_ENTRY_S32("gRandomize10GSHint", 1), - PRESET_ENTRY_S32("gRandomize20GSHint", 1), - PRESET_ENTRY_S32("gRandomize30GSHint", 1), - PRESET_ENTRY_S32("gRandomize40GSHint", 1), - PRESET_ENTRY_S32("gRandomize50GSHint", 1), - PRESET_ENTRY_S32("gRandomizeAllLocationsReachable", 0), - PRESET_ENTRY_S32("gRandomizeBlueFireArrows", 1), - PRESET_ENTRY_S32("gRandomizeBombchusInLogic", 1), - PRESET_ENTRY_S32("gRandomizeCompleteMaskQuest", 1), - PRESET_ENTRY_S32("gRandomizeCuccosToReturn", 1), - PRESET_ENTRY_S32("gRandomizeDampeHint", 1), - PRESET_ENTRY_S32("gRandomizeDoorOfTime", RO_DOOROFTIME_OPEN), - PRESET_ENTRY_S32("gRandomizeEnableBombchuDrops", 1), - PRESET_ENTRY_CPP_STRING("gRandomizeExcludedLocations", FormatLocations( + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LogicRules"), 0), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MweepSpeed"), 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ClimbSpeed"), 4), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoForcedNavi"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastDrops"), 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.Dpad"), 1), + PRESET_ENTRY_S32(CVAR_SETTING("OcarinaControl.RStick"), 1), + PRESET_ENTRY_S32(CVAR_SETTING("DpadEquips"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastOcarinaPlayback"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantScarecrow"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MarketSneak"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DayGravePull"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NewDrops"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CreditsFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkulltulaFreeze"), 1), + PRESET_ENTRY_S32(CVAR_SETTING("PauseAnyCursor"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastFarores"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoInputForCredits"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MaskSelect"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFishing"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FishNeverEscape"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantFishing"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GuaranteeFishingBite"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 3), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GoronPot"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ForgeTime"), 0), + PRESET_ENTRY_S32(CVAR_CHEAT("EasyPauseBuffer"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeAllNight"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("10GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("20GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("30GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("40GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("50GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), 0), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BombchusInLogic"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DampeHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1), + PRESET_ENTRY_CPP_STRING(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), FormatLocations( { RC_MARKET_10_BIG_POES, RC_KAK_40_GOLD_SKULLTULA_REWARD, RC_KAK_50_GOLD_SKULLTULA_REWARD, RC_ZR_FROGS_OCARINA_GAME })), - PRESET_ENTRY_S32("gRandomizeForest", RO_FOREST_OPEN), - PRESET_ENTRY_S32("gRandomizeFullWallets", 1), - PRESET_ENTRY_S32("gRandomizeGanonTrial", RO_GANONS_TRIALS_SKIP), - PRESET_ENTRY_S32("gRandomizeGerudoFortress", RO_GF_FAST), - PRESET_ENTRY_S32("gRandomizeGregHint", 1), - PRESET_ENTRY_S32("gRandomizeGsExpectSunsSong", 1), - PRESET_ENTRY_S32("gRandomizeKakarikoGate", RO_KAK_GATE_OPEN), - PRESET_ENTRY_S32("gRandomizeLacsRewardCount", 5), - PRESET_ENTRY_S32("gRandomizeRainbowBridge", RO_BRIDGE_GREG), - PRESET_ENTRY_S32("gRandomizeScrubText", 1), - PRESET_ENTRY_S32("gRandomizeShopsanity", RO_SHOPSANITY_RANDOM), - PRESET_ENTRY_S32("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_LACS_REWARDS), - PRESET_ENTRY_S32("gRandomizeShuffleKeyRings", RO_KEYRINGS_COUNT), - PRESET_ENTRY_S32("gRandomizeShuffleKokiriSword", 1), - PRESET_ENTRY_S32("gRandomizeShuffleOcarinas", 1), - PRESET_ENTRY_S32("gRandomizeShuffleScrubs", RO_SCRUBS_AFFORDABLE), - PRESET_ENTRY_S32("gRandomizeSkipChildStealth", 1), - PRESET_ENTRY_S32("gRandomizeSkipChildZelda", 1), - PRESET_ENTRY_S32("gRandomizeSkipEponaRace", 1), - PRESET_ENTRY_S32("gRandomizeSkipScarecrowsSong", 1), - PRESET_ENTRY_S32("gRandomizeSkipTowerEscape", 1), - PRESET_ENTRY_S32("gRandomizeStartingConsumables", 1), - PRESET_ENTRY_S32("gRandomizeStartingMapsCompasses", RO_DUNGEON_ITEM_LOC_STARTWITH), - PRESET_ENTRY_S32("gRandomizeStartingOcarina", 1), - PRESET_ENTRY_S32("gRandomizeSunlightArrows", 1), - PRESET_ENTRY_S32("gRandomizerSettingsEnabled", 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FullWallets"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_FAST), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 5), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_AFFORDABLE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildStealth"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingConsumables"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1), }; const std::vector spockRaceNoLogicPresetEntries = { - PRESET_ENTRY_S32("gAdultBunnyHood", 1), - PRESET_ENTRY_S32("gAdultMinimumWeightFish", 6), - PRESET_ENTRY_S32("gAssignableTunicsAndBoots", 1), - PRESET_ENTRY_S32("gCheatEasyPauseBufferEnabled", 1), - PRESET_ENTRY_S32("gChildMinimumWeightFish", 3), - PRESET_ENTRY_S32("gClimbSpeed", 4), - PRESET_ENTRY_S32("gCosmetics.Goron_NeckLength", 1000), - PRESET_ENTRY_S32("gCreditsFix", 1), - PRESET_ENTRY_S32("gCustomizeFishing", 1), - PRESET_ENTRY_S32("gDampeAllNight", 1), - PRESET_ENTRY_S32("gDayGravePull", 1), - PRESET_ENTRY_S32("gDisableFirstPersonChus", 1), - PRESET_ENTRY_S32("gDisableLOD", 1), - PRESET_ENTRY_S32("gDisableNaviCallAudio", 1), - PRESET_ENTRY_S32("gDpadEquips", 1), - PRESET_ENTRY_S32("gDpadNoDropOcarinaInput", 1), - PRESET_ENTRY_S32("gDpadOcarina", 1), - PRESET_ENTRY_S32("gDpadText", 1), - PRESET_ENTRY_S32("gDrawLineupTick", 1), - PRESET_ENTRY_S32("gEquipmentCanBeRemoved", 1), - PRESET_ENTRY_S32("gFastBoomerang", 1), - PRESET_ENTRY_S32("gFastChests", 1), - PRESET_ENTRY_S32("gFastDrops", 1), - PRESET_ENTRY_S32("gFastFarores", 1), - PRESET_ENTRY_S32("gFastOcarinaPlayback", 1), - PRESET_ENTRY_S32("gFasterBlockPush", 5), - PRESET_ENTRY_S32("gFasterHeavyBlockLift", 1), - PRESET_ENTRY_S32("gFishNeverEscape", 1), - PRESET_ENTRY_S32("gForgeTime", 0), - PRESET_ENTRY_S32("gGameplayStats.RTATiming", 1), - PRESET_ENTRY_S32("gGameplayStats.ShowIngameTimer", 1), - PRESET_ENTRY_S32("gGoronPot", 1), - PRESET_ENTRY_S32("gGuaranteeFishingBite", 1), - PRESET_ENTRY_S32("gHideBuildInfo", 1), - PRESET_ENTRY_S32("gInjectItemCounts", 1), - PRESET_ENTRY_S32("gInstantFishing", 1), - PRESET_ENTRY_S32("gInstantPutaway", 1), - PRESET_ENTRY_S32("gMMBunnyHood", BUNNY_HOOD_FAST), - PRESET_ENTRY_S32("gMarketSneak", 1), - PRESET_ENTRY_S32("gMaskSelect", 1), - PRESET_ENTRY_S32("gMweepSpeed", 5), - PRESET_ENTRY_S32("gNewDrops", 1), - PRESET_ENTRY_S32("gNoForcedNavi", 1), - PRESET_ENTRY_S32("gNoInputForCredits", 1), - PRESET_ENTRY_S32("gOnFileSelectNameEntry", 0), - PRESET_ENTRY_S32("gOpenMenuBar", 1), - PRESET_ENTRY_S32("gPauseAnyCursor", 1), - PRESET_ENTRY_S32("gRStickOcarina", 1), - PRESET_ENTRY_S32("gRandomize10GSHint", 1), - PRESET_ENTRY_S32("gRandomize20GSHint", 1), - PRESET_ENTRY_S32("gRandomize30GSHint", 1), - PRESET_ENTRY_S32("gRandomize40GSHint", 1), - PRESET_ENTRY_S32("gRandomize50GSHint", 1), - PRESET_ENTRY_S32("gRandomizeAllLocationsReachable", 0), - PRESET_ENTRY_S32("gRandomizeBlueFireArrows", 1), - PRESET_ENTRY_S32("gRandomizeBombchusInLogic", 1), - PRESET_ENTRY_S32("gRandomizeBossKeysanity", RO_DUNGEON_ITEM_LOC_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeCompleteMaskQuest", 1), - PRESET_ENTRY_S32("gRandomizeCuccosToReturn", 1), - PRESET_ENTRY_S32("gRandomizeDampeHint", 1), - PRESET_ENTRY_S32("gRandomizeDoorOfTime", RO_DOOROFTIME_OPEN), - PRESET_ENTRY_S32("gRandomizeEnableBombchuDrops", 1), - PRESET_ENTRY_CPP_STRING("gRandomizeExcludedLocations", FormatLocations( + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), + PRESET_ENTRY_S32(CVAR_CHEAT("EasyPauseBuffer"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 3), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ClimbSpeed"), 4), + PRESET_ENTRY_S32(CVAR_COSMETIC("Goron.NeckLength"), 1000), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CreditsFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFishing"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeAllNight"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DayGravePull"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastDrops"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastFarores"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastOcarinaPlayback"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FishNeverEscape"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ForgeTime"), 0), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GoronPot"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GuaranteeFishingBite"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantFishing"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MarketSneak"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MaskSelect"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MweepSpeed"), 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoForcedNavi"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoInputForCredits"), 1), + PRESET_ENTRY_S32(CVAR_SETTING("PauseAnyCursor"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("10GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("20GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("30GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("40GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("50GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), 0), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BombchusInLogic"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DampeHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1), + PRESET_ENTRY_CPP_STRING(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), FormatLocations( { RC_MARKET_10_BIG_POES, RC_KAK_40_GOLD_SKULLTULA_REWARD, RC_KAK_50_GOLD_SKULLTULA_REWARD, RC_ZR_FROGS_OCARINA_GAME })), - PRESET_ENTRY_S32("gRandomizeForest", RO_FOREST_OPEN), - PRESET_ENTRY_S32("gRandomizeFullWallets", 1), - PRESET_ENTRY_S32("gRandomizeGanonTrial", RO_GANONS_TRIALS_SKIP), - PRESET_ENTRY_S32("gRandomizeGerudoFortress", RO_GF_FAST), - PRESET_ENTRY_S32("gRandomizeGerudoKeys", RO_GERUDO_KEYS_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeGregHint", 1), - PRESET_ENTRY_S32("gRandomizeGsExpectSunsSong", 0), - PRESET_ENTRY_S32("gRandomizeKakarikoGate", RO_KAK_GATE_OPEN), - PRESET_ENTRY_S32("gRandomizeKeysanity", RO_DUNGEON_ITEM_LOC_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeLacsRewardCount", 5), - PRESET_ENTRY_S32("gRandomizeLogicRules", RO_LOGIC_NO_LOGIC), - PRESET_ENTRY_S32("gRandomizeRainbowBridge", RO_BRIDGE_GREG), - PRESET_ENTRY_S32("gRandomizeScrubText", 1), - PRESET_ENTRY_S32("gRandomizeShopsanity", RO_SHOPSANITY_RANDOM), - PRESET_ENTRY_S32("gRandomizeShuffleAdultTrade", 0), - PRESET_ENTRY_S32("gRandomizeShuffleBeans", 1), - PRESET_ENTRY_S32("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_LACS_REWARDS), - PRESET_ENTRY_S32("gRandomizeShuffleGerudoToken", 1), - PRESET_ENTRY_S32("gRandomizeShuffleKeyRings", RO_KEYRINGS_COUNT), - PRESET_ENTRY_S32("gRandomizeShuffleKokiriSword", 1), - PRESET_ENTRY_S32("gRandomizeShuffleOcarinas", 1), - PRESET_ENTRY_S32("gRandomizeShuffleScrubs", 1), - PRESET_ENTRY_S32("gRandomizeShuffleSongs", RO_SONG_SHUFFLE_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeShuffleTokens", RO_TOKENSANITY_ALL), - PRESET_ENTRY_S32("gRandomizeSkipChildStealth", 1), - PRESET_ENTRY_S32("gRandomizeSkipChildZelda", 1), - PRESET_ENTRY_S32("gRandomizeSkipEponaRace", 1), - PRESET_ENTRY_S32("gRandomizeSkipScarecrowsSong", 1), - PRESET_ENTRY_S32("gRandomizeSkipTowerEscape", 1), - PRESET_ENTRY_S32("gRandomizeStartingConsumables", 1), - PRESET_ENTRY_S32("gRandomizeStartingMapsCompasses", RO_DUNGEON_ITEM_LOC_STARTWITH), - PRESET_ENTRY_S32("gRandomizeStartingOcarina", 1), - PRESET_ENTRY_S32("gRandomizeSunlightArrows", 1), - PRESET_ENTRY_S32("gRandomizerSettingsEnabled", 1), - PRESET_ENTRY_S32("gSaveFileID", 4), - PRESET_ENTRY_S32("gSeparateArrows", 1), - PRESET_ENTRY_S32("gSkipLogoTitle", 1), - PRESET_ENTRY_S32("gSkipScarecrow", 1), - PRESET_ENTRY_S32("gSkipText", 1), - PRESET_ENTRY_S32("gSkulltulaFreeze", 1), - PRESET_ENTRY_S32("gTextSpeed", 5), - PRESET_ENTRY_S32("gZFightingMode", 0), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FullWallets"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_FAST), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), 0), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 5), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_NO_LOGIC), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 0), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildStealth"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingConsumables"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantScarecrow"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkulltulaFreeze"), 1), }; const std::vector s6PresetEntries = { - PRESET_ENTRY_S32("gChestSizeAndTextureMatchesContents", CSMC_BOTH), - PRESET_ENTRY_S32("gFastChests", 1), - PRESET_ENTRY_S32("gMMBunnyHood", BUNNY_HOOD_FAST), - PRESET_ENTRY_S32("gAdultBunnyHood", 1), - PRESET_ENTRY_S32("gRandomizeBigPoeTargetCount", 1), - PRESET_ENTRY_S32("gRandomizeCuccosToReturn", 4), - PRESET_ENTRY_S32("gRandomizeDoorOfTime", RO_DOOROFTIME_OPEN), - PRESET_ENTRY_CPP_STRING("gRandomizeExcludedLocations", FormatLocations({ RC_DEKU_THEATER_MASK_OF_TRUTH })), - PRESET_ENTRY_S32("gRandomizeForest", RO_FOREST_CLOSED_DEKU), - PRESET_ENTRY_S32("gRandomizeGanonTrial", RO_GANONS_TRIALS_SKIP), - PRESET_ENTRY_S32("gRandomizeGerudoFortress", RO_GF_FAST), - PRESET_ENTRY_S32("gRandomizeIceTraps", RO_ICE_TRAPS_OFF), - PRESET_ENTRY_S32("gRandomizeKakarikoGate", RO_KAK_GATE_OPEN), - PRESET_ENTRY_S32("gRandomizeMedallionCount", 6), - PRESET_ENTRY_S32("gRandomizeMqDungeons", RO_MQ_DUNGEONS_NONE), - PRESET_ENTRY_S32("gRandomizeRainbowBridge", RO_BRIDGE_MEDALLIONS), - PRESET_ENTRY_S32("gRandomizeShuffleAdultTrade", 1), - PRESET_ENTRY_S32("gRandomizeShuffleDungeonReward", RO_DUNGEON_REWARDS_END_OF_DUNGEON), - PRESET_ENTRY_S32("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_STARTWITH), - PRESET_ENTRY_S32("gRandomizeShuffleKokiriSword", 1), - PRESET_ENTRY_S32("gRandomizeShuffleOverworldSpawns", RO_GENERIC_ON), - PRESET_ENTRY_S32("gRandomizeSkipChildStealth", 1), - PRESET_ENTRY_S32("gRandomizeSkipChildZelda", 1), - PRESET_ENTRY_S32("gRandomizeSkipEponaRace", 1), - PRESET_ENTRY_S32("gRandomizeSkipTowerEscape", 1), - PRESET_ENTRY_S32("gRandomizeStartingAge", RO_AGE_RANDOM), - PRESET_ENTRY_S32("gRandomizeStartingConsumables", 1), - PRESET_ENTRY_S32("gRandomizeStartingDekuShield", 1), - PRESET_ENTRY_S32("gRandomizeStartingMapsCompasses", RO_DUNGEON_ITEM_LOC_STARTWITH), - PRESET_ENTRY_S32("gRandomizeStartingOcarina", 1), - PRESET_ENTRY_S32("gRandomizeZorasFountain", 0), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 4), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), + PRESET_ENTRY_CPP_STRING(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), FormatLocations({ RC_DEKU_THEATER_MASK_OF_TRUTH })), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_CLOSED_DEKU), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_FAST), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IceTraps"), RO_ICE_TRAPS_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MedallionCount"), 6), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_MEDALLIONS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_STARTWITH), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildStealth"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingConsumables"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingDekuShield"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 0), }; const std::vector hellModePresetEntries = { - PRESET_ENTRY_S32("gChestSizeAndTextureMatchesContents", CSMC_BOTH), - PRESET_ENTRY_S32("gFastChests", 1), - PRESET_ENTRY_S32("gMMBunnyHood", BUNNY_HOOD_FAST), - PRESET_ENTRY_S32("gAdultBunnyHood", 1), - PRESET_ENTRY_S32("gRandomizeBigPoeTargetCount", 1), - PRESET_ENTRY_S32("gRandomizeBlueFireArrows", 1), - PRESET_ENTRY_S32("gRandomizeBossKeysanity", RO_DUNGEON_ITEM_LOC_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeCompleteMaskQuest", 1), - PRESET_ENTRY_S32("gRandomizeCuccosToReturn", 1), - PRESET_ENTRY_S32("gRandomizeDoorOfTime", RO_DOOROFTIME_OPEN), - PRESET_ENTRY_S32("gRandomizeEnableBombchuDrops", 1), - PRESET_ENTRY_S32("gRandomizeEnableGlitchCutscenes", 1), - PRESET_ENTRY_S32("gRandomizeForest", RO_FOREST_OPEN), - PRESET_ENTRY_S32("gRandomizeGanonTrial", RO_GANONS_TRIALS_SET_NUMBER), - PRESET_ENTRY_S32("gRandomizeGanonTrialCount", 6), - PRESET_ENTRY_S32("gRandomizeGerudoKeys", RO_GERUDO_KEYS_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeGsExpectSunsSong", 1), - PRESET_ENTRY_S32("gRandomizeIceTraps", RO_ICE_TRAPS_ONSLAUGHT), - PRESET_ENTRY_S32("gRandomizeItemPool", RO_ITEM_POOL_MINIMAL), - PRESET_ENTRY_S32("gRandomizeKakarikoGate", RO_KAK_GATE_OPEN), - PRESET_ENTRY_S32("gRandomizeKeysanity", RO_DUNGEON_ITEM_LOC_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeLinksPocket", RO_LINKS_POCKET_NOTHING), - PRESET_ENTRY_S32("gRandomizeMqDungeons", RO_MQ_DUNGEONS_RANDOM_NUMBER), - PRESET_ENTRY_S32("gRandomizeRainbowBridge", RO_BRIDGE_DUNGEON_REWARDS), - PRESET_ENTRY_S32("gRandomizeShopsanity", RO_SHOPSANITY_FOUR_ITEMS), - PRESET_ENTRY_S32("gRandomizeShopsanityPrices", RO_SHOPSANITY_PRICE_TYCOON), - PRESET_ENTRY_S32("gRandomizeShuffleAdultTrade", 1), - PRESET_ENTRY_S32("gRandomizeShuffleBeans", 1), - PRESET_ENTRY_S32("gRandomizeShuffleCows", 1), - PRESET_ENTRY_S32("gRandomizeShuffleDungeonReward", RO_DUNGEON_REWARDS_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeShuffleFrogSongRupees", 1), - PRESET_ENTRY_S32("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_LACS_DUNGEONS), - PRESET_ENTRY_S32("gRandomizeShuffleGerudoToken", 1), - PRESET_ENTRY_S32("gRandomizeShuffleKeyRings", RO_KEYRINGS_RANDOM), - PRESET_ENTRY_S32("gRandomizeShuffleKokiriSword", 1), - PRESET_ENTRY_S32("gRandomizeShuffleMasterSword", 1), - PRESET_ENTRY_S32("gRandomizeShuffleOcarinas", 1), - PRESET_ENTRY_S32("gRandomizeShuffleScrubs", RO_SCRUBS_RANDOM), - PRESET_ENTRY_S32("gRandomizeShuffleSongs", RO_SONG_SHUFFLE_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeShuffleTokens", RO_TOKENSANITY_ALL), - PRESET_ENTRY_S32("gRandomizeShuffleWeirdEgg", 1), - PRESET_ENTRY_S32("gRandomizeSkipChildStealth", 1), - PRESET_ENTRY_S32("gRandomizeSkipEponaRace", 1), - PRESET_ENTRY_S32("gRandomizeSkipScarecrowsSong", 1), - PRESET_ENTRY_S32("gRandomizeSkipTowerEscape", 1), - PRESET_ENTRY_S32("gRandomizeStartingAge", RO_AGE_RANDOM), - PRESET_ENTRY_S32("gRandomizeStartingMapsCompasses", RO_DUNGEON_ITEM_LOC_ANYWHERE), - PRESET_ENTRY_S32("gRandomizeSunlightArrows", 1), - PRESET_ENTRY_S32("gRandomizeZorasFountain", 2), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableGlitchCutscenes"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SET_NUMBER), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrialCount"), 6), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IceTraps"), RO_ICE_TRAPS_ONSLAUGHT), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ItemPool"), RO_ITEM_POOL_MINIMAL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_NOTHING), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_RANDOM_NUMBER), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_DUNGEON_REWARDS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_FOUR_ITEMS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_SHOPSANITY_PRICE_TYCOON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_DUNGEONS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildStealth"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 2), }; typedef struct PresetDefinition { diff --git a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp index 5df67bb87..8dd8b4c63 100644 --- a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp @@ -26,7 +26,6 @@ typedef struct { AreaKey parentRegion; AreaKey connectedRegion; int16_t index; - int16_t blueWarp; } EntranceLinkInfo; EntranceLinkInfo NO_RETURN_ENTRANCE = {EntranceType::None, NONE, NONE, -1}; @@ -40,6 +39,11 @@ using EntranceInfoPair = std::pair; using EntrancePair = std::pair; using EntrancePools = std::map>; +// Construct entrance name from parent and connected region keys +std::string EntranceNameByRegions(uint32_t parentRegion, uint32_t connectedRegion) { + return AreaTable(parentRegion)->regionName + " -> " + AreaTable(connectedRegion)->regionName; +} + //The entrance randomization algorithm used here is a direct copy of //the algorithm used in the original N64 randomizer (except now in C++ instead //of python). It may be easier to understand the algorithm by looking at the @@ -77,26 +81,22 @@ void SetAllEntrancesData(std::vector& entranceShuffleTable) { //set data Entrance* forwardEntrance = AreaTable(forwardEntry.parentRegion)->GetExit(forwardEntry.connectedRegion); forwardEntrance->SetIndex(forwardEntry.index); - forwardEntrance->SetBlueWarp(forwardEntry.blueWarp); forwardEntrance->SetType(forwardEntry.type); forwardEntrance->SetAsPrimary(); - // When decouple entrances is on, mark it for entrances except boss rooms - if (Settings::DecoupleEntrances && forwardEntry.type != EntranceType::ChildBoss && - forwardEntry.type != EntranceType::AdultBoss) { + // When decouple entrances is on, mark the forward entrance + if (Settings::DecoupleEntrances) { forwardEntrance->SetDecoupled(); } if (returnEntry.parentRegion != NONE) { Entrance* returnEntrance = AreaTable(returnEntry.parentRegion)->GetExit(returnEntry.connectedRegion); returnEntrance->SetIndex(returnEntry.index); - returnEntrance->SetBlueWarp(returnEntry.blueWarp); returnEntrance->SetType(returnEntry.type); forwardEntrance->BindTwoWay(returnEntrance); // Mark reverse entrance as decoupled - if (Settings::DecoupleEntrances && returnEntry.type != EntranceType::ChildBoss && - returnEntry.type != EntranceType::AdultBoss) { + if (Settings::DecoupleEntrances) { returnEntrance->SetDecoupled(); } } @@ -687,31 +687,31 @@ int ShuffleAllEntrances() { curNumRandomizedEntrances = 0; std::vector entranceShuffleTable = { - //Parent Region Connected Region index blue warp + //Parent Region Connected Region index {{EntranceType::Dungeon, KF_OUTSIDE_DEKU_TREE, DEKU_TREE_ENTRYWAY, 0x0000}, - {EntranceType::Dungeon, DEKU_TREE_ENTRYWAY, KF_OUTSIDE_DEKU_TREE, 0x0209, 0x0457}}, + {EntranceType::Dungeon, DEKU_TREE_ENTRYWAY, KF_OUTSIDE_DEKU_TREE, 0x0209}}, {{EntranceType::Dungeon, DEATH_MOUNTAIN_TRAIL, DODONGOS_CAVERN_ENTRYWAY, 0x0004}, - {EntranceType::Dungeon, DODONGOS_CAVERN_ENTRYWAY, DEATH_MOUNTAIN_TRAIL, 0x0242, 0x047A}}, + {EntranceType::Dungeon, DODONGOS_CAVERN_ENTRYWAY, DEATH_MOUNTAIN_TRAIL, 0x0242}}, {{EntranceType::Dungeon, ZORAS_FOUNTAIN, JABU_JABUS_BELLY_ENTRYWAY, 0x0028}, - {EntranceType::Dungeon, JABU_JABUS_BELLY_ENTRYWAY, ZORAS_FOUNTAIN, 0x0221, 0x010E}}, + {EntranceType::Dungeon, JABU_JABUS_BELLY_ENTRYWAY, ZORAS_FOUNTAIN, 0x0221}}, {{EntranceType::Dungeon, SACRED_FOREST_MEADOW, FOREST_TEMPLE_ENTRYWAY, 0x0169}, - {EntranceType::Dungeon, FOREST_TEMPLE_ENTRYWAY, SACRED_FOREST_MEADOW, 0x0215, 0x0608}}, + {EntranceType::Dungeon, FOREST_TEMPLE_ENTRYWAY, SACRED_FOREST_MEADOW, 0x0215}}, {{EntranceType::Dungeon, DMC_CENTRAL_LOCAL, FIRE_TEMPLE_ENTRYWAY, 0x0165}, - {EntranceType::Dungeon, FIRE_TEMPLE_ENTRYWAY, DMC_CENTRAL_LOCAL, 0x024A, 0x0564}}, + {EntranceType::Dungeon, FIRE_TEMPLE_ENTRYWAY, DMC_CENTRAL_LOCAL, 0x024A}}, {{EntranceType::Dungeon, LAKE_HYLIA, WATER_TEMPLE_ENTRYWAY, 0x0010}, - {EntranceType::Dungeon, WATER_TEMPLE_ENTRYWAY, LAKE_HYLIA, 0x021D, 0x060C}}, + {EntranceType::Dungeon, WATER_TEMPLE_ENTRYWAY, LAKE_HYLIA, 0x021D}}, {{EntranceType::Dungeon, DESERT_COLOSSUS, SPIRIT_TEMPLE_ENTRYWAY, 0x0082}, - {EntranceType::Dungeon, SPIRIT_TEMPLE_ENTRYWAY, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, 0x01E1, 0x0610}}, + {EntranceType::Dungeon, SPIRIT_TEMPLE_ENTRYWAY, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, 0x01E1}}, {{EntranceType::Dungeon, GRAVEYARD_WARP_PAD_REGION, SHADOW_TEMPLE_ENTRYWAY, 0x0037}, - {EntranceType::Dungeon, SHADOW_TEMPLE_ENTRYWAY, GRAVEYARD_WARP_PAD_REGION, 0x0205, 0x0580}}, + {EntranceType::Dungeon, SHADOW_TEMPLE_ENTRYWAY, GRAVEYARD_WARP_PAD_REGION, 0x0205}}, {{EntranceType::Dungeon, KAKARIKO_VILLAGE, BOTTOM_OF_THE_WELL_ENTRYWAY, 0x0098}, {EntranceType::Dungeon, BOTTOM_OF_THE_WELL_ENTRYWAY, KAKARIKO_VILLAGE, 0x02A6}}, {{EntranceType::Dungeon, ZORAS_FOUNTAIN, ICE_CAVERN_ENTRYWAY, 0x0088}, {EntranceType::Dungeon, ICE_CAVERN_ENTRYWAY, ZORAS_FOUNTAIN, 0x03D4}}, {{EntranceType::Dungeon, GERUDO_FORTRESS, GERUDO_TRAINING_GROUNDS_ENTRYWAY, 0x0008}, {EntranceType::Dungeon, GERUDO_TRAINING_GROUNDS_ENTRYWAY, GERUDO_FORTRESS, 0x03A8}}, - {{EntranceType::GanonDungeon, GANONS_CASTLE_LEDGE, GANONS_CASTLE_ENTRYWAY, 0x0467}, - {EntranceType::GanonDungeon, GANONS_CASTLE_ENTRYWAY, CASTLE_GROUNDS_FROM_GANONS_CASTLE, 0x023D}}, + {{EntranceType::GanonDungeon, GANONS_CASTLE_LEDGE, GANONS_CASTLE_ENTRYWAY, 0x0467}, + {EntranceType::GanonDungeon, GANONS_CASTLE_ENTRYWAY, CASTLE_GROUNDS_FROM_GANONS_CASTLE, 0x023D}}, {{EntranceType::Interior, KOKIRI_FOREST, KF_MIDOS_HOUSE, 0x0433}, {EntranceType::Interior, KF_MIDOS_HOUSE, KOKIRI_FOREST, 0x0443}}, @@ -947,21 +947,30 @@ int ShuffleAllEntrances() { {{EntranceType::WarpSong, PRELUDE_OF_LIGHT_WARP, TEMPLE_OF_TIME, 0x05F4}, NO_RETURN_ENTRANCE}, {{EntranceType::ChildBoss, DEKU_TREE_BOSS_ENTRYWAY, DEKU_TREE_BOSS_ROOM, 0x040F}, - {EntranceType::ChildBoss, DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY, 0x0252, 0x0457}}, + {EntranceType::ChildBoss, DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY, 0x0252}}, {{EntranceType::ChildBoss, DODONGOS_CAVERN_BOSS_ENTRYWAY, DODONGOS_CAVERN_BOSS_ROOM, 0x040B}, - {EntranceType::ChildBoss, DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY, 0x00C5, 0x047A}}, + {EntranceType::ChildBoss, DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY, 0x00C5}}, {{EntranceType::ChildBoss, JABU_JABUS_BELLY_BOSS_ENTRYWAY, JABU_JABUS_BELLY_BOSS_ROOM, 0x0301}, - {EntranceType::ChildBoss, JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY, 0x0407, 0x010E}}, + {EntranceType::ChildBoss, JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY, 0x0407}}, {{EntranceType::AdultBoss, FOREST_TEMPLE_BOSS_ENTRYWAY, FOREST_TEMPLE_BOSS_ROOM, 0x000C}, - {EntranceType::AdultBoss, FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY, 0x024E, 0x0608}}, + {EntranceType::AdultBoss, FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY, 0x024E}}, {{EntranceType::AdultBoss, FIRE_TEMPLE_BOSS_ENTRYWAY, FIRE_TEMPLE_BOSS_ROOM, 0x0305}, - {EntranceType::AdultBoss, FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY, 0x0175, 0x0564}}, + {EntranceType::AdultBoss, FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY, 0x0175}}, {{EntranceType::AdultBoss, WATER_TEMPLE_BOSS_ENTRYWAY, WATER_TEMPLE_BOSS_ROOM, 0x0417}, - {EntranceType::AdultBoss, WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY, 0x0423, 0x060C}}, + {EntranceType::AdultBoss, WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY, 0x0423}}, {{EntranceType::AdultBoss, SPIRIT_TEMPLE_BOSS_ENTRYWAY, SPIRIT_TEMPLE_BOSS_ROOM, 0x008D}, - {EntranceType::AdultBoss, SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY, 0x02F5, 0x0610}}, + {EntranceType::AdultBoss, SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY, 0x02F5}}, {{EntranceType::AdultBoss, SHADOW_TEMPLE_BOSS_ENTRYWAY, SHADOW_TEMPLE_BOSS_ROOM, 0x0413}, - {EntranceType::AdultBoss, SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY, 0x02B2, 0x0580}}, + {EntranceType::AdultBoss, SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY, 0x02B2}}, + + {{EntranceType::BlueWarp, DEKU_TREE_BOSS_ROOM, KF_OUTSIDE_DEKU_TREE, 0x0457}, NO_RETURN_ENTRANCE}, + {{EntranceType::BlueWarp, DODONGOS_CAVERN_BOSS_ROOM, DEATH_MOUNTAIN_TRAIL, 0x047A}, NO_RETURN_ENTRANCE}, + {{EntranceType::BlueWarp, JABU_JABUS_BELLY_BOSS_ROOM, ZORAS_FOUNTAIN, 0x010E}, NO_RETURN_ENTRANCE}, + {{EntranceType::BlueWarp, FOREST_TEMPLE_BOSS_ROOM, SACRED_FOREST_MEADOW, 0x0608}, NO_RETURN_ENTRANCE}, + {{EntranceType::BlueWarp, FIRE_TEMPLE_BOSS_ROOM, DMC_CENTRAL_LOCAL, 0x0564}, NO_RETURN_ENTRANCE}, + {{EntranceType::BlueWarp, WATER_TEMPLE_BOSS_ROOM, LAKE_HYLIA, 0x060C}, NO_RETURN_ENTRANCE}, + {{EntranceType::BlueWarp, SPIRIT_TEMPLE_BOSS_ROOM, DESERT_COLOSSUS, 0x0610}, NO_RETURN_ENTRANCE}, + {{EntranceType::BlueWarp, SHADOW_TEMPLE_BOSS_ROOM, GRAVEYARD_WARP_PAD_REGION, 0x0580}, NO_RETURN_ENTRANCE}, }; std::map priorityEntranceTable = { @@ -1011,6 +1020,11 @@ int ShuffleAllEntrances() { FilterAndEraseFromPool(entrancePools[EntranceType::Boss], [](const Entrance* entrance){return entrance->GetParentRegionKey() == DEKU_TREE_BOSS_ENTRYWAY && entrance->GetConnectedRegionKey() == DEKU_TREE_BOSS_ROOM;}); } + if (Settings::DecoupleEntrances) { + for (Entrance* entrance : entrancePools[EntranceType::Boss]) { + entrancePools[EntranceType::BossReverse].push_back(entrance->GetReverse()); + } + } } else { entrancePools[EntranceType::ChildBoss] = GetShuffleableEntrances(EntranceType::ChildBoss); entrancePools[EntranceType::AdultBoss] = GetShuffleableEntrances(EntranceType::AdultBoss); @@ -1019,6 +1033,14 @@ int ShuffleAllEntrances() { FilterAndEraseFromPool(entrancePools[EntranceType::ChildBoss], [](const Entrance* entrance){return entrance->GetParentRegionKey() == DEKU_TREE_BOSS_ENTRYWAY && entrance->GetConnectedRegionKey() == DEKU_TREE_BOSS_ROOM;}); } + if (Settings::DecoupleEntrances) { + for (Entrance* entrance : entrancePools[EntranceType::ChildBoss]) { + entrancePools[EntranceType::ChildBossReverse].push_back(entrance->GetReverse()); + } + for (Entrance* entrance : entrancePools[EntranceType::AdultBoss]) { + entrancePools[EntranceType::AdultBossReverse].push_back(entrance->GetReverse()); + } + } } } @@ -1082,10 +1104,13 @@ int ShuffleAllEntrances() { SetShuffledEntrances(oneWayEntrancePools); //combine entrance pools if mixing pools. Only continue if more than one pool is selected. - int totalMixedPools = (Settings::MixDungeons ? 1 : 0) + (Settings::MixOverworld ? 1 : 0) + (Settings::MixInteriors ? 1 : 0) + (Settings::MixGrottos ? 1 : 0); + int totalMixedPools = (Settings::MixDungeons ? 1 : 0) + (Settings::MixBosses ? 1 : 0) + + (Settings::MixOverworld ? 1 : 0) + (Settings::MixInteriors ? 1 : 0) + + (Settings::MixGrottos ? 1 : 0); if (totalMixedPools < 2) { Settings::MixedEntrancePools.SetSelectedIndex(OFF); Settings::MixDungeons.SetSelectedIndex(OFF); + Settings::MixBosses.SetSelectedIndex(OFF); Settings::MixOverworld.SetSelectedIndex(OFF); Settings::MixInteriors.SetSelectedIndex(OFF); Settings::MixGrottos.SetSelectedIndex(OFF); @@ -1099,6 +1124,12 @@ int ShuffleAllEntrances() { poolsToMix.insert(EntranceType::DungeonReverse); } } + if (Settings::MixBosses) { + poolsToMix.insert(EntranceType::Boss); + if (Settings::DecoupleEntrances) { + poolsToMix.insert(EntranceType::BossReverse); + } + } if (Settings::MixOverworld) { poolsToMix.insert(EntranceType::Overworld); } @@ -1232,6 +1263,87 @@ int ShuffleAllEntrances() { } } + // Determine blue warp targets + if (true /* Settings.BlueWarps.Is(BLUEWARPS_DUNGEON) */) { // RANDOTODO: add bluewarp shuffle + // If a boss room is inside a boss door, make the blue warp go outside the dungeon's entrance + std::map bossExits = { + { EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(DEKU_TREE_ENTRYWAY, KF_OUTSIDE_DEKU_TREE)) }, + { EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_ENTRYWAY, DEATH_MOUNTAIN_TRAIL)) }, + { EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_ENTRYWAY, ZORAS_FOUNTAIN)) }, + { EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_ENTRYWAY, SACRED_FOREST_MEADOW)) }, + { EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_ENTRYWAY, DMC_CENTRAL_LOCAL)) }, + { EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(WATER_TEMPLE_ENTRYWAY, LAKE_HYLIA)) }, + { EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_ENTRYWAY, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY)) }, + { EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY), + GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_ENTRYWAY, GRAVEYARD_WARP_PAD_REGION)) }, + }; + + // If a boss room is inside a dungeon entrance (or inside a dungeon which is inside a dungeon entrance), make the blue warp go to that dungeon's blue warp target + std::map dungeonExits = { + { EntranceNameByRegions(DEKU_TREE_ENTRYWAY, KF_OUTSIDE_DEKU_TREE), + GetEntrance(EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, KF_OUTSIDE_DEKU_TREE)) }, + { EntranceNameByRegions(DODONGOS_CAVERN_ENTRYWAY, DEATH_MOUNTAIN_TRAIL), + GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DEATH_MOUNTAIN_TRAIL)) }, + { EntranceNameByRegions(JABU_JABUS_BELLY_ENTRYWAY, ZORAS_FOUNTAIN), + GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, ZORAS_FOUNTAIN)) }, + { EntranceNameByRegions(FOREST_TEMPLE_ENTRYWAY, SACRED_FOREST_MEADOW), + GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, SACRED_FOREST_MEADOW)) }, + { EntranceNameByRegions(FIRE_TEMPLE_ENTRYWAY, DMC_CENTRAL_LOCAL), + GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, DMC_CENTRAL_LOCAL)) }, + { EntranceNameByRegions(WATER_TEMPLE_ENTRYWAY, LAKE_HYLIA), + GetEntrance(EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, LAKE_HYLIA)) }, + { EntranceNameByRegions(SPIRIT_TEMPLE_ENTRYWAY, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY), + GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, DESERT_COLOSSUS)) }, + { EntranceNameByRegions(SHADOW_TEMPLE_ENTRYWAY, GRAVEYARD_WARP_PAD_REGION), + GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, GRAVEYARD_WARP_PAD_REGION)) }, + }; + + // Pair + std::vector bossRoomExitPairs = { + { GetEntrance(EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, KF_OUTSIDE_DEKU_TREE)), + GetEntrance(EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY)) }, + { GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DEATH_MOUNTAIN_TRAIL)), + GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY)) }, + { GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, ZORAS_FOUNTAIN)), + GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY)) }, + { GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, SACRED_FOREST_MEADOW)), + GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY)) }, + { GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, DMC_CENTRAL_LOCAL)), + GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY)) }, + { GetEntrance(EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, LAKE_HYLIA)), + GetEntrance(EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY)) }, + { GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, DESERT_COLOSSUS)), + GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY)) }, + { GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, GRAVEYARD_WARP_PAD_REGION)), + GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY)) }, + }; + + for (EntrancePair pair : bossRoomExitPairs) { + Entrance* target = pair.second->GetReplacement() != nullptr ? pair.second->GetReplacement() : pair.second; + + if (!Settings::DecoupleEntrances) { + while (bossExits.find(target->GetName()) != bossExits.end()) { + Entrance* next = bossExits.at(target->GetName()); + target = next->GetReplacement() != nullptr ? next->GetReplacement() : next; + } + + if (dungeonExits.find(target->GetName()) != dungeonExits.end()) { + target = dungeonExits.at(target->GetName()); + } + } + + pair.first->Connect(target->GetOriginalConnectedRegionKey()); + pair.first->SetReplacement(target); + } + } + // Validate the world one last time to ensure all special conditions are still valid if (!ValidateWorld(nullptr)) { return ENTRANCE_SHUFFLE_FAILURE; @@ -1259,8 +1371,8 @@ void CreateEntranceOverrides() { auto message = "Setting " + entrance->to_string() + "\n"; SPDLOG_DEBUG(message); + uint8_t type = (uint8_t)entrance->GetType(); int16_t originalIndex = entrance->GetIndex(); - int16_t originalBlueWarp = entrance->GetBlueWarp(); int16_t replacementIndex = entrance->GetReplacement()->GetIndex(); int16_t destinationIndex = -1; @@ -1274,9 +1386,9 @@ void CreateEntranceOverrides() { } entranceOverrides.push_back({ + .type = type, .index = originalIndex, .destination = destinationIndex, - .blueWarp = originalBlueWarp, .override = replacementIndex, .overrideDestination = replacementDestinationIndex, }); diff --git a/soh/soh/Enhancements/randomizer/3drando/entrance.hpp b/soh/soh/Enhancements/randomizer/3drando/entrance.hpp index b6a5cb432..e99b418d8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/entrance.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/entrance.hpp @@ -18,12 +18,16 @@ enum class EntranceType { OwlDrop, Spawn, WarpSong, + BlueWarp, Dungeon, GanonDungeon, DungeonReverse, Boss, + BossReverse, ChildBoss, + ChildBossReverse, AdultBoss, + AdultBossReverse, Interior, InteriorReverse, SpecialInterior, @@ -40,6 +44,7 @@ public: Entrance(uint32_t connectedRegion_, std::vector conditions_met_) : connectedRegion(connectedRegion_) { + originalConnectedRegion = connectedRegion_; conditions_met.resize(2); for (size_t i = 0; i < conditions_met_.size(); i++) { conditions_met[i] = conditions_met_[i]; @@ -134,6 +139,10 @@ public: return connectedRegion; } + uint32_t GetOriginalConnectedRegionKey() const { + return originalConnectedRegion; + } + Area* GetConnectedRegion() const { return AreaTable(connectedRegion); } @@ -198,14 +207,6 @@ public: index = newIndex; } - int16_t GetBlueWarp() const { - return blueWarp; - } - - void SetBlueWarp(int16_t newBlueWarp) { - blueWarp = newBlueWarp; - } - Entrance* GetAssumed() const { return assumed; } @@ -251,7 +252,7 @@ public: AreaTable(ROOT)->AddExit(ROOT, connectedRegion, []{return true;}); Entrance* targetEntrance = AreaTable(ROOT)->GetExit(connectedRegion); targetEntrance->SetReplacement(this); - targetEntrance->SetName(GetParentRegion()->regionName + " -> " + GetConnectedRegion()->regionName); + targetEntrance->SetName(AreaTable(ROOT)->regionName + " -> " + GetConnectedRegion()->regionName); return targetEntrance; } @@ -266,6 +267,7 @@ public: private: uint32_t parentRegion; uint32_t connectedRegion; + uint32_t originalConnectedRegion; std::vector conditions_met; //Entrance Randomizer stuff @@ -275,7 +277,6 @@ private: Entrance* assumed = nullptr; Entrance* replacement = nullptr; int16_t index = 0xFFFF; - int16_t blueWarp = 0; bool shuffled = false; bool primary = false; bool addedToPool = false; @@ -285,6 +286,7 @@ private: int ShuffleAllEntrances(); void CreateEntranceOverrides(); +std::string EntranceNameByRegions(uint32_t parentRegion, uint32_t connectedRegion); extern std::vector> playthroughEntrances; extern bool noRandomEntrances; diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index fa20a083d..ca683143e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -294,7 +294,12 @@ std::vector GetAccessibleLocations(const std::vector& allowe } // Add shuffled entrances to the entrance playthrough - if (mode == SearchMode::GeneratePlaythrough && exit.IsShuffled() && !exit.IsAddedToPool() && !noRandomEntrances) { + // Include bluewarps when unshuffled but dungeon or boss shuffle is on + if (mode == SearchMode::GeneratePlaythrough && + (exit.IsShuffled() || (exit.GetType() == EntranceType::BlueWarp && + (Settings::ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF) || + Settings::ShuffleBossEntrances.IsNot(SHUFFLEBOSSES_OFF)))) && + !exit.IsAddedToPool() && !noRandomEntrances) { entranceSphere.push_back(&exit); exit.AddToPool(); // Don't list a two-way coupled entrance from both directions @@ -913,6 +918,8 @@ void VanillaFill() { ShuffleAllEntrances(); printf("\x1b[7;32HDone"); } + // Populate the playthrough for entrances so they are placed in the spoiler log + GeneratePlaythrough(); //Finish up CreateItemOverrides(); CreateEntranceOverrides(); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp index 0ab29d869..850157ad8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp @@ -26,7 +26,7 @@ void LocationTable_Init() { locationTable[LW_NEAR_SHORTCUTS_GROTTO_CHEST] = ItemLocation::Chest (RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, 0x3E, 0x14, "LW Near Shortcuts Grotto Chest", LW_NEAR_SHORTCUTS_GROTTO_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_SKULL_KID] = ItemLocation::Base (RC_LW_SKULL_KID, 0x5B, "LW Skull Kid", LW_SKULL_KID, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(22), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_TRADE_COJIRO] = ItemLocation::Base (RC_LW_TRADE_COJIRO, 0x5B, "LW Trade Cojiro", LW_TRADE_COJIRO, ODD_MUSHROOM, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_TRADE_ODD_POTION] = ItemLocation::Base (RC_LW_TRADE_ODD_POTION, 0x5B, "LW Trade Odd Potion", LW_TRADE_ODD_POTION, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(49), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); + locationTable[LW_TRADE_ODD_POTION] = ItemLocation::Base (RC_LW_TRADE_ODD_POTION, 0x5B, "LW Trade Odd Potion", LW_TRADE_ODD_POTION, POACHERS_SAW, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(49), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_OCARINA_MEMORY_GAME] = ItemLocation::Base (RC_LW_OCARINA_MEMORY_GAME, 0x5B, "LW Ocarina Memory Game", LW_OCARINA_MEMORY_GAME, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(23), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_TARGET_IN_WOODS] = ItemLocation::Base (RC_LW_TARGET_IN_WOODS, 0x5B, "LW Target in Woods", LW_TARGET_IN_WOODS, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); locationTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, 0x5B, "LW Deku Scrub Near Deku Theater Right",LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); @@ -120,7 +120,7 @@ void LocationTable_Init() { locationTable[KAK_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_KAK_SHOOTING_GALLERY_REWARD, 0x42, "Kak Shooting Gallery Reward", KAK_SHOOTING_GALLERY_REWARD, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_GRANNYS_SHOP] = ItemLocation::Base (RC_KAK_GRANNYS_SHOP, 0x4E, "Kak Granny's Shop", KAK_GRANNYS_SHOP, BLUE_POTION_REFILL, {Category::cMerchant}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, POCKET_EGG, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_ANJU_AS_CHILD] = ItemLocation::Base (RC_KAK_ANJU_AS_CHILD, 0x52, "Kak Anju as Child", KAK_ANJU_AS_CHILD, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(12), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_TRADE_POCKET_CUCCO] = ItemLocation::Base (RC_KAK_TRADE_POCKET_CUCCO, 0x52, "Kak Trade Pocket Cucco", KAK_TRADE_POCKET_CUCCO, COJIRO, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(46), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_IMPAS_HOUSE_FREESTANDING_POH] = ItemLocation::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, 0x37, 0x01, "Kak Impas House Freestanding PoH", KAK_IMPAS_HOUSE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); @@ -492,7 +492,7 @@ void LocationTable_Init() { locationTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, 0x0B, 0x09, "Gerudo Training Grounds MQ Maze Path Third Chest", GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST, TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); locationTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, 0x0B, 0x0A, "Gerudo Training Grounds MQ Maze Path Second Chest", GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); locationTable[GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, 0x0B, 0x0B, "Gerudo Training Grounds MQ Hidden Ceiling Chest", GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, 0x0B, 0x0D, "Gerudo Training Grounds MQ Underwater Silver Rupee Chest",GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST, TREASURE_GAME_GREEN_RUPEE, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); + locationTable[GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, 0x0B, 0x0D, "Gerudo Training Grounds MQ Underwater Silver Rupee Chest",GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); locationTable[GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, 0x0B, 0x02, "Gerudo Training Grounds MQ Heavy Block Chest", GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); //Ganons Castle Shared @@ -918,7 +918,7 @@ void LocationTable_Init() { locationTable[DMC_UPPER_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, "DMC Upper Grotto Gossip Stone"); locationTable[GANONDORF_HINT] = ItemLocation::OtherHint(RC_GANONDORF_HINT, "Ganondorf Hint"); - locationTable[TRIFORCE_COMPLETED] = ItemLocation::Reward (RC_TRIFORCE_COMPLETED, 0xFF, "Completed Triforce", NONE, TRIFORCE_COMPLETED, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP); + locationTable[TRIFORCE_COMPLETED] = ItemLocation::Reward (RC_TRIFORCE_COMPLETED, 0xFF, "Completed Triforce", NONE, NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP); for (int i = NONE; i != KEY_ENUM_MAX; i++) locationLookupTable.insert(std::make_pair(locationTable[i].GetRandomizerCheck(), static_cast(i))); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 6be67ea84..684dd16e1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -503,3 +503,16 @@ std::vector GetShuffleableEntrances(EntranceType type, bool onlyPrima } return entrancesToShuffle; } + +// Get the specific entrance by name +Entrance* GetEntrance(const std::string name) { + for (uint32_t area : Areas::GetAllAreas()) { + for (auto& exit : AreaTable(area)->exits) { + if (exit.GetName() == name) { + return &exit; + } + } + } + + return nullptr; +} diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp index 60529a2f6..672a97f5c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -242,6 +242,7 @@ namespace Areas { void AreaTable_Init(); Area* AreaTable(const uint32_t areaKey); std::vector GetShuffleableEntrances(EntranceType type, bool onlyPrimary = true); +Entrance* GetEntrance(const std::string name); // Overworld void AreaTable_Init_LostWoods(); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp index 2224df4ca..c1231b29e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp @@ -267,5 +267,6 @@ void AreaTable_Init_DekuTree() { { // Exits Entrance(DEKU_TREE_BOSS_ENTRYWAY, { [] { return true; } }), + Entrance(KF_OUTSIDE_DEKU_TREE, { [] { return DekuTreeClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp index 9f8effbcc..dc88b1b2c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp @@ -309,5 +309,6 @@ void AreaTable_Init_DodongosCavern() { { // Exits Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY, { [] { return true; } }), + Entrance(DEATH_MOUNTAIN_TRAIL, { [] { return DodongosCavernClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp index ff2fb885c..107028872 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_fire_temple.cpp @@ -420,5 +420,6 @@ void AreaTable_Init_FireTemple() { { // Exits Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(DMC_CENTRAL_LOCAL, { [] { return FireTempleClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp index 5e64aee6c..16798906e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_forest_temple.cpp @@ -433,5 +433,6 @@ void AreaTable_Init_ForestTemple() { { // Exits Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(SACRED_FOREST_MEADOW, { [] { return ForestTempleClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp index 108b69ccc..c8e38bb61 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp @@ -179,17 +179,17 @@ void AreaTable_Init_JabuJabusBelly() { //Locations LocationAccess(JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, {[]{return true;}}), LocationAccess(JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, {[]{return (IsAdult && (CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT))) || ChildCanAccess(JABU_JABUS_BELLY_MQ_BOSS_AREA);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_COMPASS_CHEST, {[]{return true;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, {[]{return true;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, {[]{return true;}}), + LocationAccess(JABU_JABUS_BELLY_MQ_COMPASS_CHEST, {[]{return (IsChild || CanDive || CanUse(IRON_BOOTS) || LogicJabuAlcoveJumpDive) && (CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(HOOKSHOT) || HasBombchus || (LogicJabuMQRangJump && CanUse(BOOMERANG)));}}), + LocationAccess(JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, {[]{return CanUse(SLINGSHOT);}}), + LocationAccess(JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, {[]{return CanUse(SLINGSHOT);}}), LocationAccess(JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, {[]{return true;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, {[]{return true;}}), + LocationAccess(JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(STICKS) || Bombs;}}), LocationAccess(JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, {[]{return CanPlay(SongOfTime) || (LogicJabuMQSoTGS && IsChild && CanUse(BOOMERANG));}}), //Trick: CanPlay(SongOfTime) || (LogicJabuMQSoTGS && IsChild && CanUse(BOOMERANG)) }, { //Exits Entrance(JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_MQ_DEPTHS, {[]{return HasExplosives && IsChild && CanUse(BOOMERANG);}}), + Entrance(JABU_JABUS_BELLY_MQ_DEPTHS, {[]{return HasExplosives && CanUse(SLINGSHOT) && CanUse(BOOMERANG);}}), }); areaTable[JABU_JABUS_BELLY_MQ_DEPTHS] = Area("Jabu Jabus Belly MQ Depths", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, { @@ -209,8 +209,8 @@ void AreaTable_Init_JabuJabusBelly() { }, { //Locations LocationAccess(JABU_JABUS_BELLY_MQ_COW, {[]{return CanPlay(EponasSong);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, {[]{return true;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, {[]{return true;}}), + LocationAccess(JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, {[]{return CanUse(SLINGSHOT);}}), + LocationAccess(JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, {[]{return CanUse(BOOMERANG) || (LogicJabuNearBossRanged && CanUse(HOOKSHOT));}}), }, { //Exits Entrance(JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), @@ -245,5 +245,6 @@ void AreaTable_Init_JabuJabusBelly() { { // Exits Entrance(JABU_JABUS_BELLY_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(ZORAS_FOUNTAIN, { [] { return JabuJabusBellyClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp index a3dda7521..61778d563 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp @@ -209,5 +209,6 @@ void AreaTable_Init_ShadowTemple() { { // Exits Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(GRAVEYARD_WARP_PAD_REGION, { [] { return ShadowTempleClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp index 2aa0c0516..f676c3c91 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_spirit_temple.cpp @@ -271,5 +271,6 @@ void AreaTable_Init_SpiritTemple() { { // Exits Entrance(SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(DESERT_COLOSSUS, { [] { return SpiritTempleClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp index 559b6c20c..f1c86abb0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_water_temple.cpp @@ -331,5 +331,6 @@ void AreaTable_Init_WaterTemple() { { // Exits Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(LAKE_HYLIA, { [] { return WaterTempleClear; } }), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 5da2b618c..9f6cc2796 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -22,6 +22,14 @@ std::vector presetEntries; Option* currentSetting; } // namespace +static void RestoreOverrides() { + if (Settings::Logic.Is(LOGIC_VANILLA)) { + for (auto overridePair : Settings::vanillaLogicOverrides) { + overridePair.first->RestoreDelayedOption(); + } + } +} + std::string GenerateRandomizer(std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks, std::string seedString) { @@ -52,20 +60,17 @@ std::string GenerateRandomizer(std::unordered_map printf("\n\nFailed to generate after 5 tries.\nPress B to go back to the menu.\nA different seed might be " "successful."); SPDLOG_DEBUG("\nRANDOMIZATION FAILED COMPLETELY. PLZ FIX\n"); + RestoreOverrides(); return ""; } else { printf("\n\nError %d with fill.\nPress Select to exit or B to go back to the menu.\n", ret); + RestoreOverrides(); return ""; } } - // Restore settings that were set to a specific value for vanilla logic - if (Settings::Logic.Is(LOGIC_VANILLA)) { - for (Option* setting : Settings::vanillaLogicDefaults) { - setting->RestoreDelayedOption(); - } - Settings::Keysanity.RestoreDelayedOption(); - } + RestoreOverrides(); + std::ostringstream fileNameStream; for (int i = 0; i < Settings::hashIconIndexes.size(); i++) { if (i) { diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index 62042246c..e1a5656ea 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -10,6 +10,7 @@ #include "spoiler_log.hpp" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "variables.h" +#include "soh/OTRGlobals.h" namespace Playthrough { @@ -41,7 +42,7 @@ int Playthrough_Init(uint32_t seed, std::unordered_map #include #include +#include "soh/OTRGlobals.h" void RandoMain::GenerateRando(std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks, std::string seedString) { @@ -16,14 +17,14 @@ void RandoMain::GenerateRando(std::unordered_map cvarS LocationTable_Init(); // std::string settingsFileName = "./randomizer/latest_settings.json"; - // CVarSetString("gLoadedPreset", settingsFileName.c_str()); + // CVarSetString(CVAR_RANDOMIZER_SETTING("LoadedPreset"), settingsFileName.c_str()); - std::string fileName = LUS::Context::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings, excludedLocations, enabledTricks, seedString).c_str()); - CVarSetString("gSpoilerLog", fileName.c_str()); + std::string fileName = Ship::Context::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings, excludedLocations, enabledTricks, seedString).c_str()); + CVarSetString(CVAR_GENERAL("SpoilerLog"), fileName.c_str()); CVarSave(); CVarLoad(); - CVarSetInteger("gNewSeedGenerated", 1); + CVarSetInteger(CVAR_GENERAL("NewSeedGenerated"), 1); } std::array* RandoMain::GetFullItemTable() { diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 08d09cfa8..5dcd5a792 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -94,6 +94,7 @@ namespace Settings { Option ShuffleOverworldSpawns = Option::Bool("Overworld Spawns", {"Off", "On"}); Option MixedEntrancePools = Option::Bool("Mixed Entrance Pools", {"Off", "On"}); Option MixDungeons = Option::Bool("Mix Dungeons", {"Off", "On"}); + Option MixBosses = Option::Bool("Mix Bosses", {"Off", "On"}); Option MixOverworld = Option::Bool("Mix Overworld", {"Off", "On"}); Option MixInteriors = Option::Bool("Mix Interiors", {"Off", "On"}); Option MixGrottos = Option::Bool("Mix Grottos", {"Off", "On"}); @@ -135,6 +136,7 @@ namespace Settings { &ShuffleOverworldSpawns, &MixedEntrancePools, &MixDungeons, + &MixBosses, &MixOverworld, &MixInteriors, &MixGrottos, @@ -1298,6 +1300,7 @@ namespace Settings { ctx.shuffleOverworldSpawns = (ShuffleOverworldSpawns) ? 1 : 0; ctx.mixedEntrancePools = (MixedEntrancePools) ? 1 : 0; ctx.mixDungeons = (MixDungeons) ? 1 : 0; + ctx.mixBosses = (MixBosses) ? 1 : 0; ctx.mixOverworld = (MixOverworld) ? 1 : 0; ctx.mixInteriors = (MixInteriors) ? 1 : 0; ctx.mixGrottos = (MixGrottos) ? 1 : 0; @@ -1891,6 +1894,13 @@ namespace Settings { MixDungeons.SetSelectedIndex(OFF); } + if (ShuffleBossEntrances.Is(SHUFFLEBOSSES_FULL)) { + MixBosses.Unhide(); + } else { + MixBosses.Hide(); + MixBosses.SetSelectedIndex(OFF); + } + if (ShuffleOverworldEntrances) { MixOverworld.Unhide(); } else { @@ -1914,6 +1924,8 @@ namespace Settings { } else { MixDungeons.Hide(); MixDungeons.SetSelectedIndex(OFF); + MixBosses.Hide(); + MixBosses.SetSelectedIndex(OFF); MixOverworld.Hide(); MixOverworld.SetSelectedIndex(OFF); MixInteriors.Hide(); @@ -2060,21 +2072,65 @@ namespace Settings { } //Options that should be saved, set to default, then restored after finishing when vanilla logic is enabled - std::vector