mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-29 04:42:18 -05:00
Merge remote-tracking branch 'upstream/develop' into NoMS
This commit is contained in:
commit
e5b4e2eb3c
2
.github/workflows/apt-deps.txt
vendored
2
.github/workflows/apt-deps.txt
vendored
@ -1 +1 @@
|
||||
libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev ninja-build
|
||||
libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev ninja-build
|
||||
|
131
.github/workflows/generate-builds.yml
vendored
131
.github/workflows/generate-builds.yml
vendored
@ -13,22 +13,37 @@ 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/
|
||||
@ -37,7 +52,7 @@ jobs:
|
||||
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
|
||||
@ -50,9 +65,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,7 +103,7 @@ jobs:
|
||||
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
|
||||
@ -99,7 +117,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: |
|
||||
@ -128,17 +146,32 @@ 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/
|
||||
@ -146,15 +179,17 @@ jobs:
|
||||
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
|
||||
@ -170,7 +205,7 @@ 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: |
|
||||
@ -180,7 +215,7 @@ jobs:
|
||||
needs: generate-soh-otr
|
||||
runs-on: ${{ (vars.LINUX_RUNNER && fromJSON(vars.LINUX_RUNNER)) || 'ubuntu-latest' }}
|
||||
container:
|
||||
image: devkitpro/devkita64:latest
|
||||
image: devkitpro/devkita64:20240120
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@ -193,9 +228,12 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ runner.os }}-switch-ccache
|
||||
key: ${{ runner.os }}-switch-ccache-${{ github.ref }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-switch-ccache-${{ github.ref }}
|
||||
${{ 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
|
||||
@ -204,11 +242,11 @@ jobs:
|
||||
mv build-switch/soh/*.nro soh.nro
|
||||
mv README.md readme.txt
|
||||
- name: Download soh.otr
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: soh.otr
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: soh-switch
|
||||
path: |
|
||||
@ -230,9 +268,12 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ runner.os }}-wiiu-ccache
|
||||
key: ${{ runner.os }}-wiiu-ccache-${{ github.ref }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-wiiu-ccache-${{ github.ref }}
|
||||
${{ 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
|
||||
@ -245,11 +286,11 @@ jobs:
|
||||
DEVKITPRO: /opt/devkitpro
|
||||
DEVKITPPC: /opt/devkitpro/devkitPPC
|
||||
- name: Download soh.otr
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: soh.otr
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: soh-wiiu
|
||||
path: |
|
||||
@ -270,15 +311,25 @@ jobs:
|
||||
with:
|
||||
submodules: true
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ runner.os }}-ccache
|
||||
- name: vcpkg
|
||||
uses: johnwason/vcpkg-action@v5
|
||||
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:
|
||||
pkgs: zlib bzip2 libpng sdl2 sdl2-net glew glfw3
|
||||
token: ${{ github.token }}
|
||||
triplet: 'x64-windows-static'
|
||||
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
|
||||
@ -286,7 +337,7 @@ jobs:
|
||||
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 -DBUILD_REMOTE_CONTROL=1
|
||||
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
|
||||
@ -299,12 +350,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
|
||||
|
@ -8,5 +8,9 @@ if(MSVC)
|
||||
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
||||
set_config_specific_property("DEFAULT_CXX_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()
|
@ -14,13 +14,17 @@ add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
|
||||
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
|
||||
|
||||
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 libpng sdl2 sdl2-net glew glfw3)
|
||||
|
||||
if (CMAKE_C_COMPILER_LAUNCHER MATCHES "ccache|sccache")
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 04b85b95fab07a394b62dcd28a502a3040f08e0c
|
||||
Subproject commit 44adc47b4da529e72d968b14cab94aefd8260f22
|
@ -1 +1 @@
|
||||
Subproject commit 15d57d806e39d7f19783e26acc1a062d402169c7
|
||||
Subproject commit 0833afad66e96d2ec4bbc410186d7247dc243ee2
|
@ -8,5 +8,9 @@ if(MSVC)
|
||||
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
||||
set_config_specific_property("DEFAULT_CXX_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()
|
@ -328,7 +328,7 @@ endif()
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
Boost
|
||||
URL https://sourceforge.net/projects/boost/files/boost/1.81.0/boost_1_81_0.tar.gz
|
||||
URL https://archives.boost.io/release/1.81.0/source/boost_1_81_0.tar.gz
|
||||
URL_HASH SHA256=205666dea9f6a7cfed87c7a6dfbeb52a2c1b9de55712c9c1a87735d7181452b6
|
||||
SOURCE_SUBDIR "null" # Set to a nonexistent directory so boost is not built (we don't need to build it)
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP false # supress timestamp warning, not needed since the url wont change
|
||||
|
2
soh/assets/.gitignore
vendored
2
soh/assets/.gitignore
vendored
@ -4,4 +4,4 @@
|
||||
*.cfg
|
||||
*.vtx.inc
|
||||
*.dlist.inc
|
||||
*.txt
|
||||
!*.png
|
||||
|
15
soh/assets/sources/triforce-hunt/paths.txt
Normal file
15
soh/assets/sources/triforce-hunt/paths.txt
Normal file
@ -0,0 +1,15 @@
|
||||
Complete triforce:
|
||||
DL name: gTriforcePieceCompletedDL
|
||||
Export Path: objects/object_triforce_completed
|
||||
|
||||
Shard 0:
|
||||
DL name: gTriforcePiece0DL
|
||||
Export Path: objects/object_triforce_piece_0
|
||||
|
||||
Shard 1:
|
||||
DL name: gTriforcePiece1DL
|
||||
Export Path: objects/object_triforce_piece_1
|
||||
|
||||
Shard 2:
|
||||
DL name: gTriforcePiece2DL
|
||||
Export Path: objects/object_triforce_piece_2
|
BIN
soh/assets/sources/triforce-hunt/textures/noise_tex.png
Normal file
BIN
soh/assets/sources/triforce-hunt/textures/noise_tex.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 660 B |
BIN
soh/assets/sources/triforce-hunt/triforce_complete.blend
Normal file
BIN
soh/assets/sources/triforce-hunt/triforce_complete.blend
Normal file
Binary file not shown.
BIN
soh/assets/sources/triforce-hunt/triforce_shard_0.blend
Normal file
BIN
soh/assets/sources/triforce-hunt/triforce_shard_0.blend
Normal file
Binary file not shown.
BIN
soh/assets/sources/triforce-hunt/triforce_shard_1.blend
Normal file
BIN
soh/assets/sources/triforce-hunt/triforce_shard_1.blend
Normal file
Binary file not shown.
BIN
soh/assets/sources/triforce-hunt/triforce_shard_2.blend
Normal file
BIN
soh/assets/sources/triforce-hunt/triforce_shard_2.blend
Normal file
Binary file not shown.
@ -744,7 +744,6 @@ typedef struct {
|
||||
/* 0x0134 */ char** doActionSegment;
|
||||
/* 0x0138 */ u8* iconItemSegment;
|
||||
/* 0x013C */ char** mapSegment;
|
||||
char** mapSegmentName;
|
||||
/* 0x0140 */ u8 mapPalette[32];
|
||||
/* 0x0160 */ DmaRequest dmaRequest_160;
|
||||
/* 0x0180 */ DmaRequest dmaRequest_180;
|
||||
@ -815,6 +814,10 @@ typedef struct {
|
||||
/* 0x026C */ u8 dinsNayrus; // "m_magic"; din's fire and nayru's love
|
||||
/* 0x026D */ u8 all; // "another"; enables all item restrictions
|
||||
} restrictions;
|
||||
// #region SOH [General]
|
||||
/* */ char* mapSegmentName[2]; // Tracks the map segment texture by OTR sig name
|
||||
/* */ u8 mapPalettesPulse[40][32]; // Used to have unique pointers per map pulse color for the shader backend. 40 for map pulse timer x2
|
||||
// #endregion
|
||||
} InterfaceContext; // size = 0x270
|
||||
|
||||
typedef struct {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <Utils/StringHelper.h>
|
||||
#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;
|
||||
@ -79,6 +80,11 @@ void UpdateCurrentBGM(u16 seqKey, SeqType seqType) {
|
||||
void RandomizeGroup(SeqType type) {
|
||||
std::vector<u16> values;
|
||||
|
||||
// An empty IncludedSequences set means that the AudioEditor window has never been drawn
|
||||
if (AudioCollection::Instance->GetIncludedSequences().empty()) {
|
||||
AudioCollection::Instance->InitializeShufflePool();
|
||||
}
|
||||
|
||||
// use a while loop to add duplicates if we don't have enough included sequences
|
||||
while (values.size() < AuthenticCountBySequenceType(type)) {
|
||||
for (const auto& seqData : AudioCollection::Instance->GetIncludedSequences()) {
|
||||
@ -123,6 +129,34 @@ void ResetGroup(const std::map<u16, SequenceInfo>& map, SeqType type) {
|
||||
}
|
||||
}
|
||||
|
||||
void LockGroup(const std::map<u16, SequenceInfo>& map, SeqType type) {
|
||||
for (const auto& [defaultValue, seqData] : map) {
|
||||
if (seqData.category == type) {
|
||||
// Only save authentic sequence CVars
|
||||
if (seqData.category == SEQ_FANFARE && defaultValue >= MAX_AUTHENTIC_SEQID) {
|
||||
continue;
|
||||
}
|
||||
const std::string cvarKey = AudioCollection::Instance->GetCvarKey(seqData.sfxKey);
|
||||
const std::string cvarLockKey = AudioCollection::Instance->GetCvarLockKey(seqData.sfxKey);
|
||||
CVarSetInteger(cvarLockKey.c_str(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UnlockGroup(const std::map<u16, SequenceInfo>& map, SeqType type) {
|
||||
for (const auto& [defaultValue, seqData] : map) {
|
||||
if (seqData.category == type) {
|
||||
// Only save authentic sequence CVars
|
||||
if (seqData.category == SEQ_FANFARE && defaultValue >= MAX_AUTHENTIC_SEQID) {
|
||||
continue;
|
||||
}
|
||||
const std::string cvarKey = AudioCollection::Instance->GetCvarKey(seqData.sfxKey);
|
||||
const std::string cvarLockKey = AudioCollection::Instance->GetCvarLockKey(seqData.sfxKey);
|
||||
CVarSetInteger(cvarLockKey.c_str(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequenceType) {
|
||||
const std::string cvarKey = AudioCollection::Instance->GetCvarKey(sfxKey);
|
||||
const std::string hiddenKey = "##" + cvarKey;
|
||||
@ -163,6 +197,8 @@ 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);
|
||||
@ -184,6 +220,28 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
|
||||
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);
|
||||
LUS::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);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
|
||||
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
|
||||
ReplayCurrentBGM();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::BeginTable(tabId.c_str(), 3, ImGuiTableFlags_SizingFixedFit);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
|
||||
@ -350,6 +408,19 @@ void DrawTypeChip(SeqType type) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
|
||||
void AudioEditorRegisterOnSceneInitHook() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
|
||||
if (CVarGetInteger("gAudioEditor.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);
|
||||
@ -431,6 +524,10 @@ void AudioEditor::DrawElement() {
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
UIWidgets::EnhancementCheckbox("Randomize All Music and Sound Effects on New Scene", "gAudioEditor.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();
|
||||
@ -625,3 +722,19 @@ void AudioEditor_ResetAll() {
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
ReplayCurrentBGM();
|
||||
}
|
||||
|
||||
void AudioEditor_LockAll() {
|
||||
for (auto type : allTypes) {
|
||||
LockGroup(AudioCollection::Instance->GetAllSequences(), type);
|
||||
}
|
||||
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
|
||||
void AudioEditor_UnlockAll() {
|
||||
for (auto type : allTypes) {
|
||||
UnlockGroup(AudioCollection::Instance->GetAllSequences(), type);
|
||||
}
|
||||
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
|
@ -14,13 +14,15 @@ class AudioEditor : public LUS::GuiWindow {
|
||||
using LUS::GuiWindow::GuiWindow;
|
||||
|
||||
void DrawElement() override;
|
||||
void InitElement() override {};
|
||||
void InitElement() override;
|
||||
void UpdateElement() override {};
|
||||
~AudioEditor() {};
|
||||
};
|
||||
|
||||
void AudioEditor_RandomizeAll();
|
||||
void AudioEditor_ResetAll();
|
||||
void AudioEditor_LockAll();
|
||||
void AudioEditor_UnlockAll();
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -1,355 +0,0 @@
|
||||
#include "GameControlEditor.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <variables.h>
|
||||
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#endif
|
||||
#include <ImGui/imgui.h>
|
||||
#include <ImGui/imgui_internal.h>
|
||||
#include <libultraship/bridge.h>
|
||||
#include <libultraship/libultra/controller.h>
|
||||
#include <Utils/StringHelper.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
#include "../../UIWidgets.hpp"
|
||||
|
||||
namespace GameControlEditor {
|
||||
const ImGuiTableFlags PANEL_TABLE_FLAGS =
|
||||
ImGuiTableFlags_BordersH |
|
||||
ImGuiTableFlags_BordersV;
|
||||
const ImGuiTableColumnFlags PANEL_TABLE_COLUMN_FLAGS =
|
||||
ImGuiTableColumnFlags_IndentEnable |
|
||||
ImGuiTableColumnFlags_NoSort;
|
||||
|
||||
namespace TableHelper {
|
||||
void InitHeader(bool has_header = true) {
|
||||
if (has_header) {
|
||||
ImGui::TableHeadersRow();
|
||||
}
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding(); //This is to adjust Vertical pos of item in a cell to be normlized.
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
}
|
||||
|
||||
void NextCol() {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
}
|
||||
|
||||
void NextLine() {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawHelpIcon(const std::string& helptext) {
|
||||
// place the ? button to the most of the right side of the cell it is using.
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 22);
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 15);
|
||||
ImGui::SmallButton("?");
|
||||
UIWidgets::Tooltip(helptext.c_str());
|
||||
}
|
||||
|
||||
typedef uint32_t N64ButtonMask;
|
||||
|
||||
// Used together for an incomplete linked hash map implementation in order to
|
||||
// map button masks to their names and original mapping on N64
|
||||
static std::list<std::pair<N64ButtonMask, const char*>> buttons;
|
||||
static std::unordered_map<N64ButtonMask, decltype(buttons)::iterator> buttonNames;
|
||||
|
||||
void addButtonName(N64ButtonMask mask, const char* name) {
|
||||
buttons.push_back(std::make_pair(mask, name));
|
||||
buttonNames[mask] = std::prev(buttons.end());
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char* label;
|
||||
const char* cVarName;
|
||||
N64ButtonMask defaultBtn;
|
||||
} CustomButtonMap;
|
||||
|
||||
// Ocarina button maps
|
||||
static CustomButtonMap ocarinaD5 = {"D5", "gOcarinaD5BtnMap", BTN_CUP};
|
||||
static CustomButtonMap ocarinaB4 = {"B4", "gOcarinaB4BtnMap", BTN_CLEFT};
|
||||
static CustomButtonMap ocarinaA4 = {"A4", "gOcarinaA4BtnMap", BTN_CRIGHT};
|
||||
static CustomButtonMap ocarinaF4 = {"F4", "gOcarinaF4BtnMap", BTN_CDOWN};
|
||||
static CustomButtonMap ocarinaD4 = {"D4", "gOcarinaD4BtnMap", BTN_A};
|
||||
static CustomButtonMap ocarinaSongDisable = {"Disable songs", "gOcarinaDisableBtnMap", BTN_L};
|
||||
static CustomButtonMap ocarinaSharp = {"Pitch up", "gOcarinaSharpBtnMap", BTN_R};
|
||||
static CustomButtonMap ocarinaFlat = {"Pitch down", "gOcarinaFlatBtnMap", BTN_Z};
|
||||
|
||||
void GameControlEditorWindow::InitElement() {
|
||||
addButtonName(BTN_A, "A");
|
||||
addButtonName(BTN_B, "B");
|
||||
addButtonName(BTN_CUP, "C Up");
|
||||
addButtonName(BTN_CDOWN, "C Down");
|
||||
addButtonName(BTN_CLEFT, "C Left");
|
||||
addButtonName(BTN_CRIGHT, "C Right");
|
||||
addButtonName(BTN_L, "L");
|
||||
addButtonName(BTN_Z, "Z");
|
||||
addButtonName(BTN_R, "R");
|
||||
addButtonName(BTN_START, "Start");
|
||||
addButtonName(BTN_DUP, "D-pad up");
|
||||
addButtonName(BTN_DDOWN, "D-pad down");
|
||||
addButtonName(BTN_DLEFT, "D-pad left");
|
||||
addButtonName(BTN_DRIGHT, "D-pad right");
|
||||
addButtonName(0, "None");
|
||||
}
|
||||
|
||||
// Draw a button mapping setting consisting of a padded label and button dropdown.
|
||||
// excludedButtons indicates which buttons are unavailable to choose from.
|
||||
void DrawMapping(CustomButtonMap& mapping, float labelWidth, N64ButtonMask excludedButtons) {
|
||||
N64ButtonMask currentButton = CVarGetInteger(mapping.cVarName, mapping.defaultBtn);
|
||||
|
||||
const char* preview;
|
||||
if (buttonNames.contains(currentButton)) {
|
||||
preview = buttonNames[currentButton]->second;
|
||||
} else {
|
||||
preview = "Unknown";
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
||||
ImVec2 textSize = ImGui::CalcTextSize(mapping.label);
|
||||
ImGui::SetCursorPosY(cursorPos.y + textSize.y / 4);
|
||||
ImGui::SetCursorPosX(cursorPos.x + abs(textSize.x - labelWidth));
|
||||
ImGui::Text("%s", mapping.label);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosY(cursorPos.y);
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
if (ImGui::BeginCombo(StringHelper::Sprintf("##%s", mapping.cVarName).c_str(), preview)) {
|
||||
for (auto i = buttons.begin(); i != buttons.end(); i++) {
|
||||
if ((i->first & excludedButtons) != 0) {
|
||||
continue;
|
||||
}
|
||||
if (ImGui::Selectable(i->second, i->first == currentButton)) {
|
||||
CVarSetInteger(mapping.cVarName, i->first);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
}
|
||||
|
||||
void DrawOcarinaControlPanel(GameControlEditorWindow* window) {
|
||||
if (!ImGui::CollapsingHeader("Ocarina Controls")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ImGui::BeginTable("tableCustomOcarinaControls", 1, PANEL_TABLE_FLAGS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TableSetupColumn("Custom Ocarina Controls", PANEL_TABLE_COLUMN_FLAGS | ImGuiTableColumnFlags_WidthStretch);
|
||||
TableHelper::InitHeader(false);
|
||||
|
||||
ImVec2 cursor = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
||||
UIWidgets::EnhancementCheckbox("Customize Ocarina Controls", "gCustomOcarinaControls");
|
||||
|
||||
if (CVarGetInteger("gCustomOcarinaControls", 0) == 1) {
|
||||
if (ImGui::BeginTable("tableCustomMainOcarinaControls", 2, ImGuiTableFlags_SizingStretchProp)) {
|
||||
float labelWidth;
|
||||
N64ButtonMask disableMask = BTN_B;
|
||||
if (CVarGetInteger("gDpadOcarina", 0)) {
|
||||
disableMask |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
||||
}
|
||||
|
||||
ImGui::TableSetupColumn("Notes##CustomOcarinaNotes", PANEL_TABLE_COLUMN_FLAGS);
|
||||
ImGui::TableSetupColumn("Modifiers##CustomOcaranaModifiers", PANEL_TABLE_COLUMN_FLAGS);
|
||||
TableHelper::InitHeader(false);
|
||||
|
||||
window->BeginGroupPanelPublic("Notes", ImGui::GetContentRegionAvail());
|
||||
labelWidth = ImGui::CalcTextSize("D5").x + 10;
|
||||
DrawMapping(ocarinaD5, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaB4, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaA4, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaF4, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaD4, labelWidth, disableMask);
|
||||
ImGui::Dummy(ImVec2(0, 5));
|
||||
float cursorY = ImGui::GetCursorPosY();
|
||||
window->EndGroupPanelPublic(0);
|
||||
|
||||
TableHelper::NextCol();
|
||||
|
||||
window->BeginGroupPanelPublic("Modifiers", ImGui::GetContentRegionAvail());
|
||||
labelWidth = ImGui::CalcTextSize(ocarinaSongDisable.label).x + 10;
|
||||
DrawMapping(ocarinaSongDisable, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaSharp, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaFlat, labelWidth, disableMask);
|
||||
window->EndGroupPanelPublic(cursorY - ImGui::GetCursorPosY() + 2);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
} else {
|
||||
UIWidgets::Spacer(0);
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
||||
ImGui::TextWrapped("To modify the main ocarina controls, select the \"Customize Ocarina Controls\" checkbox.");
|
||||
UIWidgets::Spacer(0);
|
||||
}
|
||||
|
||||
window->BeginGroupPanelPublic("Alternate controls", ImGui::GetContentRegionAvail());
|
||||
if (ImGui::BeginTable("tableOcarinaAlternateControls", 2, ImGuiTableFlags_SizingFixedSame)) {
|
||||
ImGui::TableSetupColumn("D-pad", PANEL_TABLE_COLUMN_FLAGS);
|
||||
ImGui::TableSetupColumn("Right stick", PANEL_TABLE_COLUMN_FLAGS);
|
||||
TableHelper::InitHeader(false);
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
||||
UIWidgets::EnhancementCheckbox("Play with D-pad", "gDpadOcarina");
|
||||
TableHelper::NextCol();
|
||||
UIWidgets::EnhancementCheckbox("Play with camera stick", "gRStickOcarina");
|
||||
UIWidgets::Spacer(0);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
window->EndGroupPanelPublic(0);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
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");
|
||||
if (CVarGetInteger("gRightStickAiming", 0)) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Allow moving while in first person mode", "gMoveWhileFirstPerson");
|
||||
DrawHelpIcon("Changes the left stick to move the player while in first person mode");
|
||||
}
|
||||
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("Invert Z-Weapon Aiming Y Axis", "gInvertZAimingYAxis", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
||||
DrawHelpIcon("Inverts the Camera Y Axis in:\n-Z-Weapon Aiming");
|
||||
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("gFirstPersonCameraSensitivityX");
|
||||
CVarClear("gFirstPersonCameraSensitivityY");
|
||||
}
|
||||
}
|
||||
if (CVarGetInteger("gEnableFirstPersonSensitivity", 0)) {
|
||||
UIWidgets::EnhancementSliderFloat("Aiming/First-Person Horizontal Sensitivity: %.0f %%", "##FirstPersonSensitivity Horizontal",
|
||||
"gFirstPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true);
|
||||
UIWidgets::EnhancementSliderFloat("Aiming/First-Person Vertical Sensitivity: %.0f %%", "##FirstPersonSensitivity Vertical",
|
||||
"gFirstPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true);
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
window->EndGroupPanelPublic(0);
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
window->BeginGroupPanelPublic("Third-Person Camera", ImGui::GetContentRegionAvail());
|
||||
|
||||
UIWidgets::PaddedEnhancementCheckbox("Free Camera", "gFreeCamera");
|
||||
DrawHelpIcon("Enables free 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", "gInvertXAxis");
|
||||
DrawHelpIcon("Inverts the Camera X Axis in:\n-Free camera");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Invert Camera Y Axis", "gInvertYAxis", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
||||
DrawHelpIcon("Inverts the Camera Y Axis in:\n-Free camera");
|
||||
UIWidgets::Spacer(0);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Third-Person Horizontal Sensitivity: %.0f %%", "##ThirdPersonSensitivity Horizontal",
|
||||
"gThirdPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Third-Person Vertical Sensitivity: %.0f %%", "##ThirdPersonSensitivity Vertical",
|
||||
"gThirdPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Camera Distance: %d", "##CamDist",
|
||||
"gFreeCameraDistMax", 100, 900, "", 185, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Camera Transition Speed: %d", "##CamTranSpeed",
|
||||
"gFreeCameraTransitionSpeed", 0, 900, "", 25, true, false, true);
|
||||
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: %.0f %%", "##WalkMod1", "gWalkModifierOne", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Modifier 2: %.0f %%", "##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 GameControlEditorWindow::DrawElement() {
|
||||
ImGui::SetNextWindowSize(ImVec2(465, 430), ImGuiCond_FirstUseEver);
|
||||
if (ImGui::Begin("Game Controls Configuration", &mIsVisible)) {
|
||||
DrawOcarinaControlPanel(this);
|
||||
DrawCameraControlPanel(this);
|
||||
DrawDpadControlPanel(this);
|
||||
DrawMiscControlPanel(this);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void GameControlEditorWindow::BeginGroupPanelPublic(const char* name, const ImVec2& size) {
|
||||
BeginGroupPanel(name, size);
|
||||
}
|
||||
|
||||
void GameControlEditorWindow::EndGroupPanelPublic(float minHeight) {
|
||||
EndGroupPanel(minHeight);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
namespace GameControlEditor {
|
||||
class GameControlEditorWindow : public LUS::GuiWindow {
|
||||
public:
|
||||
using LUS::GuiWindow::GuiWindow;
|
||||
|
||||
void BeginGroupPanelPublic(const char* name, const ImVec2& size);
|
||||
void EndGroupPanelPublic(float minHeight);
|
||||
|
||||
void InitElement() override;
|
||||
void DrawElement() override;
|
||||
void UpdateElement() override {};
|
||||
};
|
||||
|
||||
static int CurrentPort = 0;
|
||||
static int BtnReading = -1;
|
||||
|
||||
} // namespace GameControlEditor
|
@ -22,6 +22,22 @@ void SohInputEditorWindow::InitElement() {
|
||||
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
|
||||
@ -1017,14 +1033,6 @@ void SohInputEditorWindow::DrawAddLEDMappingButton(uint8_t port) {
|
||||
}
|
||||
}
|
||||
|
||||
void SohInputEditorWindow::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() - SCALE_IMGUI_SIZE(22));
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - SCALE_IMGUI_SIZE(15));
|
||||
ImGui::SmallButton("?");
|
||||
UIWidgets::Tooltip(helptext.c_str());
|
||||
}
|
||||
|
||||
void SohInputEditorWindow::DrawLEDSection(uint8_t port) {
|
||||
for (auto [id, mapping] :
|
||||
LUS::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetLED()->GetAllLEDMappings()) {
|
||||
@ -1063,11 +1071,11 @@ void SohInputEditorWindow::DrawLEDSection(uint8_t port) {
|
||||
};
|
||||
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");
|
||||
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("gLedColorSource", 1) == LED_SOURCE_CUSTOM) {
|
||||
UIWidgets::Spacer(3);
|
||||
auto port1Color = CVarGetColor24("gLedPort1Color", { 255, 255, 255 });
|
||||
@ -1087,12 +1095,12 @@ void SohInputEditorWindow::DrawLEDSection(uint8_t port) {
|
||||
}
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Brightness: %.1f %%", "##LED_Brightness", "gLedBrightness", 0.0f,
|
||||
1.0f, "", 1.0f, true, true);
|
||||
DrawHelpIcon("Sets the brightness of controller LEDs. 0% brightness = LEDs off.");
|
||||
UIWidgets::Tooltip("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.");
|
||||
UIWidgets::Tooltip("Shows red color when health is critical, otherwise displays according to color source.");
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -1430,6 +1438,273 @@ void SohInputEditorWindow::DrawLEDDeviceIcons(uint8_t portIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
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", "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};
|
||||
|
||||
// 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);
|
||||
LUS::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", "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);
|
||||
|
||||
LUS::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();
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
|
||||
TableHelper::NextCol();
|
||||
|
||||
LUS::GuiWindow::BeginGroupPanel("Modifiers", ImGui::GetContentRegionAvail());
|
||||
labelWidth = ImGui::CalcTextSize(ocarinaSongDisable.label).x + 10;
|
||||
DrawMapping(ocarinaSongDisable, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaSharp, labelWidth, disableMask);
|
||||
DrawMapping(ocarinaFlat, labelWidth, disableMask);
|
||||
LUS::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);
|
||||
}
|
||||
|
||||
LUS::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", "gDpadOcarina");
|
||||
TableHelper::NextCol();
|
||||
UIWidgets::EnhancementCheckbox("Play with camera stick", "gRStickOcarina");
|
||||
UIWidgets::Spacer(0);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
void SohInputEditorWindow::DrawCameraControlPanel() {
|
||||
ImVec2 cursor = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
||||
LUS::GuiWindow::BeginGroupPanel("Aiming/First-Person Camera", ImGui::GetContentRegionAvail());
|
||||
UIWidgets::PaddedEnhancementCheckbox("Right Stick Aiming", "gRightStickAiming");
|
||||
UIWidgets::Tooltip("Allows for aiming with the right stick in:\n-First-Person/C-Up view\n-Weapon Aiming");
|
||||
if (CVarGetInteger("gRightStickAiming", 0)) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Allow moving while in first person mode", "gMoveWhileFirstPerson");
|
||||
UIWidgets::Tooltip("Changes the left stick to move the player while in first person mode");
|
||||
}
|
||||
UIWidgets::PaddedEnhancementCheckbox("Invert Aiming X Axis", "gInvertAimingXAxis");
|
||||
UIWidgets::Tooltip("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);
|
||||
UIWidgets::Tooltip("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);
|
||||
UIWidgets::Tooltip("Inverts the Shield Aiming Y Axis");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming X Axis", "gInvertShieldAimingXAxis");
|
||||
UIWidgets::Tooltip("Inverts the Shield Aiming X Axis");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Invert Z-Weapon Aiming Y Axis", "gInvertZAimingYAxis", 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", "gDisableAutoCenterViewFirstPerson");
|
||||
UIWidgets::Tooltip("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("gFirstPersonCameraSensitivityX");
|
||||
CVarClear("gFirstPersonCameraSensitivityY");
|
||||
}
|
||||
}
|
||||
if (CVarGetInteger("gEnableFirstPersonSensitivity", 0)) {
|
||||
UIWidgets::EnhancementSliderFloat("Aiming/First-Person Horizontal Sensitivity: %.0f %%", "##FirstPersonSensitivity Horizontal",
|
||||
"gFirstPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true);
|
||||
UIWidgets::EnhancementSliderFloat("Aiming/First-Person Vertical Sensitivity: %.0f %%", "##FirstPersonSensitivity Vertical",
|
||||
"gFirstPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true);
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
cursor = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
||||
LUS::GuiWindow::BeginGroupPanel("Third-Person Camera", ImGui::GetContentRegionAvail());
|
||||
|
||||
UIWidgets::PaddedEnhancementCheckbox("Free Camera", "gFreeCamera");
|
||||
UIWidgets::Tooltip("Enables free 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", "gInvertXAxis");
|
||||
UIWidgets::Tooltip("Inverts the Camera X Axis in:\n-Free camera");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Invert Camera Y Axis", "gInvertYAxis", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
||||
UIWidgets::Tooltip("Inverts the Camera Y Axis in:\n-Free camera");
|
||||
UIWidgets::Spacer(0);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Third-Person Horizontal Sensitivity: %.0f %%", "##ThirdPersonSensitivity Horizontal",
|
||||
"gThirdPersonCameraSensitivityX", 0.01f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Third-Person Vertical Sensitivity: %.0f %%", "##ThirdPersonSensitivity Vertical",
|
||||
"gThirdPersonCameraSensitivityY", 0.01f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Camera Distance: %d", "##CamDist",
|
||||
"gFreeCameraDistMax", 100, 900, "", 185, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Camera Transition Speed: %d", "##CamTranSpeed",
|
||||
"gFreeCameraTransitionSpeed", 0, 900, "", 25, true, false, true);
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
}
|
||||
|
||||
void SohInputEditorWindow::DrawDpadControlPanel() {
|
||||
ImVec2 cursor = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
||||
LUS::GuiWindow::BeginGroupPanel("D-Pad Options", ImGui::GetContentRegionAvail());
|
||||
UIWidgets::PaddedEnhancementCheckbox("D-pad Support on Pause Screen", "gDpadPause");
|
||||
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 gDpadHoldChange to 0");
|
||||
UIWidgets::PaddedEnhancementCheckbox("D-pad Support in Text Boxes", "gDpadText");
|
||||
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 gDpadHoldChange to 0");
|
||||
UIWidgets::PaddedEnhancementCheckbox("D-pad as Equip Items", "gDpadEquips");
|
||||
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");
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
}
|
||||
|
||||
void SohInputEditorWindow::DrawMiscControlPanel() {
|
||||
ImVec2 cursor = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
|
||||
LUS::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("gPauseAnyCursor", 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("gDisableChangingSettings", 0));
|
||||
UIWidgets::PaddedEnhancementCheckbox("Enable speed modifiers", "gEnableWalkModify", true, false);
|
||||
UIWidgets::Tooltip("Hold the assigned button to change the maximum walking or swimming speed");
|
||||
if (CVarGetInteger("gEnableWalkModify", 0)) {
|
||||
UIWidgets::Spacer(5);
|
||||
LUS::GuiWindow::BeginGroupPanel("Speed Modifier", ImGui::GetContentRegionAvail());
|
||||
UIWidgets::PaddedEnhancementCheckbox("Toggle modifier instead of holding", "gWalkSpeedToggle", true, false);
|
||||
LUS::GuiWindow::BeginGroupPanel("Walk Modifier", ImGui::GetContentRegionAvail());
|
||||
UIWidgets::PaddedEnhancementCheckbox("Don't affect jump distance/velocity", "gWalkModifierDoesntChangeJump", true, false);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Walk Modifier 1: %.0f %%", "##WalkMod1", "gWalkModifierOne", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Walk Modifier 2: %.0f %%", "##WalkMod2", "gWalkModifierTwo", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
LUS::GuiWindow::BeginGroupPanel("Swim Modifier", ImGui::GetContentRegionAvail());
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Swim Modifier 1: %.0f %%", "##SwimMod1", "gSwimModifierOne", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderFloat("Swim Modifier 2: %.0f %%", "##SwimMod2", "gSwimModifierTwo", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
UIWidgets::Spacer(0);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Answer Navi Prompt with L Button", "gNaviOnL");
|
||||
UIWidgets::Tooltip("Speak to Navi with L but enter first-person camera with C-Up");
|
||||
LUS::GuiWindow::EndGroupPanel(0);
|
||||
}
|
||||
|
||||
void SohInputEditorWindow::DrawLinkTab() {
|
||||
uint8_t portIndex = 0;
|
||||
if (ImGui::BeginTabItem(StringHelper::Sprintf("Link (P1)###port%d", portIndex).c_str())) {
|
||||
@ -1516,6 +1791,46 @@ void SohInputEditorWindow::DrawLinkTab() {
|
||||
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();
|
||||
|
@ -10,6 +10,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
typedef uint32_t N64ButtonMask;
|
||||
|
||||
typedef struct {
|
||||
const char* label;
|
||||
const char* cVarName;
|
||||
N64ButtonMask defaultBtn;
|
||||
} CustomButtonMap;
|
||||
|
||||
class SohInputEditorWindow : public LUS::GuiWindow {
|
||||
public:
|
||||
@ -51,6 +60,17 @@ class SohInputEditorWindow : public LUS::GuiWindow {
|
||||
void DrawRemoveGyroMappingButton(uint8_t port, std::string id);
|
||||
void DrawAddGyroMappingButton(uint8_t port);
|
||||
|
||||
// Used together for an incomplete linked hash map implementation in order to
|
||||
// map button masks to their names and original mapping on N64
|
||||
std::list<std::pair<N64ButtonMask, const char*>> buttons;
|
||||
std::unordered_map<N64ButtonMask, decltype(buttons)::iterator> buttonNames;
|
||||
void addButtonName(N64ButtonMask mask, const char* name);
|
||||
void DrawMapping(CustomButtonMap& mapping, float labelWidth, N64ButtonMask excludedButtons);
|
||||
void DrawOcarinaControlPanel();
|
||||
void DrawCameraControlPanel();
|
||||
void DrawDpadControlPanel();
|
||||
void DrawMiscControlPanel();
|
||||
|
||||
int32_t mGameInputBlockTimer;
|
||||
int32_t mMappingInputBlockTimer;
|
||||
int32_t mRumbleTimer;
|
||||
@ -84,6 +104,4 @@ class SohInputEditorWindow : public LUS::GuiWindow {
|
||||
bool mInputEditorPopupOpen;
|
||||
void DrawSetDefaultsButton(uint8_t portIndex);
|
||||
void DrawClearAllButton(uint8_t portIndex);
|
||||
|
||||
void DrawHelpIcon(const std::string& helptext);
|
||||
};
|
||||
|
@ -67,6 +67,7 @@ typedef enum {
|
||||
GROUP_EQUIPMENT,
|
||||
GROUP_CONSUMABLE,
|
||||
GROUP_HUD,
|
||||
GROUP_KALEIDO,
|
||||
GROUP_TITLE,
|
||||
GROUP_NPC,
|
||||
GROUP_WORLD,
|
||||
@ -75,6 +76,7 @@ typedef enum {
|
||||
GROUP_SPIN_ATTACK,
|
||||
GROUP_TRAILS,
|
||||
GROUP_NAVI,
|
||||
GROUP_IVAN,
|
||||
} CosmeticGroup;
|
||||
|
||||
std::map<CosmeticGroup, const char*> groupLabels = {
|
||||
@ -85,6 +87,7 @@ std::map<CosmeticGroup, const char*> groupLabels = {
|
||||
{ GROUP_EQUIPMENT, "Equipment" },
|
||||
{ GROUP_CONSUMABLE, "Consumables" },
|
||||
{ GROUP_HUD, "HUD" },
|
||||
{ GROUP_KALEIDO, "Pause Menu" },
|
||||
{ GROUP_TITLE, "Title Screen" },
|
||||
{ GROUP_NPC, "NPCs" },
|
||||
{ GROUP_WORLD, "World" },
|
||||
@ -93,6 +96,7 @@ std::map<CosmeticGroup, const char*> groupLabels = {
|
||||
{ GROUP_SPIN_ATTACK, "Spin Attack" },
|
||||
{ GROUP_TRAILS, "Trails" },
|
||||
{ GROUP_NAVI, "Navi" },
|
||||
{ GROUP_IVAN, "Ivan" }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -265,6 +269,38 @@ static std::map<std::string, CosmeticOption> cosmeticOptions = {
|
||||
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("Kal_ItemSelA", "Item Select Color A", GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_ItemSelB", "Item Select Color B", GROUP_KALEIDO, ImVec4(70, 100, 130, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_ItemSelC", "Item Select Color C", GROUP_KALEIDO, ImVec4(70, 100, 130, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_ItemSelD", "Item Select Color D", GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, false),
|
||||
|
||||
COSMETIC_OPTION("Kal_EquipSelA", "Equip Select Color A", GROUP_KALEIDO, ImVec4(10, 50, 40, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_EquipSelB", "Equip Select Color B", GROUP_KALEIDO, ImVec4(90, 100, 60, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_EquipSelC", "Equip Select Color C", GROUP_KALEIDO, ImVec4(90, 100, 60, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_EquipSelD", "Equip Select Color D", GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, false),
|
||||
|
||||
COSMETIC_OPTION("Kal_MapSelDunA", "Map Dungeon Color A", GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_MapSelDunB", "Map Dungeon Color B", GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_MapSelDunC", "Map Dungeon Color C", GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_MapSelDunD", "Map Dungeon Color D", GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, false),
|
||||
|
||||
COSMETIC_OPTION("Kal_QuestStatusA", "Quest StatusColor A", GROUP_KALEIDO, ImVec4(80, 80, 50, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_QuestStatusB", "Quest StatusColor B", GROUP_KALEIDO, ImVec4(120, 120, 70, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_QuestStatusC", "Quest StatusColor C", GROUP_KALEIDO, ImVec4(120, 120, 70, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_QuestStatusD", "Quest StatusColor D", GROUP_KALEIDO, ImVec4(80, 80, 50, 255), false, true, false),
|
||||
|
||||
COSMETIC_OPTION("Kal_MapSelectA", "Map Color A", GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_MapSelectB", "Map Color B", GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_MapSelectC", "Map Color C", GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_MapSelectD", "Map Color D", GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, false),
|
||||
|
||||
COSMETIC_OPTION("Kal_SaveA", "Save A", GROUP_KALEIDO, ImVec4(50, 50, 50, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_SaveB", "Save B", GROUP_KALEIDO, ImVec4(110, 110, 110, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_SaveC", "Save C", GROUP_KALEIDO, ImVec4(110, 110, 110, 255), false, true, false),
|
||||
COSMETIC_OPTION("Kal_SaveD", "Save D", GROUP_KALEIDO, ImVec4(50, 50, 50, 255), false, true, false),
|
||||
|
||||
COSMETIC_OPTION("Kal_NamePanel", "Name Panel", GROUP_KALEIDO, ImVec4(90,100,130,255), true, true, false),
|
||||
|
||||
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),
|
||||
@ -317,6 +353,9 @@ static std::map<std::string, CosmeticOption> cosmeticOptions = {
|
||||
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("Ivan_IdlePrimary", "Ivan Idle Primary", GROUP_IVAN, ImVec4(255, 255, 255, 255), false, true, false),
|
||||
COSMETIC_OPTION("Ivan_IdleSecondary", "Ivan Idle Secondary", GROUP_IVAN, ImVec4( 0, 255, 0, 255), false, true, true),
|
||||
|
||||
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),
|
||||
@ -1626,6 +1665,8 @@ void RandomizeColor(CosmeticOption& cosmeticOption) {
|
||||
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") {
|
||||
@ -1794,14 +1835,11 @@ void CosmeticsEditorWindow::DrawElement() {
|
||||
}
|
||||
UIWidgets::EnhancementCheckbox("Sync Rainbow colors", "gCosmetics.RainbowSync");
|
||||
UIWidgets::EnhancementSliderFloat("Rainbow Speed: %.3f", "##rainbowSpeed", "gCosmetics.RainbowSpeed", 0.03f, 1.0f, "", 0.6f, false, true);
|
||||
UIWidgets::EnhancementCheckbox("Randomize All on New Scene", "gCosmetics.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))) {
|
||||
@ -1861,6 +1899,7 @@ void CosmeticsEditorWindow::DrawElement() {
|
||||
if (ImGui::BeginTabItem("World & NPCs")) {
|
||||
DrawCosmeticGroup(GROUP_WORLD);
|
||||
DrawCosmeticGroup(GROUP_NAVI);
|
||||
DrawCosmeticGroup(GROUP_IVAN);
|
||||
DrawCosmeticGroup(GROUP_NPC);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
@ -1873,10 +1912,16 @@ void CosmeticsEditorWindow::DrawElement() {
|
||||
DrawCosmeticGroup(GROUP_TITLE);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("HUD Placement")) {
|
||||
Draw_Placements();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Pause Menu")) {
|
||||
DrawCosmeticGroup(GROUP_KALEIDO);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::End();
|
||||
@ -1894,6 +1939,14 @@ void RegisterOnGameFrameUpdateHook() {
|
||||
});
|
||||
}
|
||||
|
||||
void Cosmetics_RegisterOnSceneInitHook() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
|
||||
if (CVarGetInteger("gCosmetics.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) {
|
||||
@ -1911,6 +1964,7 @@ void CosmeticsEditorWindow::InitElement() {
|
||||
|
||||
RegisterOnLoadGameHook();
|
||||
RegisterOnGameFrameUpdateHook();
|
||||
Cosmetics_RegisterOnSceneInitHook();
|
||||
}
|
||||
|
||||
void CosmeticsEditor_RandomizeAll() {
|
||||
|
@ -8,6 +8,7 @@ extern "C" {
|
||||
#include "objects/object_gi_soldout/object_gi_soldout.h"
|
||||
#include "objects/object_ik/object_ik.h"
|
||||
#include "objects/object_link_child/object_link_child.h"
|
||||
#include "objects/object_ru2/object_ru2.h"
|
||||
|
||||
uint32_t ResourceMgr_GameHasMasterQuest();
|
||||
uint32_t ResourceMgr_GameHasOriginal();
|
||||
@ -187,10 +188,25 @@ void PatchIronKnuckleTextureOverflow() {
|
||||
}
|
||||
}
|
||||
|
||||
void PatchPrincessRutoEaring() {
|
||||
// FAST3D: This is a hack for the issue of both TEXEL0 and TEXEL1 using the same texture with different settings.
|
||||
// Ruto's earring uses both TEXEL0 and TEXEL1 to render. The issue is that it never loads anything into TEXEL1, so
|
||||
// it reuses whatever happens to be there, which is the water temple brick texture. It just so happens that the
|
||||
// earring texture loads into the same place in TMEM as the brick texture, so when it comes to rendering, TEXEL1
|
||||
// uses the earring texture with different clamp settings, and it displays without noticeable error. However, both
|
||||
// texel samplers are not intended to be used for the same texture with different settings, so this misuse confuses
|
||||
// our texture cache, and we load the wrong settings for the earrings texture. This patch is a hack that replaces
|
||||
// TEXEL1 with TEXEL0, which is most likely the original intention, and all is well.
|
||||
ResourceMgr_PatchGfxByName(gAdultRutoHeadDL, "RutoEaringTileFix", 162,
|
||||
gsDPSetCombineLERP(TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, COMBINED,
|
||||
TEXEL0, 0, PRIM_LOD_FRAC, COMBINED));
|
||||
}
|
||||
|
||||
void ApplyAuthenticGfxPatches() {
|
||||
PatchDekuStickTextureOverflow();
|
||||
PatchFreezardTextureOverflow();
|
||||
PatchIronKnuckleTextureOverflow();
|
||||
PatchPrincessRutoEaring();
|
||||
}
|
||||
|
||||
// Patches the Sold Out GI DL to render the texture in the mirror boundary
|
||||
|
@ -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,
|
||||
|
@ -730,6 +730,62 @@ void RegisterPatchNoMSHandler() {
|
||||
});
|
||||
}
|
||||
|
||||
void UpdatePatchHand() {
|
||||
if ((CVarGetInteger("gEnhancements.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("gEnhancements.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<GameInteractor::OnSceneInit>([](int32_t sceneNum) {
|
||||
UpdatePatchHand();
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterResetNaviTimer() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int32_t sceneNum) {
|
||||
if (CVarGetInteger("gEnhancements.ResetNaviTimer", 0)) {
|
||||
gSaveContext.naviTimer = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
f32 triforcePieceScale;
|
||||
|
||||
void RegisterTriforceHunt() {
|
||||
@ -1133,6 +1189,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<GameInteractor::OnLoadGame>([](int32_t fileNum) {
|
||||
UpdateHurtContainerModeState(CVarGetInteger("gHurtContainer", 0));
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterRandomizedEnemySizes() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* refActor) {
|
||||
// Randomized Enemy Sizes
|
||||
@ -1291,6 +1370,7 @@ void InitMods() {
|
||||
RegisterBonkDamage();
|
||||
RegisterMenuPathFix();
|
||||
RegisterMirrorModeHandler();
|
||||
RegisterResetNaviTimer();
|
||||
RegisterTriforceHunt();
|
||||
RegisterGrantGanonsBossKey();
|
||||
RegisterEnemyDefeatCounts();
|
||||
@ -1300,4 +1380,6 @@ void InitMods() {
|
||||
RegisterToTMedallions();
|
||||
NameTag_RegisterHooks();
|
||||
RegisterPatchNoMSHandler();
|
||||
RegisterPatchHandHandler();
|
||||
RegisterHurtContainerModeHandler();
|
||||
}
|
||||
|
@ -9,9 +9,11 @@ extern "C" {
|
||||
|
||||
void UpdateDirtPathFixState(int32_t sceneNum);
|
||||
void UpdateMirrorModeState(int32_t sceneNum);
|
||||
void UpdateHurtContainerModeState(bool newState);
|
||||
void PatchToTMedallions();
|
||||
void UpdatePermanentHeartLossState();
|
||||
void InitMods();
|
||||
void UpdatePatchHand();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -12,6 +12,14 @@ void clearCvars(std::vector<const char*> cvarsToClear) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string FormatLocations(std::vector<RandomizerCheck> locs) {
|
||||
std::string locString = "";
|
||||
for (auto loc: locs) {
|
||||
locString += std::to_string(loc) + ",";
|
||||
}
|
||||
return locString;
|
||||
}
|
||||
|
||||
void applyPreset(std::vector<PresetEntry> entries) {
|
||||
for(auto& [cvar, type, value] : entries) {
|
||||
switch (type) {
|
||||
@ -24,6 +32,9 @@ void applyPreset(std::vector<PresetEntry> entries) {
|
||||
case PRESET_ENTRY_TYPE_STRING:
|
||||
CVarSetString(cvar, std::get<const char*>(value));
|
||||
break;
|
||||
case PRESET_ENTRY_TYPE_CPP_STRING:
|
||||
CVarSetString(cvar, std::get<std::string>(value).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <cstdint>
|
||||
@ -11,6 +12,7 @@ enum PresetEntryType {
|
||||
PRESET_ENTRY_TYPE_S32,
|
||||
PRESET_ENTRY_TYPE_FLOAT,
|
||||
PRESET_ENTRY_TYPE_STRING,
|
||||
PRESET_ENTRY_TYPE_CPP_STRING,
|
||||
};
|
||||
|
||||
enum PresetType {
|
||||
@ -36,15 +38,19 @@ enum RandomizerPreset {
|
||||
typedef struct PresetEntry {
|
||||
const char* cvar;
|
||||
PresetEntryType type;
|
||||
std::variant<int32_t, float, const char*> value;
|
||||
std::variant<int32_t, float, const char*, std::string> value;
|
||||
} PresetEntry;
|
||||
|
||||
std::string FormatLocations(std::vector<RandomizerCheck> locs);
|
||||
|
||||
#define PRESET_ENTRY_S32(cvar, value) \
|
||||
{ cvar, PRESET_ENTRY_TYPE_S32, value }
|
||||
#define PRESET_ENTRY_FLOAT(cvar, value) \
|
||||
{ cvar, PRESET_ENTRY_TYPE_FLOAT, value }
|
||||
#define PRESET_ENTRY_STRING(cvar, value) \
|
||||
{ cvar, PRESET_ENTRY_TYPE_STRING, value }
|
||||
#define PRESET_ENTRY_CPP_STRING(cvar, value) \
|
||||
{ cvar, PRESET_ENTRY_TYPE_CPP_STRING, value }
|
||||
|
||||
void DrawPresetSelector(PresetType presetType);
|
||||
void clearCvars(std::vector<const char*> cvarsToClear);
|
||||
@ -70,6 +76,7 @@ const std::vector<const char*> enhancementsCvars = {
|
||||
"gForgeTime",
|
||||
"gClimbSpeed",
|
||||
"gFasterBlockPush",
|
||||
"gCrawlSpeed",
|
||||
"gFasterHeavyBlockLift",
|
||||
"gNoForcedNavi",
|
||||
"gSkulltulaFreeze",
|
||||
@ -136,6 +143,7 @@ const std::vector<const char*> enhancementsCvars = {
|
||||
"gInjectItemCounts",
|
||||
"gDayGravePull",
|
||||
"gDampeAllNight",
|
||||
"gQuitFishingAtDoor",
|
||||
"gSkipSwimDeepEndAnim",
|
||||
"gSkipScarecrow",
|
||||
"gBlueFireArrows",
|
||||
@ -184,6 +192,14 @@ const std::vector<const char*> enhancementsCvars = {
|
||||
"gBombchuBowlingNoSmallCucco",
|
||||
"gBombchuBowlingNoBigCucco",
|
||||
"gBombchuBowlingAmmunition",
|
||||
"gCustomizeOcarinaGame",
|
||||
"gInstantOcarinaGameWin",
|
||||
"gOcarinaGameNoteSpeed",
|
||||
"gOcarinaUnlimitedFailTime",
|
||||
"gOcarinaGameStartingNotes",
|
||||
"gOcarinaGameRoundOneNotes",
|
||||
"gOcarinaGameRoundTwoNotes",
|
||||
"gOcarinaGameRoundThreeNotes",
|
||||
"gCreditsFix",
|
||||
"gSilverRupeeJingleExtend",
|
||||
"gStaticExplosionRadius",
|
||||
@ -256,6 +272,8 @@ const std::vector<const char*> cheatCvars = {
|
||||
"gWalkSpeedToggle",
|
||||
"gWalkModifierOne",
|
||||
"gWalkModifierTwo",
|
||||
"gSwimModifierOne",
|
||||
"gSwimModifierTwo",
|
||||
"gGoronPot",
|
||||
"gDampeWin",
|
||||
"gCustomizeShootingGallery",
|
||||
@ -783,6 +801,13 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
|
||||
// Adult Minimum Weight (8 to 13)
|
||||
PRESET_ENTRY_S32("gAdultMinimumWeightFish", 6),
|
||||
|
||||
// Customize Lost Woods Ocarina Game Behavior
|
||||
PRESET_ENTRY_S32("gCustomizeOcarinaGame", 1),
|
||||
// Start With Five Notes
|
||||
PRESET_ENTRY_S32("gOcarinaGameStartingNotes", 5),
|
||||
// Round One Notes
|
||||
PRESET_ENTRY_S32("gOcarinaGameRoundOneNotes", 5),
|
||||
|
||||
// Visual Stone of Agony
|
||||
PRESET_ENTRY_S32("gVisualAgony", 1),
|
||||
// Pull grave during the day
|
||||
@ -871,7 +896,8 @@ const std::vector<PresetEntry> spockRacePresetEntries = {
|
||||
PRESET_ENTRY_S32("gRandomizeDampeHint", 1),
|
||||
PRESET_ENTRY_S32("gRandomizeDoorOfTime", RO_DOOROFTIME_OPEN),
|
||||
PRESET_ENTRY_S32("gRandomizeEnableBombchuDrops", 1),
|
||||
PRESET_ENTRY_STRING("gRandomizeExcludedLocations", "78,143,144,229,"),
|
||||
PRESET_ENTRY_CPP_STRING("gRandomizeExcludedLocations", 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),
|
||||
@ -963,7 +989,8 @@ const std::vector<PresetEntry> spockRaceNoLogicPresetEntries = {
|
||||
PRESET_ENTRY_S32("gRandomizeDampeHint", 1),
|
||||
PRESET_ENTRY_S32("gRandomizeDoorOfTime", RO_DOOROFTIME_OPEN),
|
||||
PRESET_ENTRY_S32("gRandomizeEnableBombchuDrops", 1),
|
||||
PRESET_ENTRY_STRING("gRandomizeExcludedLocations", "78,143,144,229,"),
|
||||
PRESET_ENTRY_CPP_STRING("gRandomizeExcludedLocations", 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),
|
||||
@ -1016,7 +1043,7 @@ const std::vector<PresetEntry> s6PresetEntries = {
|
||||
PRESET_ENTRY_S32("gRandomizeBigPoeTargetCount", 1),
|
||||
PRESET_ENTRY_S32("gRandomizeCuccosToReturn", 4),
|
||||
PRESET_ENTRY_S32("gRandomizeDoorOfTime", RO_DOOROFTIME_OPEN),
|
||||
PRESET_ENTRY_STRING("gRandomizeExcludedLocations", "48,"),
|
||||
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),
|
||||
|
@ -40,7 +40,7 @@ void AreaTable_Init_FireTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}),
|
||||
Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyFireTemple && ((IsAdult && LogicFireBossDoorJump) || CanUse(HOVER_BOOTS) || Here(FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return CanUse(MEGATON_HAMMER);}));}}),
|
||||
Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyFireTemple && ((IsAdult && (LogicFireBossDoorJump || Here(FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return CanUse(MEGATON_HAMMER);}))) || CanUse(HOVER_BOOTS));}}),
|
||||
});
|
||||
|
||||
areaTable[FIRE_TEMPLE_LOOP_ENEMIES] = Area("Fire Temple Loop Enemies", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
@ -536,7 +536,7 @@ namespace Logic {
|
||||
Fish = HasBottle && FishAccess;
|
||||
Fairy = HasBottle && FairyAccess;
|
||||
|
||||
FoundBombchus = (BombchuDrop || Bombchus || Bombchus5 || Bombchus10 || Bombchus20);
|
||||
FoundBombchus = (BombchuDrop || Bombchus || Bombchus5 || Bombchus10 || Bombchus20) && (BombBag || BombchusInLogic);
|
||||
CanPlayBowling = (BombchusInLogic && FoundBombchus) || (!BombchusInLogic && BombBag);
|
||||
HasBombchus = (BuyBombchus10 || BuyBombchus20 || (AmmoDrops.Is(AMMODROPS_BOMBCHU) && FoundBombchus));
|
||||
|
||||
|
@ -4221,7 +4221,7 @@ void RandomizerSettingsWindow::DrawElement() {
|
||||
break;
|
||||
case RO_LACS_GREG_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoLacsStoneCount",
|
||||
"gRandomizeLacsStoneCount", 1, 4, "", 4, true, true, false);
|
||||
"gRandomizeLacsStoneCount", 1, 4, "", 3, true, true, false);
|
||||
break;
|
||||
case RO_LACS_WILDCARD_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Stone Count: %d", "##RandoLacsStoneCount",
|
||||
@ -4250,7 +4250,7 @@ void RandomizerSettingsWindow::DrawElement() {
|
||||
break;
|
||||
case RO_LACS_GREG_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoLacsMedallionCount",
|
||||
"gRandomizeLacsMedallionCount", 1, 7, "", 7, true, true, false);
|
||||
"gRandomizeLacsMedallionCount", 1, 7, "", 6, true, true, false);
|
||||
break;
|
||||
case RO_LACS_WILDCARD_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Medallion Count: %d", "##RandoLacsMedallionCount",
|
||||
@ -4279,7 +4279,7 @@ void RandomizerSettingsWindow::DrawElement() {
|
||||
break;
|
||||
case RO_LACS_GREG_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoLacsRewardCount",
|
||||
"gRandomizeLacsRewardCount", 1, 10, "", 10, true, true, false);
|
||||
"gRandomizeLacsRewardCount", 1, 10, "", 9, true, true, false);
|
||||
break;
|
||||
case RO_LACS_WILDCARD_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Reward Count: %d", "##RandoLacsRewardCount",
|
||||
@ -4308,7 +4308,7 @@ void RandomizerSettingsWindow::DrawElement() {
|
||||
break;
|
||||
case RO_LACS_GREG_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoLacsDungeonCount",
|
||||
"gRandomizeLacsDungeonCount", 1, 9, "", 9, true, true, false);
|
||||
"gRandomizeLacsDungeonCount", 1, 9, "", 8, true, true, false);
|
||||
break;
|
||||
case RO_LACS_WILDCARD_REWARD:
|
||||
UIWidgets::PaddedEnhancementSliderInt("Dungeon Count: %d", "##RandoLacsDungeonCount",
|
||||
|
@ -412,10 +412,31 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) {
|
||||
|
||||
void DrawItemCount(ItemTrackerItem item) {
|
||||
int iconSize = CVarGetInteger("gItemTrackerIconSize", 36);
|
||||
int textSize = CVarGetInteger("gTrackers.ItemTracker.ItemTrackerTextSize", 13);
|
||||
ItemTrackerNumbers currentAndMax = GetItemCurrentAndMax(item);
|
||||
ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
int32_t trackerNumberDisplayMode = CVarGetInteger("gItemTrackerCapacityTrack", ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY);
|
||||
int32_t trackerKeyNumberDisplayMode = CVarGetInteger("gItemTrackerKeyTrack", KEYS_COLLECTED_MAX);
|
||||
float textScalingFactor = static_cast<float>(iconSize) / 36.0f;
|
||||
uint32_t actualItemId = INV_CONTENT(item.id);
|
||||
bool hasItem = actualItemId != ITEM_NONE;
|
||||
|
||||
if (CVarGetInteger("gTrackers.ItemTracker.HookshotIdentifier", 0)) {
|
||||
if ((actualItemId == ITEM_HOOKSHOT || actualItemId == ITEM_LONGSHOT) && hasItem) {
|
||||
|
||||
// Calculate the scaled position for the text
|
||||
ImVec2 textPos = ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(item.id == ITEM_HOOKSHOT ? "H" : "L").x *
|
||||
textScalingFactor / 2) + 8 * textScalingFactor, p.y - 22 * textScalingFactor);
|
||||
|
||||
ImGui::SetCursorScreenPos(textPos);
|
||||
ImGui::SetWindowFontScale(textScalingFactor);
|
||||
|
||||
ImGui::Text(item.id == ITEM_HOOKSHOT ? "H" : "L");
|
||||
ImGui::SetWindowFontScale(1.0f); // Reset font scale to the original state
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SetWindowFontScale(textSize / 13.0f);
|
||||
|
||||
if (item.id == ITEM_KEY_SMALL && IsValidSaveFile()) {
|
||||
std::string currentString = "";
|
||||
@ -671,7 +692,7 @@ void DrawDungeonItem(ItemTrackerItem item) {
|
||||
|
||||
ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
std::string dungeonName = itemTrackerDungeonShortNames[item.data];
|
||||
ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + 16)));
|
||||
ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + CVarGetInteger("gTrackers.ItemTracker.ItemTrackerTextSize", 13) + 3)));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, dungeonColor);
|
||||
ImGui::Text("%s", dungeonName.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
@ -800,7 +821,7 @@ void DrawItemsInACircle(std::vector<ItemTrackerItem> items) {
|
||||
float angle = (float)i / items.size() * 2.0f * M_PI;
|
||||
float x = (radius / 2.0f) * cos(angle) + max.x / 2.0f;
|
||||
float y = (radius / 2.0f) * sin(angle) + max.y / 2.0f;
|
||||
ImGui::SetCursorPos(ImVec2(x - 14, y + 4));
|
||||
ImGui::SetCursorPos(ImVec2(x - (CVarGetInteger("gItemTrackerIconSize", 36) - 8) / 2.0f, y + 4));
|
||||
items[i].drawFunc(items[i]);
|
||||
}
|
||||
}
|
||||
@ -1127,6 +1148,7 @@ void ItemTrackerSettingsWindow::DrawElement() {
|
||||
UIWidgets::PaddedSeparator();
|
||||
UIWidgets::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gItemTrackerIconSize", 25, 128, "", 36);
|
||||
UIWidgets::EnhancementSliderInt("Icon margins : %dpx", "##ITEMTRACKERSPACING", "gItemTrackerIconSpacing", -5, 50, "", 12);
|
||||
UIWidgets::EnhancementSliderInt("Text size : %dpx", "##ITEMTRACKERTEXTSIZE", "gTrackers.ItemTracker.ItemTrackerTextSize", 1, 30, "", 13);
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
@ -1167,7 +1189,7 @@ void ItemTrackerSettingsWindow::DrawElement() {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarGetInteger("gItemTrackerDungeonRewardsDisplayType", SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) {
|
||||
if (UIWidgets::PaddedEnhancementCheckbox("Circle display", "gItemTrackerDungeonRewardsCircle", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true)) {
|
||||
if (UIWidgets::PaddedEnhancementCheckbox("Circle display", "gItemTrackerDungeonRewardsCircle", true, true, false, "", UIWidgets::CheckboxGraphics::Cross, false)) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
@ -1200,6 +1222,10 @@ void ItemTrackerSettingsWindow::DrawElement() {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
UIWidgets::EnhancementCheckbox("Show Hookshot Identifiers", "gTrackers.ItemTracker.HookshotIdentifier");
|
||||
UIWidgets::InsertHelpHoverText("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.");
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTable();
|
||||
|
@ -207,6 +207,9 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
gSaveContext.randomizerInf[i] = 0;
|
||||
}
|
||||
|
||||
// Reset triforce pieces collected
|
||||
gSaveContext.triforcePiecesCollected = 0;
|
||||
|
||||
gSaveContext.cutsceneIndex = 0; // no intro cutscene
|
||||
// Starts pending ice traps out at 0 before potentially incrementing them down the line.
|
||||
gSaveContext.pendingIceTrapCount = 0;
|
||||
@ -442,8 +445,5 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth
|
||||
}
|
||||
|
||||
// Reset triforce pieces collected
|
||||
gSaveContext.triforcePiecesCollected = 0;
|
||||
|
||||
SetStartingItems();
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ void AdvancedResolutionSettingsWindow::DrawElement() {
|
||||
const bool disabled_resolutionSlider = (CVarGetInteger("gAdvancedResolution.VerticalResolutionToggle", 0) &&
|
||||
CVarGetInteger("gAdvancedResolution.Enabled", 0)) ||
|
||||
CVarGetInteger("gLowResMode", 0);
|
||||
if (UIWidgets::EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f,
|
||||
if (UIWidgets::EnhancementSliderFloat("Internal Resolution: %.1f%%", "##IMul", "gInternalResolution", 0.5f,
|
||||
2.0f, "", 1.0f, true, true, disabled_resolutionSlider)) {
|
||||
LUS::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(
|
||||
CVarGetFloat("gInternalResolution", 1));
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <dr_libs/wav.h>
|
||||
#include <AudioPlayer.h>
|
||||
#include "Enhancements/speechsynthesizer/SpeechSynthesizer.h"
|
||||
#include "Enhancements/controls/GameControlEditor.h"
|
||||
#include "Enhancements/controls/SohInputEditorWindow.h"
|
||||
#include "Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
#include "Enhancements/audio/AudioCollection.h"
|
||||
@ -318,6 +317,8 @@ OTRGlobals::OTRGlobals() {
|
||||
context->InitWindow(sohInputEditorWindow);
|
||||
context->InitAudio();
|
||||
|
||||
SPDLOG_INFO("Starting Ship of Harkinian version {}", (char*)gBuildVersion);
|
||||
|
||||
context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::SOH_Animation, "Animation", std::make_shared<LUS::AnimationFactory>());
|
||||
context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::SOH_PlayerAnimation, "PlayerAnimation", std::make_shared<LUS::PlayerAnimationFactory>());
|
||||
context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::SOH_Room, "Room", std::make_shared<LUS::SceneFactory>()); // Is room scene? maybe?
|
||||
@ -1213,8 +1214,7 @@ extern "C" uint64_t GetUnixTimestamp() {
|
||||
auto time = std::chrono::system_clock::now();
|
||||
auto since_epoch = time.time_since_epoch();
|
||||
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch);
|
||||
long now = millis.count();
|
||||
return now;
|
||||
return (uint64_t)millis.count();
|
||||
}
|
||||
|
||||
// C->C++ Bridge
|
||||
@ -2563,8 +2563,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
||||
randoInf = RAND_INF_MERCHANTS_CARPET_SALESMAN;
|
||||
}
|
||||
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, textId, Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_ON_HINT);
|
||||
} else if (Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) &&
|
||||
(textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT)) {
|
||||
} else if (textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
|
||||
} else if (textId == TEXT_CURSED_SKULLTULA_PEOPLE) {
|
||||
actorParams = GET_PLAYER(play)->targetActor->params;
|
||||
@ -2629,6 +2628,9 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
||||
if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger("gMarketSneak", 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT);
|
||||
}
|
||||
if (textId == TEXT_FISHERMAN_LEAVE && CVarGetInteger("gQuitFishingAtDoor", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_FISHERMAN_LEAVE);
|
||||
}
|
||||
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
|
||||
switch (gSaveContext.language) {
|
||||
case LANGUAGE_FRA:
|
||||
@ -2674,6 +2676,24 @@ extern "C" void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* repla
|
||||
gfx_register_blended_texture(name, mask, replacement);
|
||||
}
|
||||
|
||||
extern "C" void Gfx_UnregisterBlendedTexture(const char* name) {
|
||||
gfx_unregister_blended_texture(name);
|
||||
}
|
||||
|
||||
extern "C" void Gfx_TextureCacheDelete(const uint8_t* texAddr) {
|
||||
char* imgName = (char*)texAddr;
|
||||
|
||||
if (texAddr == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ResourceMgr_OTRSigCheck(imgName)) {
|
||||
texAddr = (const uint8_t*)GetResourceDataByNameHandlingMQ(imgName);
|
||||
}
|
||||
|
||||
gfx_texture_cache_delete(texAddr);
|
||||
}
|
||||
|
||||
void SoH_ProcessDroppedFiles(std::string filePath) {
|
||||
try {
|
||||
std::ifstream configStream(filePath);
|
||||
|
@ -176,6 +176,8 @@ void Entrance_InitEntranceTrackingData(void);
|
||||
void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex);
|
||||
void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex);
|
||||
void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement);
|
||||
void Gfx_UnregisterBlendedTexture(const char* name);
|
||||
void Gfx_TextureCacheDelete(const uint8_t* addr);
|
||||
void SaveManager_ThreadPoolWait();
|
||||
void CheckTracker_OnMessageClose();
|
||||
|
||||
|
@ -116,7 +116,6 @@ namespace SohGui {
|
||||
std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
|
||||
|
||||
std::shared_ptr<AudioEditor> mAudioEditorWindow;
|
||||
std::shared_ptr<GameControlEditor::GameControlEditorWindow> mGameControlEditorWindow;
|
||||
std::shared_ptr<CosmeticsEditorWindow> mCosmeticsEditorWindow;
|
||||
std::shared_ptr<ActorViewerWindow> mActorViewerWindow;
|
||||
std::shared_ptr<ColViewerWindow> mColViewerWindow;
|
||||
@ -164,8 +163,6 @@ namespace SohGui {
|
||||
|
||||
mAudioEditorWindow = std::make_shared<AudioEditor>("gAudioEditor.WindowOpen", "Audio Editor");
|
||||
gui->AddGuiWindow(mAudioEditorWindow);
|
||||
mGameControlEditorWindow = std::make_shared<GameControlEditor::GameControlEditorWindow>("gGameControlEditorEnabled", "Game Control Editor");
|
||||
gui->AddGuiWindow(mGameControlEditorWindow);
|
||||
mCosmeticsEditorWindow = std::make_shared<CosmeticsEditorWindow>("gCosmeticsEditorEnabled", "Cosmetics Editor");
|
||||
gui->AddGuiWindow(mCosmeticsEditorWindow);
|
||||
mActorViewerWindow = std::make_shared<ActorViewerWindow>("gActorViewerEnabled", "Actor Viewer");
|
||||
@ -211,7 +208,6 @@ namespace SohGui {
|
||||
mColViewerWindow = nullptr;
|
||||
mActorViewerWindow = nullptr;
|
||||
mCosmeticsEditorWindow = nullptr;
|
||||
mGameControlEditorWindow = nullptr;
|
||||
mAudioEditorWindow = nullptr;
|
||||
mInputEditorWindow = nullptr;
|
||||
mStatsWindow = nullptr;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <stdio.h>
|
||||
#include "SohMenuBar.h"
|
||||
#include "Enhancements/audio/AudioEditor.h"
|
||||
#include "Enhancements/controls/GameControlEditor.h"
|
||||
#include "Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
#include "Enhancements/debugger/actorViewer.h"
|
||||
#include "Enhancements/debugger/colViewer.h"
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
|
||||
#include "Enhancements/audio/AudioEditor.h"
|
||||
#include "Enhancements/controls/GameControlEditor.h"
|
||||
#include "Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
#include "Enhancements/debugger/actorViewer.h"
|
||||
#include "Enhancements/debugger/colViewer.h"
|
||||
@ -180,7 +179,6 @@ void DrawShipMenu() {
|
||||
}
|
||||
|
||||
extern std::shared_ptr<LUS::GuiWindow> mInputEditorWindow;
|
||||
extern std::shared_ptr<GameControlEditor::GameControlEditorWindow> mGameControlEditorWindow;
|
||||
extern std::shared_ptr<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow> mAdvancedResolutionSettingsWindow;
|
||||
|
||||
void DrawSettingsMenu() {
|
||||
@ -241,11 +239,6 @@ void DrawSettingsMenu() {
|
||||
mInputEditorWindow->ToggleVisibility();
|
||||
}
|
||||
}
|
||||
if (mGameControlEditorWindow) {
|
||||
if (ImGui::Button(GetWindowButtonText("Additional Controller Options", CVarGetInteger("gGameControlEditorEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
|
||||
mGameControlEditorWindow->ToggleVisibility();
|
||||
}
|
||||
}
|
||||
UIWidgets::PaddedSeparator();
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopStyleVar(3);
|
||||
@ -273,8 +266,10 @@ void DrawSettingsMenu() {
|
||||
2.0f, "", 1.0f, true, true, disabled_resolutionSlider)) {
|
||||
LUS::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1));
|
||||
}
|
||||
UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing");
|
||||
#endif
|
||||
UIWidgets::Tooltip("Resolution scale. Multiplies output resolution by this value, on each axis relative to window size.\n"
|
||||
"Lower values may improve performance.\n"
|
||||
"Values above 100% can be used for super-sampling, as an intensive but highly effective form of anti-aliasing.\n\n"
|
||||
"Default: 100%");
|
||||
|
||||
if (mAdvancedResolutionSettingsWindow) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f));
|
||||
@ -288,14 +283,28 @@ void DrawSettingsMenu() {
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopStyleVar(3);
|
||||
}
|
||||
|
||||
#ifndef __WIIU__
|
||||
if (UIWidgets::PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "", 1, true, true, false)) {
|
||||
LUS::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1));
|
||||
};
|
||||
UIWidgets::Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel");
|
||||
#else
|
||||
// macOS: Internal resolution is currently disabled in libultraship.
|
||||
ImGui::BeginGroup();
|
||||
ImGui::Text("Internal Resolution: 100.0%%");
|
||||
UIWidgets::Spacer(0);
|
||||
ImGui::Text(" " ICON_FA_INFO_CIRCLE " Not available on this system.");
|
||||
UIWidgets::Spacer(0);
|
||||
ImGui::EndGroup();
|
||||
#endif
|
||||
|
||||
#ifndef __WIIU__
|
||||
if (UIWidgets::PaddedEnhancementSliderInt(
|
||||
(CVarGetInteger("gMSAAValue", 1) == 1) ? "Anti-aliasing (MSAA): Off" : "Anti-aliasing (MSAA): %d",
|
||||
"##IMSAA", "gMSAAValue", 1, 8, "", 1, true, true, false)) {
|
||||
LUS::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1));
|
||||
}
|
||||
UIWidgets::Tooltip("Activates MSAA (multi-sample anti-aliasing) from 2x up to 8x, to smooth the edges of rendered geometry.\n"
|
||||
"Higher sample count will result in smoother edges on models, but may reduce performance.\n\n"
|
||||
"Recommended: 2x or 4x");
|
||||
#endif
|
||||
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
{ // FPS Slider
|
||||
const int minFps = 20;
|
||||
static int maxFps;
|
||||
@ -369,26 +378,27 @@ void DrawSettingsMenu() {
|
||||
bool matchingRefreshRate =
|
||||
CVarGetInteger("gMatchRefreshRate", 0) && LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() != LUS::WindowBackend::DX11;
|
||||
UIWidgets::PaddedEnhancementSliderInt(
|
||||
(currentFps == 20) ? "FPS: Original (20)" : "FPS: %d",
|
||||
(currentFps == 20) ? "Frame Rate: Original (20 fps)" : "Frame Rate: %d fps",
|
||||
"##FPSInterpolation", "gInterpolationFPS", minFps, maxFps, "", 20, true, true, false, matchingRefreshRate);
|
||||
#endif
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
|
||||
UIWidgets::Tooltip(
|
||||
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is purely "
|
||||
"visual and does not impact game logic, execution of glitches etc.\n\n"
|
||||
"A higher target FPS than your monitor's refresh rate will waste resources, and might give a worse result."
|
||||
);
|
||||
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics.\n"
|
||||
"This is purely visual and does not impact game logic, execution of glitches etc.\n"
|
||||
"Higher frame rate settings may impact CPU performance."
|
||||
"\n\n " ICON_FA_INFO_CIRCLE
|
||||
" There is no need to set this above your monitor's refresh rate. Doing so will waste resources and may give a worse result.");
|
||||
} else {
|
||||
UIWidgets::Tooltip(
|
||||
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is purely "
|
||||
"visual and does not impact game logic, execution of glitches etc."
|
||||
);
|
||||
"Uses Matrix Interpolation to create extra frames, resulting in smoother graphics.\n"
|
||||
"This is purely visual and does not impact game logic, execution of glitches etc.\n"
|
||||
"Higher frame rate settings may impact CPU performance.");
|
||||
}
|
||||
} // END FPS Slider
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
|
||||
UIWidgets::Spacer(0);
|
||||
if (ImGui::Button("Match Refresh Rate")) {
|
||||
if (ImGui::Button("Match Frame Rate to Refresh Rate")) {
|
||||
int hz = LUS::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
|
||||
if (hz >= 20 && hz <= 360) {
|
||||
CVarSetInteger("gInterpolationFPS", hz);
|
||||
@ -396,17 +406,22 @@ void DrawSettingsMenu() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Match Refresh Rate", "gMatchRefreshRate", true, false);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Match Frame Rate to Refresh Rate", "gMatchRefreshRate", true, false);
|
||||
}
|
||||
UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate");
|
||||
UIWidgets::Tooltip("Matches interpolation value to the game window's current refresh rate.");
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetWindowBackend() == LUS::WindowBackend::DX11) {
|
||||
UIWidgets::PaddedEnhancementSliderInt(CVarGetInteger("gExtraLatencyThreshold", 80) == 0 ? "Jitter fix: Off" : "Jitter fix: >= %d FPS",
|
||||
"##ExtraLatencyThreshold", "gExtraLatencyThreshold", 0, 360, "", 80, true, true, false);
|
||||
UIWidgets::Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag (e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to work on one frame while GPU works on the previous frame.\nThis setting should be used when your computer is too slow to do CPU + GPU work in time.");
|
||||
UIWidgets::Tooltip(
|
||||
"(For DirectX backend only)\n\n"
|
||||
"When Interpolation FPS (Frame Rate) setting is at least this threshold, add one frame of delay (e.g. 16.6 ms for 60 FPS) in order to avoid jitter."
|
||||
"This setting allows the CPU to work on one frame while GPU works on the previous frame.\n"
|
||||
"This setting should be used when your computer is too slow to do CPU + GPU work in time.");
|
||||
}
|
||||
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
|
||||
ImGui::Text("ImGui Menu Scale");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored({ 0.85f, 0.35f, 0.0f, 1.0f }, "(Experimental)");
|
||||
@ -455,6 +470,7 @@ void DrawSettingsMenu() {
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Enable Vsync", "gVsyncEnabled", true, false);
|
||||
UIWidgets::Tooltip("Activate vertical sync, to prevent screen tearing.");
|
||||
}
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen()) {
|
||||
@ -462,17 +478,21 @@ void DrawSettingsMenu() {
|
||||
}
|
||||
|
||||
if (LUS::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports()) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows", "gEnableMultiViewports", true, false, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows (Needs reload)", "gEnableMultiViewports", true, false, false, "", UIWidgets::CheckboxGraphics::Cross, true);
|
||||
UIWidgets::Tooltip("Allows windows to be able to be dragged off of the main game window. Requires a reload to take effect.");
|
||||
}
|
||||
|
||||
// If more filters are added to LUS, make sure to add them to the filters list here
|
||||
ImGui::Text("Texture Filter (Needs reload)");
|
||||
|
||||
ImGui::Text("Texture Filtering (Needs reload)");
|
||||
UIWidgets::EnhancementCombobox("gTextureFilter", filters, FILTER_THREE_POINT);
|
||||
UIWidgets::Tooltip("Texture filtering, aka texture smoothing. Requires a reload to take effect.\n\n"
|
||||
"Three-Point: Replicates real N64 texture filtering.\n"
|
||||
"Bilinear: If Three-Point causes poor performance, try this.\n"
|
||||
"Nearest: Disables texture smoothing. (Not recommended)");
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f);
|
||||
|
||||
// Draw LUS settings menu (such as Overlays Text Font)
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings();
|
||||
|
||||
ImGui::EndMenu();
|
||||
@ -542,6 +562,7 @@ void DrawEnhancementsMenu() {
|
||||
UIWidgets::PaddedEnhancementSliderInt("King Zora Speed: %dx", "##MWEEPSPEED", "gMweepSpeed", 1, 5, "", 1, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", "gClimbSpeed", 0, 12, "", 0, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Block pushing speed +%d", "##BLOCKSPEED", "gFasterBlockPush", 0, 5, "", 0, true, false, true);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Crawl speed %dx", "##CRAWLSPEED", "gCrawlSpeed", 1, 5, "", 1, true, false, true);
|
||||
UIWidgets::PaddedEnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift", false, false);
|
||||
UIWidgets::Tooltip("Speeds up lifting silver rocks and obelisks");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Skip Pickup Messages", "gFastDrops", true, false);
|
||||
@ -573,6 +594,8 @@ void DrawEnhancementsMenu() {
|
||||
"This doesn't work if the save was made in a grotto.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("No Forced Navi", "gNoForcedNavi", true, false);
|
||||
UIWidgets::Tooltip("Prevent forced Navi conversations");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Navi Timer Resets", "gEnhancements.ResetNaviTimer", true, false);
|
||||
UIWidgets::Tooltip("Resets the Navi timer on scene change. If you have already talked to her, she will try and talk to you again, instead of needing a save warp or death. ");
|
||||
UIWidgets::PaddedEnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze", true, false);
|
||||
UIWidgets::Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Nighttime GS Always Spawn", "gNightGSAlwaysSpawn", true, false);
|
||||
@ -610,6 +633,8 @@ void DrawEnhancementsMenu() {
|
||||
UIWidgets::Tooltip("Allows exiting Hyrule Castle Market Town to Hyrule Field at night by speaking to the guard next to the gate.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Link as default file name", "gLinkDefaultName", true, false);
|
||||
UIWidgets::Tooltip("Allows you to have \"Link\" as a premade file name");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Quit Fishing At Door", "gQuitFishingAtDoor", true, false);
|
||||
UIWidgets::Tooltip("Fisherman asks if you want to quit at the door when you still have the rod");
|
||||
UIWidgets::PaddedText("Time Travel with the Song of Time", true, false);
|
||||
UIWidgets::EnhancementCombobox("gTimeTravel", timeTravelOptions, 0);
|
||||
UIWidgets::Tooltip("Allows Link to freely change age by playing the Song of Time.\n"
|
||||
@ -814,6 +839,40 @@ void DrawEnhancementsMenu() {
|
||||
UIWidgets::Tooltip("The minimum weight for the unique fishing reward as an adult");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
if (ImGui::BeginMenu("Lost Woods Ocarina Game")) {
|
||||
UIWidgets::EnhancementCheckbox("Customize Behavior", "gCustomizeOcarinaGame");
|
||||
UIWidgets::Tooltip("Turn on/off changes to the lost woods ocarina game behavior");
|
||||
bool disabled = !CVarGetInteger("gCustomizeOcarinaGame", 0);
|
||||
static const char* disabledTooltip = "This option is disabled because \"Customize Behavior\" is turned off";
|
||||
UIWidgets::PaddedEnhancementCheckbox("Instant Win", "gInstantOcarinaGameWin", true, false, disabled, disabledTooltip);
|
||||
UIWidgets::Tooltip("Skips the lost woods ocarina game");
|
||||
UIWidgets::PaddedEnhancementSliderInt("Note Play Speed: %dx", "##OcarinaGameNoteSpeed", "gOcarinaGameNoteSpeed", 1, 5, "", 1, true, true, false, disabled, disabledTooltip);
|
||||
UIWidgets::Tooltip("Adjust the speed that the skull kids play notes");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Unlimited Playback Time", "gOcarinaUnlimitedFailTime", true, false, disabled, disabledTooltip);
|
||||
UIWidgets::Tooltip("Removes the timer to play back the song");
|
||||
UIWidgets::PaddedEnhancementSliderInt("Number of Starting Notes: %d", "##OcarinaGameStartingNotes", "gOcarinaGameStartingNotes", 1, 8, "", 3, true, true, false,
|
||||
disabled, disabledTooltip);
|
||||
UIWidgets::Tooltip("Adjust the number of notes the skull kids play to start the first round");
|
||||
int roundMin = CVarGetInteger("gOcarinaGameStartingNotes", 3);
|
||||
UIWidgets::PaddedEnhancementSliderInt("Round One Notes: %d", "##OcarinaGameRoundOne",
|
||||
"gOcarinaGameRoundOneNotes", roundMin, 8, "", 5, true, true,
|
||||
false,
|
||||
disabled, disabledTooltip);
|
||||
UIWidgets::Tooltip("Adjust the number of notes you need to play to end the first round");
|
||||
UIWidgets::PaddedEnhancementSliderInt("Round Two Notes: %d", "##OcarinaGameRoundTwoNotes",
|
||||
"gOcarinaGameRoundTwoNotes", roundMin, 8, "", 6, true, true,
|
||||
false,
|
||||
disabled, disabledTooltip);
|
||||
UIWidgets::Tooltip("Adjust the number of notes you need to play to end the second round");
|
||||
UIWidgets::PaddedEnhancementSliderInt("Round Three Notes: %d", "##OcarinaGameRoundThreeNotes",
|
||||
"gOcarinaGameRoundThreeNotes", roundMin, 8, "", 8, true, true,
|
||||
false,
|
||||
disabled, disabledTooltip);
|
||||
UIWidgets::Tooltip("Adjust the number of notes you need to play to end the third round");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
|
||||
@ -1046,6 +1105,15 @@ void DrawEnhancementsMenu() {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Kokiri Draw Distance", "gDisableKokiriDrawDistance", true, false);
|
||||
UIWidgets::Tooltip("The Kokiri are mystical beings that fade into view when approached\nEnabling this will remove their draw distance");
|
||||
}
|
||||
if (UIWidgets::PaddedEnhancementCheckbox("Show Age-Dependent Equipment", "gEnhancements.EquimentAlwaysVisible", true,
|
||||
false)) {
|
||||
UpdatePatchHand();
|
||||
}
|
||||
UIWidgets::Tooltip("Makes all equipment visible, regardless of Age.");
|
||||
if (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0) == 1) {
|
||||
UIWidgets::PaddedEnhancementCheckbox("Scale Adult Equipment as Child", "gEnhancements.ScaleAdultEquimentAsChild", true, false);
|
||||
UIWidgets::Tooltip("Scales all of the Adult Equipment, as well and moving some a bit, to fit on Child Link Better. May not work properly with some mods.");
|
||||
}
|
||||
UIWidgets::PaddedEnhancementCheckbox("N64 Mode", "gLowResMode", true, false);
|
||||
UIWidgets::Tooltip("Sets aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Glitch line-up tick", "gDrawLineupTick", true, false);
|
||||
@ -1064,6 +1132,7 @@ void DrawEnhancementsMenu() {
|
||||
PatchToTMedallions();
|
||||
}
|
||||
UIWidgets::Tooltip("When medallions are collected, the medallion imprints around the Master Sword pedestal in the Temple of Time will become colored");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Show locked door chains on both sides of locked doors", "gShowDoorLocksOnBothSides", true, false);
|
||||
UIWidgets::PaddedText("Fix Vanishing Paths", true, false);
|
||||
if (UIWidgets::EnhancementCombobox("gSceneSpecificDirtPathFix", zFightingOptions, ZFIGHT_FIX_DISABLED) && gPlayState != NULL) {
|
||||
UpdateDirtPathFixState(gPlayState->sceneNum);
|
||||
@ -1257,6 +1326,14 @@ void DrawEnhancementsMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
if (UIWidgets::PaddedEnhancementCheckbox("Hurt Container Mode", "gHurtContainer", true, false)) {
|
||||
UpdateHurtContainerModeState(CVarGetInteger("gHurtContainer", 0));
|
||||
}
|
||||
UIWidgets::Tooltip("Changes Heart Piece and Heart Container functionality.\n\n"
|
||||
"- Each Heart Container or full Heart Piece reduces Links hearts by 1.\n"
|
||||
"- Can be enabled retroactively after a File has already started.");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
@ -449,7 +449,7 @@ namespace UIWidgets {
|
||||
|
||||
if (changed && !(abs(oldVal - val) < 0.000001f)) {
|
||||
std::stringstream ss;
|
||||
ss << std::setprecision(ticks) << val;
|
||||
ss << std::setprecision(ticks + 1) << val;
|
||||
val = std::stof(ss.str());
|
||||
CVarSetFloat(cvarName, val);
|
||||
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
|
||||
|
@ -182,4 +182,9 @@ extern "C" void OTRMessage_Init()
|
||||
CustomMessage("You look bored. Wanna go out for a&walk?\x1B&%gYes&No%w",
|
||||
"Du siehst gelangweilt aus.&Willst du einen Spaziergang machen?\x1B&%gJa&Nein%w",
|
||||
"Tu as l'air de t'ennuyer. Tu veux&aller faire un tour?\x1B&%gOui&Non%w"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_FISHERMAN_LEAVE,
|
||||
CustomMessage("Hey! Hey!&You can't take the rod out of here!&I'm serious!^Do you want to quit?&\x1B&%gYes&No%w",
|
||||
"Hey! Hey!&Du kannst die Angel doch nicht&einfach mitnehmen!&Ganz im Ernst!^Möchtest du aufhören?&\x1B&%gJa&Nein%w", //TODO Used AI translation as placeholder
|
||||
"Holà! Holà!&Les cannes ne sortent pas d'ici!&Je suis sérieux!^Voulez-vous arrêter?&\x1B&%gOui&Non%w")); //TODO Used AI translation as placeholder
|
||||
}
|
||||
|
@ -149,6 +149,13 @@ bool Scene_CommandMeshHeader(PlayState* play, LUS::ISceneCommand* cmd) {
|
||||
|
||||
extern "C" void* func_800982FC(ObjectContext* objectCtx, s32 bankIndex, s16 objectId);
|
||||
|
||||
bool OTRfunc_800982FC(ObjectContext* objectCtx, s32 bankIndex, s16 objectId) {
|
||||
|
||||
objectCtx->status[bankIndex].id = -objectId;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Scene_CommandObjectList(PlayState* play, LUS::ISceneCommand* cmd) {
|
||||
// LUS::SetObjectList* cmdObj = static_pointer_cast<LUS::SetObjectList>(cmd);
|
||||
LUS::SetObjectList* cmdObj = (LUS::SetObjectList*)cmd;
|
||||
@ -164,49 +171,30 @@ bool Scene_CommandObjectList(PlayState* play, LUS::ISceneCommand* cmd) {
|
||||
void* nextPtr;
|
||||
|
||||
k = 0;
|
||||
// i = play->objectCtx.unk_09;
|
||||
i = 0;
|
||||
i = play->objectCtx.unk_09;
|
||||
firstStatus = &play->objectCtx.status[0];
|
||||
status = &play->objectCtx.status[i];
|
||||
|
||||
for (int i = 0; i < cmdObj->objects.size(); i++) {
|
||||
bool alreadyIncluded = false;
|
||||
|
||||
for (int j = 0; j < play->objectCtx.num; j++) {
|
||||
if (play->objectCtx.status[j].id == cmdObj->objects[i]) {
|
||||
alreadyIncluded = true;
|
||||
break;
|
||||
// Loop until a mismatch in the object lists
|
||||
// Then clear all object ids past that in the context object list and kill actors for those objects
|
||||
for (i = play->objectCtx.unk_09, k = 0; i < play->objectCtx.num; i++, k++) {
|
||||
if (play->objectCtx.status[i].id != cmdObj->objects[k]) {
|
||||
for (j = i; j < play->objectCtx.num; j++) {
|
||||
play->objectCtx.status[j].id = OBJECT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyIncluded) {
|
||||
play->objectCtx.status[play->objectCtx.num++].id = cmdObj->objects[i];
|
||||
func_80031A28(play, &play->actorCtx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
while (i < play->objectCtx.num) {
|
||||
if (status->id != *objectEntry) {
|
||||
status2 = &play->objectCtx.status[i];
|
||||
for (j = i; j < play->objectCtx.num; j++) {
|
||||
status2->id = OBJECT_INVALID;
|
||||
status2++;
|
||||
}
|
||||
play->objectCtx.num = i;
|
||||
func_80031A28(play, &play->actorCtx);
|
||||
|
||||
continue;
|
||||
// Continuing from the last index, add the remaining object ids from the command object list
|
||||
for (; k < cmdObj->objects.size(); k++, i++) {
|
||||
if (i < OBJECT_EXCHANGE_BANK_MAX - 1) {
|
||||
OTRfunc_800982FC(&play->objectCtx, i, cmdObj->objects[k]);
|
||||
}
|
||||
|
||||
i++;
|
||||
k++;
|
||||
objectEntry++;
|
||||
status++;
|
||||
}
|
||||
|
||||
play->objectCtx.num = i;
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2066,15 +2066,39 @@ void func_800EE404(void) {
|
||||
void Audio_OcaMemoryGameStart(u8 minigameRound) {
|
||||
u8 i;
|
||||
|
||||
if (minigameRound > 2) {
|
||||
minigameRound = 2;
|
||||
}
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gCustomizeOcarinaGame", 0)) {
|
||||
u8 startingNotes = 3;
|
||||
u8 roundOneCount = CVarGetInteger("gOcarinaGameRoundOneNotes", 5);
|
||||
u8 roundTwoCount = CVarGetInteger("gOcarinaGameRoundTwoNotes", 6);
|
||||
u8 roundThreeCount = CVarGetInteger("gOcarinaGameRoundThreeNotes", 8);
|
||||
u8 modMinigameNoteCnts[] = { roundOneCount, roundTwoCount, roundThreeCount };
|
||||
|
||||
sOcaMinigameAppendPos = 0;
|
||||
sOcaMinigameEndPos = sOcaMinigameNoteCnts[minigameRound];
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
Audio_OcaMemoryGameGenNote();
|
||||
startingNotes = CVarGetInteger("gOcarinaGameStartingNotes", 3);
|
||||
|
||||
if (minigameRound > 2) {
|
||||
minigameRound = 2;
|
||||
}
|
||||
|
||||
sOcaMinigameAppendPos = 0;
|
||||
sOcaMinigameEndPos = modMinigameNoteCnts[minigameRound];
|
||||
|
||||
for (i = 0; i < startingNotes; i++) {
|
||||
Audio_OcaMemoryGameGenNote();
|
||||
}
|
||||
// #endregion
|
||||
} else {
|
||||
if (minigameRound > 2) {
|
||||
minigameRound = 2;
|
||||
}
|
||||
|
||||
sOcaMinigameAppendPos = 0;
|
||||
sOcaMinigameEndPos = sOcaMinigameNoteCnts[minigameRound];
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
Audio_OcaMemoryGameGenNote();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2093,11 +2117,24 @@ s32 Audio_OcaMemoryGameGenNote(void) {
|
||||
rndNote = sOcarinaNoteValues[(rnd + 1) % 5];
|
||||
}
|
||||
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].noteIdx = rndNote;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].unk_02 = 0x2D;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].volume = 0x50;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].vibrato = 0;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].tone = 0;
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gCustomizeOcarinaGame", 0)) {
|
||||
int noteSpeed = 0x2D;
|
||||
noteSpeed = noteSpeed / CVarGetInteger("gOcarinaGameNoteSpeed", 1);
|
||||
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].noteIdx = rndNote;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].unk_02 = noteSpeed;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].volume = 0x50;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].vibrato = 0;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].tone = 0;
|
||||
// #endregion
|
||||
} else {
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].noteIdx = rndNote;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].unk_02 = 0x2D;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].volume = 0x50;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].vibrato = 0;
|
||||
sOcarinaSongs[OCARINA_SONG_MEMORY_GAME][sOcaMinigameAppendPos].tone = 0;
|
||||
}
|
||||
|
||||
sOcaMinigameAppendPos++;
|
||||
|
||||
|
@ -1239,8 +1239,7 @@ void Actor_Init(Actor* actor, PlayState* play) {
|
||||
CollisionCheck_InitInfo(&actor->colChkInfo);
|
||||
actor->floorBgId = BGCHECK_SCENE;
|
||||
ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f);
|
||||
//if (Object_IsLoaded(&play->objectCtx, actor->objBankIndex))
|
||||
{
|
||||
if (Object_IsLoaded(&play->objectCtx, actor->objBankIndex)) {
|
||||
//Actor_SetObjectDependency(play, actor);
|
||||
actor->init(actor, play);
|
||||
actor->init = NULL;
|
||||
@ -2881,11 +2880,19 @@ s32 func_800314D4(PlayState* play, Actor* actor, Vec3f* arg2, f32 arg3) {
|
||||
if ((arg2->z > -actor->uncullZoneScale) && (arg2->z < (actor->uncullZoneForward + actor->uncullZoneScale))) {
|
||||
var = (arg3 < 1.0f) ? 1.0f : 1.0f / arg3;
|
||||
|
||||
if ((((fabsf(arg2->x) - actor->uncullZoneScale) * var) < 2.0f) &&
|
||||
(((arg2->y + actor->uncullZoneDownward) * var) > -2.0f) &&
|
||||
(((arg2->y - actor->uncullZoneScale) * var) < 2.0f)) {
|
||||
// #region SoH [Widescreen support]
|
||||
// Doors will cull quite noticeably on wider screens. For these actors the zone is increased
|
||||
f32 limit = 1.0f;
|
||||
if (((actor->id == ACTOR_EN_DOOR) || (actor->id == ACTOR_DOOR_SHUTTER)) && CVarGetInteger("gIncreaseDoorUncullZones", 1)) {
|
||||
limit = 2.0f;
|
||||
}
|
||||
|
||||
if ((((fabsf(arg2->x) - actor->uncullZoneScale) * var) < limit) &&
|
||||
(((arg2->y + actor->uncullZoneDownward) * var) > -limit) &&
|
||||
(((arg2->y - actor->uncullZoneScale) * var) < limit)) {
|
||||
return true;
|
||||
}
|
||||
// #endregion
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -3149,6 +3156,9 @@ void Actor_FreeOverlay(ActorDBEntry* dbEntry) {
|
||||
osSyncPrintf(VT_RST);
|
||||
}
|
||||
|
||||
// SoH: Flag to check if actors are being spawned from the actor entry list
|
||||
// This flag is checked against to allow actors which dont have an objectBankIndex in the objectCtx slot/status array to spawn
|
||||
// An example of what this fixes, is that it allows hookshot to be used as child
|
||||
int gMapLoading = 0;
|
||||
|
||||
Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 posX, f32 posY, f32 posZ,
|
||||
|
@ -1902,7 +1902,7 @@ s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResul
|
||||
s32 bgId2;
|
||||
f32 nx, ny, nz; // unit normal of polygon
|
||||
|
||||
if (CVarGetInteger("gNoClip", 0) != 0) {
|
||||
if (CVarGetInteger("gNoClip", 0) && actor != NULL && actor->id == ACTOR_PLAYER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -7887,7 +7887,7 @@ s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags) {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear free camera if an action is performed that would move the camera (targeting, first person, talking)
|
||||
// Clear free look if an action is performed that would move the camera (targeting, first person, talking)
|
||||
if (CVarGetInteger("gFreeCamera", 0) && SetCameraManual(camera) == 1 &&
|
||||
((mode >= CAM_MODE_TARGET && mode <= CAM_MODE_BATTLE) ||
|
||||
(mode >= CAM_MODE_FIRSTPERSON && mode <= CAM_MODE_CLIMBZ) || mode == CAM_MODE_HANGZ ||
|
||||
|
@ -524,7 +524,6 @@ void Map_Init(PlayState* play) {
|
||||
interfaceCtx->unk_25A = -1;
|
||||
|
||||
interfaceCtx->mapSegment = GAMESTATE_ALLOC_MC(&play->state, 2 * sizeof(char*));
|
||||
interfaceCtx->mapSegmentName = GAMESTATE_ALLOC_MC(&play->state, 2 * sizeof(char*));
|
||||
// "MAP texture initialization scene_data_ID=%d mapSegment=%x"
|
||||
osSyncPrintf("\n\n\nMAP テクスチャ初期化 scene_data_ID=%d\nmapSegment=%x\n\n", play->sceneNum,
|
||||
interfaceCtx->mapSegment, play);
|
||||
|
@ -3361,8 +3361,13 @@ void Message_Update(PlayState* play) {
|
||||
}
|
||||
if ((s32)(gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000) {
|
||||
gSaveContext.inventory.questItems ^= 0x40000000;
|
||||
gSaveContext.healthCapacity += 0x10;
|
||||
gSaveContext.health += 0x10;
|
||||
if (!CVarGetInteger("gHurtContainer", 0)) {
|
||||
gSaveContext.healthCapacity += 0x10;
|
||||
gSaveContext.health += 0x10;
|
||||
} else {
|
||||
gSaveContext.healthCapacity -= 0x10;
|
||||
gSaveContext.health -= 0x10;
|
||||
}
|
||||
}
|
||||
if (msgCtx->ocarinaAction != OCARINA_ACTION_CHECK_NOWARP_DONE) {
|
||||
if (sLastPlayedSong == OCARINA_SONG_SARIAS) {
|
||||
|
@ -70,6 +70,12 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
|
||||
f32 tempRand;
|
||||
Unique9OnePointCs* csInfo = ONEPOINT_CS_INFO(csCam);
|
||||
|
||||
// #region SOH [Enhancement]
|
||||
//the default is 90, lower values necessary to prevent camera swing as animation speeds up
|
||||
s16 camCrawlTemp = CVarGetInteger("gCrawlSpeed", 1);
|
||||
s16 camCrawlTimer = D_8012042C / camCrawlTemp;
|
||||
// #endregion
|
||||
|
||||
switch (csId) {
|
||||
case 1020:
|
||||
if (timer < 20) {
|
||||
@ -330,13 +336,26 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
|
||||
case 9601:
|
||||
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
|
||||
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
|
||||
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120398);
|
||||
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
||||
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120398);
|
||||
} else {
|
||||
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120398);
|
||||
}
|
||||
break;
|
||||
case 9602:
|
||||
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
|
||||
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
|
||||
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120434);
|
||||
break;
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
||||
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
|
||||
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
|
||||
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120434);
|
||||
break;
|
||||
// #endregion
|
||||
} else {
|
||||
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
|
||||
Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting);
|
||||
OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120434);
|
||||
break;
|
||||
}
|
||||
case 4175:
|
||||
csInfo->keyFrames = D_8012147C;
|
||||
csInfo->keyFrameCnt = 4;
|
||||
|
@ -2278,8 +2278,13 @@ u8 Item_Give(PlayState* play, u8 item) {
|
||||
gSaveContext.sohStats.heartPieces++;
|
||||
return Return_Item(item, MOD_NONE, ITEM_NONE);
|
||||
} else if (item == ITEM_HEART_CONTAINER) {
|
||||
gSaveContext.healthCapacity += 0x10;
|
||||
gSaveContext.health += 0x10;
|
||||
if (!CVarGetInteger("gHurtContainer", 0)) {
|
||||
gSaveContext.healthCapacity += 0x10;
|
||||
gSaveContext.health += 0x10;
|
||||
} else {
|
||||
gSaveContext.healthCapacity -= 0x10;
|
||||
gSaveContext.health -= 0x10;
|
||||
}
|
||||
gSaveContext.sohStats.heartContainers++;
|
||||
return Return_Item(item, MOD_NONE, ITEM_NONE);
|
||||
} else if (item == ITEM_HEART) {
|
||||
|
@ -600,13 +600,23 @@ void Player_SetModelsForHoldingShield(Player* this) {
|
||||
if ((CVarGetInteger("gShieldTwoHanded", 0) && (this->heldItemAction != PLAYER_IA_DEKU_STICK) ||
|
||||
!Player_HoldsTwoHandedWeapon(this)) && !Player_IsChildWithHylianShield(this)) {
|
||||
this->rightHandType = PLAYER_MODELTYPE_RH_SHIELD;
|
||||
this->rightHandDLists = &sPlayerDListGroups[PLAYER_MODELTYPE_RH_SHIELD][gSaveContext.linkAge];
|
||||
if (LINK_IS_CHILD && (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) && (this->currentShield == PLAYER_SHIELD_MIRROR)) {
|
||||
this->rightHandDLists = &sPlayerDListGroups[PLAYER_MODELTYPE_RH_SHIELD][0];
|
||||
} else if (LINK_IS_ADULT && (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) && (this->currentShield == PLAYER_SHIELD_DEKU)) {
|
||||
this->rightHandDLists = &sPlayerDListGroups[PLAYER_MODELTYPE_RH_SHIELD][1];
|
||||
} else {
|
||||
this->rightHandDLists = &sPlayerDListGroups[PLAYER_MODELTYPE_RH_SHIELD][gSaveContext.linkAge];
|
||||
}
|
||||
if (this->sheathType == PLAYER_MODELTYPE_SHEATH_18) {
|
||||
this->sheathType = PLAYER_MODELTYPE_SHEATH_16;
|
||||
} else if (this->sheathType == PLAYER_MODELTYPE_SHEATH_19) {
|
||||
this->sheathType = PLAYER_MODELTYPE_SHEATH_17;
|
||||
}
|
||||
this->sheathDLists = &sPlayerDListGroups[this->sheathType][gSaveContext.linkAge];
|
||||
if ((CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) && LINK_IS_CHILD &&
|
||||
gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI) {
|
||||
this->sheathDLists = &sPlayerDListGroups[this->sheathType][0];
|
||||
}
|
||||
this->modelAnimType = PLAYER_ANIMTYPE_2;
|
||||
this->itemAction = -1;
|
||||
}
|
||||
@ -618,11 +628,39 @@ void Player_SetModels(Player* this, s32 modelGroup) {
|
||||
this->leftHandType = gPlayerModelTypes[modelGroup][PLAYER_MODELGROUPENTRY_LEFT_HAND];
|
||||
this->leftHandDLists = &sPlayerDListGroups[this->leftHandType][gSaveContext.linkAge];
|
||||
|
||||
if (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) {
|
||||
if (LINK_IS_CHILD &&
|
||||
(this->leftHandType == PLAYER_MODELTYPE_LH_HAMMER ||
|
||||
((this->leftHandType == PLAYER_MODELTYPE_LH_SWORD || this->leftHandType == PLAYER_MODELTYPE_LH_BGS) &&
|
||||
(gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI)))) {
|
||||
this->leftHandDLists = &sPlayerDListGroups[this->leftHandType][0];
|
||||
}
|
||||
|
||||
if (LINK_IS_ADULT && (this->leftHandType == PLAYER_MODELTYPE_LH_BOOMERANG ||
|
||||
(this->leftHandType == PLAYER_MODELTYPE_LH_SWORD && gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KOKIRI))) {
|
||||
this->leftHandDLists = &sPlayerDListGroups[this->leftHandType][1];
|
||||
}
|
||||
}
|
||||
|
||||
// Right hand
|
||||
this->rightHandType = gPlayerModelTypes[modelGroup][PLAYER_MODELGROUPENTRY_RIGHT_HAND];
|
||||
this->rightHandDLists = &sPlayerDListGroups[this->rightHandType][gSaveContext.linkAge];
|
||||
|
||||
if (CVarGetInteger("gBowSlingShotAmmoFix", 0) && this->rightHandType == 11) { // If holding Bow/Slingshot
|
||||
this->rightHandType = gPlayerModelTypes[modelGroup][PLAYER_MODELGROUPENTRY_RIGHT_HAND];
|
||||
this->rightHandDLists = &sPlayerDListGroups[this->rightHandType][gSaveContext.linkAge];
|
||||
|
||||
if (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) {
|
||||
if (LINK_IS_CHILD &&
|
||||
(this->rightHandType == PLAYER_MODELTYPE_RH_HOOKSHOT ||
|
||||
(this->rightHandType == PLAYER_MODELTYPE_RH_SHIELD && this->currentShield == PLAYER_SHIELD_MIRROR))) {
|
||||
this->rightHandDLists = &sPlayerDListGroups[this->rightHandType][0];
|
||||
}
|
||||
if (LINK_IS_ADULT &&
|
||||
(this->rightHandType == PLAYER_MODELTYPE_RH_SHIELD && this->currentShield == PLAYER_SHIELD_DEKU)) {
|
||||
this->rightHandDLists = &sPlayerDListGroups[this->rightHandType][1];
|
||||
}
|
||||
}
|
||||
if ((CVarGetInteger("gBowSlingShotAmmoFix", 0) || CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) && this->rightHandType == 11) { // If holding Bow/Slingshot
|
||||
this->rightHandDLists = &sPlayerDListGroups[this->rightHandType][Player_HoldsSlingshot(this)];
|
||||
}
|
||||
|
||||
@ -630,6 +668,23 @@ void Player_SetModels(Player* this, s32 modelGroup) {
|
||||
this->sheathType = gPlayerModelTypes[modelGroup][PLAYER_MODELGROUPENTRY_SHEATH];
|
||||
this->sheathDLists = &sPlayerDListGroups[this->sheathType][gSaveContext.linkAge];
|
||||
|
||||
if (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) {
|
||||
if (LINK_IS_CHILD &&
|
||||
(this->currentShield == PLAYER_SHIELD_HYLIAN || this->currentShield == PLAYER_SHIELD_MIRROR) &&
|
||||
((gSaveContext.equips.buttonItems[0] == ITEM_SWORD_MASTER) ||
|
||||
(gSaveContext.equips.buttonItems[0] == ITEM_SWORD_BGS))) {
|
||||
this->sheathDLists = &sPlayerDListGroups[this->sheathType][0];
|
||||
} else if (LINK_IS_CHILD && this->currentShield == PLAYER_SHIELD_MIRROR && gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KOKIRI &&
|
||||
this->sheathType == PLAYER_MODELTYPE_SHEATH_18) {
|
||||
this->sheathDLists = &sPlayerDListGroups[this->sheathType][0];
|
||||
} else if (LINK_IS_ADULT && this->currentShield == PLAYER_SHIELD_DEKU) {
|
||||
this->sheathDLists = &sPlayerDListGroups[this->sheathType][1];
|
||||
} else if (LINK_IS_CHILD && this->sheathType == PLAYER_MODELTYPE_SHEATH_17 &&
|
||||
((gSaveContext.equips.buttonItems[0] == ITEM_SWORD_MASTER) || (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_BGS))) {
|
||||
this->sheathDLists = &sPlayerDListGroups[this->sheathType][0];
|
||||
}
|
||||
}
|
||||
|
||||
// Waist
|
||||
this->waistDLists = &sPlayerDListGroups[gPlayerModelTypes[modelGroup][4]][gSaveContext.linkAge];
|
||||
|
||||
@ -1188,6 +1243,42 @@ void func_8008F87C(PlayState* play, Player* this, SkelAnime* skelAnime, Vec3f* p
|
||||
s32 Player_OverrideLimbDrawGameplayCommon(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
|
||||
Player* this = (Player*)thisx;
|
||||
|
||||
if (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0) && CVarGetInteger("gEnhancements.ScaleAdultEquimentAsChild", 0) && LINK_IS_CHILD) {
|
||||
if (limbIndex == PLAYER_LIMB_L_HAND) {
|
||||
if ((gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI && sLeftHandType == PLAYER_MODELTYPE_LH_SWORD) ||
|
||||
(sLeftHandType == PLAYER_MODELTYPE_LH_BGS) || (sLeftHandType == PLAYER_MODELTYPE_LH_HAMMER)) {
|
||||
Matrix_Scale(0.8, 0.8, 0.8, MTXMODE_APPLY);
|
||||
}
|
||||
}
|
||||
if (limbIndex == PLAYER_LIMB_R_HAND) {
|
||||
if ((this->currentShield == PLAYER_SHIELD_MIRROR && sRightHandType == PLAYER_MODELTYPE_RH_SHIELD) ||
|
||||
(this->currentShield == PLAYER_SHIELD_HYLIAN && (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_MASTER ||
|
||||
gSaveContext.equips.buttonItems[0] == ITEM_SWORD_BGS)) || (sRightHandType == PLAYER_MODELTYPE_RH_HOOKSHOT) ||
|
||||
(sRightHandType == PLAYER_MODELTYPE_RH_BOW_SLINGSHOT && Player_HoldsBow(this))) {
|
||||
Matrix_Scale(0.8, 0.8, 0.8, MTXMODE_APPLY);
|
||||
}
|
||||
}
|
||||
if (limbIndex == PLAYER_LIMB_SHEATH) {
|
||||
if ((this->currentShield == PLAYER_SHIELD_MIRROR ||
|
||||
(this->currentShield == PLAYER_SHIELD_HYLIAN &&
|
||||
(gSaveContext.equips.buttonItems[0] == ITEM_SWORD_MASTER ||
|
||||
gSaveContext.equips.buttonItems[0] == ITEM_SWORD_BGS))) &&
|
||||
((this->sheathType == PLAYER_MODELTYPE_SHEATH_16) || (this->sheathType == PLAYER_MODELTYPE_SHEATH_17) ||
|
||||
(this->sheathType == PLAYER_MODELTYPE_SHEATH_18) ||
|
||||
(this->sheathType == PLAYER_MODELTYPE_SHEATH_19))) {
|
||||
Matrix_Translate(218, -100, 62, MTXMODE_APPLY);
|
||||
Matrix_Scale(0.8, 0.8, 0.8, MTXMODE_APPLY);
|
||||
}
|
||||
if ((this->currentShield == PLAYER_SHIELD_DEKU &&
|
||||
gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI &&
|
||||
(this->sheathType == PLAYER_MODELTYPE_SHEATH_16 ||
|
||||
this->sheathType == PLAYER_MODELTYPE_SHEATH_17))) {
|
||||
Matrix_Translate(218, -100, 62, MTXMODE_APPLY);
|
||||
Matrix_Scale(0.8, 0.8, 0.8, MTXMODE_APPLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (limbIndex == PLAYER_LIMB_ROOT) {
|
||||
sLeftHandType = this->leftHandType;
|
||||
sRightHandType = this->rightHandType;
|
||||
@ -1305,9 +1396,11 @@ s32 Player_OverrideLimbDrawGameplayDefault(PlayState* play, s32 limbIndex, Gfx**
|
||||
(gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI)) {
|
||||
dLists += PLAYER_SHIELD_MAX * 4;
|
||||
}
|
||||
} else if (!LINK_IS_ADULT && ((this->sheathType == PLAYER_MODELTYPE_SHEATH_16) || (this->sheathType == PLAYER_MODELTYPE_SHEATH_17)) &&
|
||||
(gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI)) {
|
||||
dLists = &sSheathWithSwordDLs[PLAYER_SHIELD_MAX * 4];
|
||||
} else if (!CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) {
|
||||
if (!LINK_IS_ADULT && ((this->sheathType == PLAYER_MODELTYPE_SHEATH_16) || (this->sheathType == PLAYER_MODELTYPE_SHEATH_17)) &&
|
||||
(gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KOKIRI)) {
|
||||
dLists = &sSheathWithSwordDLs[PLAYER_SHIELD_MAX * 4];
|
||||
}
|
||||
}
|
||||
|
||||
if (dLists[sDListsLodOffset] != NULL) {
|
||||
@ -1345,7 +1438,7 @@ s32 Player_OverrideLimbDrawGameplayFirstPerson(PlayState* play, s32 limbIndex, G
|
||||
*dList = sFirstPersonLeftForearmDLs[gSaveContext.linkAge];
|
||||
} else if (limbIndex == PLAYER_LIMB_L_HAND) {
|
||||
s32 handOutDlIndex = gSaveContext.linkAge;
|
||||
if (CVarGetInteger("gBowSlingShotAmmoFix", 0) && LINK_IS_ADULT && Player_HoldsSlingshot(this)) {
|
||||
if ((CVarGetInteger("gBowSlingShotAmmoFix", 0) || CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) && LINK_IS_ADULT && Player_HoldsSlingshot(this)) {
|
||||
handOutDlIndex = 1;
|
||||
}
|
||||
*dList = sFirstPersonLeftHandDLs[handOutDlIndex];
|
||||
@ -1355,7 +1448,7 @@ s32 Player_OverrideLimbDrawGameplayFirstPerson(PlayState* play, s32 limbIndex, G
|
||||
*dList = sFirstPersonForearmDLs[gSaveContext.linkAge];
|
||||
} else if (limbIndex == PLAYER_LIMB_R_HAND) {
|
||||
s32 firstPersonWeaponIndex = gSaveContext.linkAge;
|
||||
if (CVarGetInteger("gBowSlingShotAmmoFix", 0)) {
|
||||
if (CVarGetInteger("gBowSlingShotAmmoFix", 0) || CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) {
|
||||
if (Player_HoldsBow(this)) {
|
||||
firstPersonWeaponIndex = 0;
|
||||
} else if (Player_HoldsSlingshot(this)) {
|
||||
@ -1755,7 +1848,7 @@ void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList, Ve
|
||||
Matrix_Get(&this->shieldMf);
|
||||
} else if ((this->rightHandType == PLAYER_MODELTYPE_RH_BOW_SLINGSHOT) || (this->rightHandType == PLAYER_MODELTYPE_RH_BOW_SLINGSHOT_2)) {
|
||||
s32 stringModelToUse = gSaveContext.linkAge;
|
||||
if(CVarGetInteger("gBowSlingShotAmmoFix", 0)){
|
||||
if (CVarGetInteger("gBowSlingShotAmmoFix", 0) || CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) {
|
||||
stringModelToUse = Player_HoldsSlingshot(this);
|
||||
}
|
||||
BowStringData* stringData = &sBowStringData[stringModelToUse];
|
||||
|
@ -83,9 +83,10 @@ void Object_UpdateBank(ObjectContext* objectCtx) {
|
||||
RomFile* objectFile;
|
||||
size_t size;
|
||||
|
||||
/*
|
||||
|
||||
for (i = 0; i < objectCtx->num; i++) {
|
||||
if (status->id < 0) {
|
||||
/*
|
||||
if (status->dmaRequest.vromAddr == 0) {
|
||||
osCreateMesgQueue(&status->loadQueue, &status->loadMsg, 1);
|
||||
objectFile = &gObjectTable[-status->id];
|
||||
@ -96,10 +97,12 @@ void Object_UpdateBank(ObjectContext* objectCtx) {
|
||||
} else if (!osRecvMesg(&status->loadQueue, NULL, OS_MESG_NOBLOCK)) {
|
||||
status->id = -status->id;
|
||||
}
|
||||
*/
|
||||
status->id = -status->id;
|
||||
}
|
||||
status++;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
s32 Object_GetIndex(ObjectContext* objectCtx, s16 objectId) {
|
||||
|
@ -10,10 +10,6 @@
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memcpy
|
||||
|
||||
// OTRTODO: Replace usage of this method when we can clear the cache
|
||||
// for a single texture without the need of a DL opcode in the render code
|
||||
void gfx_texture_cache_clear();
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
|
||||
|
||||
#define LAVA_TEX_WIDTH 32
|
||||
@ -123,7 +119,9 @@ void BossDodongo_RegisterBlendedLavaTextureUpdate() {
|
||||
sMaskTexLava[i] = maskVal;
|
||||
}
|
||||
}
|
||||
|
||||
Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, NULL);
|
||||
Gfx_TextureCacheDelete(sMaskTexLava);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -165,7 +163,9 @@ void BossDodongo_RegisterBlendedLavaTextureUpdate() {
|
||||
}
|
||||
}
|
||||
|
||||
gfx_texture_cache_clear();
|
||||
Gfx_TextureCacheDelete(sMaskTexLava);
|
||||
Gfx_TextureCacheDelete(sLavaWavyTex);
|
||||
Gfx_TextureCacheDelete(sLavaFloorModifiedTex);
|
||||
}
|
||||
|
||||
void func_808C12C4(u8* arg1, s16 arg2) {
|
||||
@ -228,6 +228,7 @@ void func_808C1554_Raw(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
|
||||
}
|
||||
|
||||
free(sp54);
|
||||
Gfx_TextureCacheDelete(sLavaWavyTexRaw);
|
||||
}
|
||||
|
||||
// Modified to support CPU modified texture with the resource system
|
||||
@ -255,6 +256,8 @@ void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
|
||||
temp_s3[i + temp2] = sp54[i + i2];
|
||||
}
|
||||
}
|
||||
|
||||
Gfx_TextureCacheDelete(sLavaWavyTex);
|
||||
}
|
||||
|
||||
void func_808C17C8(PlayState* play, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, s16 arg5) {
|
||||
@ -373,6 +376,13 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
|
||||
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016990, sMaskTex32x16, NULL);
|
||||
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016E10, sMaskTex32x16, NULL);
|
||||
|
||||
// Clear cache for masks
|
||||
Gfx_TextureCacheDelete(sMaskTex8x16);
|
||||
Gfx_TextureCacheDelete(sMaskTex8x32);
|
||||
Gfx_TextureCacheDelete(sMaskTex16x16);
|
||||
Gfx_TextureCacheDelete(sMaskTex16x32);
|
||||
Gfx_TextureCacheDelete(sMaskTex32x16);
|
||||
|
||||
BossDodongo_RegisterBlendedLavaTextureUpdate();
|
||||
|
||||
// Register alt listener to update the blended lava for the replacement texture based on alt path
|
||||
@ -1206,6 +1216,7 @@ void BossDodongo_Update(Actor* thisx, PlayState* play2) {
|
||||
}
|
||||
} else {
|
||||
sMaskTexLava[new_var] = 1;
|
||||
Gfx_TextureCacheDelete(sMaskTexLava);
|
||||
}
|
||||
|
||||
this->unk_1C2 += 37;
|
||||
@ -1345,18 +1356,6 @@ void BossDodongo_Draw(Actor* thisx, PlayState* play) {
|
||||
gSPInvalidateTexCache(POLY_OPA_DISP++, sMaskTex32x16);
|
||||
}
|
||||
|
||||
gSPInvalidateTexCache(POLY_OPA_DISP++, sMaskTexLava);
|
||||
|
||||
// Using WORK_DISP to invalidate these textures as they are used in drawing the scene textures which happens
|
||||
// before actors are drawn. WORK_DISP comes before POLAY_OPA_DISP. It is probably not meant for this, but it
|
||||
// at least works for now.
|
||||
// Alternatively, having a way to invalidate just these pointers from the Update func should be sufficient.
|
||||
if (sLavaFloorModifiedTexRaw != NULL) {
|
||||
gSPInvalidateTexCache(WORK_DISP++, sLavaWavyTexRaw);
|
||||
} else {
|
||||
gSPInvalidateTexCache(WORK_DISP++, sLavaWavyTex);
|
||||
}
|
||||
|
||||
if ((this->unk_1C0 >= 2) && (this->unk_1C0 & 1)) {
|
||||
POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 255, 255, 0, 900, 1099);
|
||||
} else {
|
||||
|
@ -192,11 +192,11 @@ void DemoGj_Explode(DemoGj* this, PlayState* play, Vec3f* initialPos, Vec3f* dir
|
||||
phi_s0 = 0x21;
|
||||
}
|
||||
|
||||
Gfx* gfx = ResourceMgr_LoadGfxByName(gGanonRubbleDL);
|
||||
|
||||
// SoH [Port] Changed from &gGanonsCastleRubbleAroundArenaDL[28] to gGanonRubbleDL as it seems this was an error in the original rom/decomp
|
||||
// Other calls to EffectSsKakera_Spawn with OBJECT_GEFF use gGanonRubbleDL, so this change is to match that
|
||||
EffectSsKakera_Spawn(play, &explosionPos, &velocity, initialPos, -200, phi_s0, 10, 10, 0,
|
||||
Rand_ZeroOne() * 20.0f + 20.0f, 20, 300, (s32)(Rand_ZeroOne() * 30.0f) + 30, -1,
|
||||
OBJECT_GEFF, gfx);
|
||||
OBJECT_GEFF, gGanonRubbleDL);
|
||||
|
||||
theta += 0x2AAA;
|
||||
}
|
||||
|
@ -101,6 +101,9 @@ void EnDntJiji_Destroy(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
|
||||
void EnDntJiji_SetFlower(EnDntJiji* this, PlayState* play) {
|
||||
// SOH: Due to removed object dependencies, parent was still NULL when Init was called. In order to properly set
|
||||
// stage, redo it here now that we are a frame later.
|
||||
this->stage = (EnDntDemo*)this->actor.parent;
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
this->flowerPos = this->actor.world.pos;
|
||||
this->actionFunc = EnDntJiji_SetupWait;
|
||||
|
@ -349,7 +349,15 @@ void EnDoor_Draw(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
}
|
||||
if (this->lockTimer != 0) {
|
||||
if (CVarGetInteger("gShowDoorLocksOnBothSides", 0)) {
|
||||
Matrix_Push();
|
||||
}
|
||||
Actor_DrawDoorLock(play, this->lockTimer, DOORLOCK_NORMAL);
|
||||
if (CVarGetInteger("gShowDoorLocksOnBothSides", 0)) {
|
||||
Matrix_Pop();
|
||||
Matrix_RotateZYX(0, 0x8000, 0, MTXMODE_APPLY);
|
||||
Actor_DrawDoorLock(play, this->lockTimer, DOORLOCK_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
|
@ -1027,8 +1027,8 @@ void EnGirlA_BuyEvent_ObtainBombchuPack(PlayState* play, EnGirlA* this) {
|
||||
Rupees_ChangeBy(-this->basePrice);
|
||||
|
||||
// Normally, buying a bombchu pack sets a flag indicating the pack is now sold out
|
||||
// If they're in logic for rando, skip setting that flag so they can be purchased repeatedly
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC)) {
|
||||
// If we're in rando, skip setting that flag so they can be purchased repeatedly
|
||||
if (IS_RANDO) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1255,8 +1255,7 @@ void EnGirlA_InitializeItemAction(EnGirlA* this, PlayState* play) {
|
||||
this->itemGiveFunc = itemEntry->itemGiveFunc;
|
||||
this->buyEventFunc = itemEntry->buyEventFunc;
|
||||
// If chus are in logic, make the 10 pack affordable without a wallet upgrade
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) &&
|
||||
this->getItemId == GI_BOMBCHUS_10) {
|
||||
if (IS_RANDO && this->getItemId == GI_BOMBCHUS_10) {
|
||||
this->basePrice = 99;
|
||||
} else {
|
||||
this->basePrice = itemEntry->price;
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "objects/object_tite/object_tite.h"
|
||||
#include "objects/object_ik/object_ik.h"
|
||||
|
||||
#include <string.h> // strcmp
|
||||
|
||||
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
|
||||
|
||||
void EnPart_Init(Actor* thisx, PlayState* play);
|
||||
@ -297,11 +299,11 @@ void EnPart_Draw(Actor* thisx, PlayState* play) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, func_80ACEAC0(play->state.gfxCtx, 255, 255, 255, 180, 180, 180));
|
||||
gSPSegment(POLY_OPA_DISP++, 0x09, func_80ACEAC0(play->state.gfxCtx, 225, 205, 115, 25, 20, 0));
|
||||
gSPSegment(POLY_OPA_DISP++, 0x0A, func_80ACEAC0(play->state.gfxCtx, 225, 205, 115, 25, 20, 0));
|
||||
} else if ((thisx->params == 9) && (this->displayList == ResourceMgr_LoadGfxByName(object_tite_DL_002FF0))) {
|
||||
} else if ((thisx->params == 9) && (strcmp((const char*)this->displayList, object_tite_DL_002FF0) == 0)) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, object_tite_Tex_001300);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x09, object_tite_Tex_001700);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x0A, object_tite_Tex_001900);
|
||||
} else if ((thisx->params == 10) && (this->displayList == ResourceMgr_LoadGfxByName(object_tite_DL_002FF0))) {
|
||||
} else if ((thisx->params == 10) && (strcmp((const char*)this->displayList, object_tite_DL_002FF0) == 0)) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, object_tite_Tex_001B00);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x09, object_tite_Tex_001F00);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x0A, object_tite_Tex_002100);
|
||||
|
@ -745,6 +745,28 @@ void EnPartner_Update(Actor* thisx, PlayState* play) {
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
|
||||
}
|
||||
|
||||
if (CVarGetInteger("gCosmetics.Ivan_IdlePrimary.Changed", 0)) {
|
||||
Color_RGB8 ivanColor1 = CVarGetColor24("gCosmetics.Ivan_IdlePrimary.Value", (Color_RGB8){ 255, 255, 255 });
|
||||
this->innerColor.r = ivanColor1.r;
|
||||
this->innerColor.g = ivanColor1.g;
|
||||
this->innerColor.b = ivanColor1.b;
|
||||
} else {
|
||||
this->innerColor.r = 255;
|
||||
this->innerColor.g = 255;
|
||||
this->innerColor.b = 255;
|
||||
}
|
||||
|
||||
if (CVarGetInteger("gCosmetics.Ivan_IdleSecondary.Changed", 0)) {
|
||||
Color_RGB8 ivanColor2 = CVarGetColor24("gCosmetics.Ivan_IdleSecondary.Value", (Color_RGB8){ 0, 255, 0 });
|
||||
this->outerColor.r = ivanColor2.r;
|
||||
this->outerColor.g = ivanColor2.g;
|
||||
this->outerColor.b = ivanColor2.b;
|
||||
} else {
|
||||
this->outerColor.r = 0;
|
||||
this->outerColor.g = 255;
|
||||
this->outerColor.b = 0;
|
||||
}
|
||||
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
|
||||
EnPartner_UpdateLights(this, play);
|
||||
|
@ -821,19 +821,6 @@ void func_80AF3F20(EnRu2* this, PlayState* play) {
|
||||
void EnRu2_Draw(Actor* thisx, PlayState* play) {
|
||||
EnRu2* this = (EnRu2*)thisx;
|
||||
|
||||
// FAST3D: This is a hack for the issue of both TEXEL0 and TEXEL1 using the same texture with different settings.
|
||||
// Ruto's earring uses both TEXEL0 and TEXEL1 to render. The issue is that it never loads anything into TEXEL1, so
|
||||
// it reuses whatever happens to be there, which is the water temple brick texture. It just so happens that the
|
||||
// earring texture loads into the same place in tmem as the brick texture, so when it comes to rendering, TEXEL1
|
||||
// uses the earring texture with diffrent clamp settings, and it displays without noticeable error. However, both
|
||||
// texel samplers are not intended to be used for the same texture with different settings, so this misuse confuses
|
||||
// our texture cache, and we load the wrong settings for the earrings texture. This patch is a hack that replaces
|
||||
// TEXEL1 with TEXEL0, which is most likely the original intention, and all is well.
|
||||
Gfx* gfx = ResourceMgr_LoadGfxByName(gAdultRutoHeadDL);
|
||||
Gfx patch = gsDPSetCombineLERP(TEXEL0, 0, PRIMITIVE, 0, TEXEL0, 0, ENVIRONMENT, 0, 0, 0, 0, COMBINED, TEXEL0, 0,
|
||||
PRIM_LOD_FRAC, COMBINED);
|
||||
gfx[0xA2] = patch;
|
||||
|
||||
if ((this->drawConfig < 0) || (this->drawConfig >= ARRAY_COUNT(sDrawFuncs)) ||
|
||||
(sDrawFuncs[this->drawConfig] == 0)) {
|
||||
// "Draw Mode is improper!"
|
||||
|
@ -1412,12 +1412,20 @@ void EnSkj_StartOcarinaMinigame(EnSkj* this, PlayState* play) {
|
||||
EnSkj_TurnPlayer(this, player);
|
||||
|
||||
if (dialogState == TEXT_STATE_CLOSING) {
|
||||
func_8010BD58(play, OCARINA_ACTION_MEMORY_GAME);
|
||||
if (sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid != NULL) {
|
||||
sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid->minigameState = SKULL_KID_OCARINA_PLAY_NOTES;
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gInstantOcarinaGameWin", 0) && CVarGetInteger("gCustomizeOcarinaGame", 0)) {
|
||||
play->msgCtx.ocarinaMode = OCARINA_MODE_0F;
|
||||
this->songFailTimer = 160;
|
||||
this->actionFunc = EnSkj_WaitForPlayback;
|
||||
// #endregion
|
||||
} else {
|
||||
func_8010BD58(play, OCARINA_ACTION_MEMORY_GAME);
|
||||
if (sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid != NULL) {
|
||||
sOcarinaMinigameSkullKids[SKULL_KID_LEFT].skullkid->minigameState = SKULL_KID_OCARINA_PLAY_NOTES;
|
||||
this->songFailTimer = 160;
|
||||
this->actionFunc = EnSkj_WaitForPlayback;
|
||||
}
|
||||
}
|
||||
this->songFailTimer = 160;
|
||||
this->actionFunc = EnSkj_WaitForPlayback;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1466,7 +1474,14 @@ void EnSkj_WaitForPlayback(EnSkj* this, PlayState* play) {
|
||||
break;
|
||||
case MSGMODE_MEMORY_GAME_PLAYER_PLAYING:
|
||||
if (this->songFailTimer != 0) {
|
||||
this->songFailTimer--;
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gOcarinaUnlimitedFailTime", 0) == 1 &&
|
||||
CVarGetInteger("gCustomizeOcarinaGame", 0) == 1) {
|
||||
// don't decrement timer
|
||||
// #endregion
|
||||
} else {
|
||||
this->songFailTimer--;
|
||||
}
|
||||
} else { // took too long, game failed
|
||||
func_80078884(NA_SE_SY_OCARINA_ERROR);
|
||||
Message_CloseTextbox(play);
|
||||
|
@ -5174,6 +5174,37 @@ static Vec3s sSinkingLureLocationPos[] = {
|
||||
{ 553, -48, -508 },
|
||||
};
|
||||
|
||||
// #region SOH [Enhancement]
|
||||
void Fishing_QuitAtDoor(Fishing* this, PlayState* play) {
|
||||
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) {
|
||||
Message_CloseTextbox(play);
|
||||
|
||||
switch (play->msgCtx.choiceIndex) {
|
||||
case 0:
|
||||
if (D_80B7E084 == 0) {
|
||||
Message_ContinueTextbox(play, 0x4085);
|
||||
} else if (sLinkAge == 1) {
|
||||
Message_ContinueTextbox(play, 0x4092);
|
||||
}
|
||||
|
||||
if (Message_GetState(&play->msgCtx) == TEXT_STATE_DONE_FADING) {
|
||||
|
||||
if (D_80B7A68C != 0) {
|
||||
D_80B7A688 = 1;
|
||||
D_80B7A68C = 0;
|
||||
}
|
||||
D_80B7E0AC = 0;
|
||||
play->interfaceCtx.unk_260 = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
func_800A9F6C(0.0f, 150, 10, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// #endregion
|
||||
|
||||
void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) {
|
||||
PlayState* play = play2;
|
||||
Fishing* this = (Fishing*)thisx;
|
||||
@ -5481,6 +5512,12 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) {
|
||||
player->actor.world.pos.z = 1360.0f;
|
||||
player->actor.speedXZ = 0.0f;
|
||||
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gQuitFishingAtDoor", 0)) {
|
||||
Fishing_QuitAtDoor(this, play);
|
||||
}
|
||||
// #endregion
|
||||
|
||||
if (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE) {
|
||||
Camera* camera = Play_GetCamera(play, MAIN_CAM);
|
||||
|
||||
|
@ -2911,7 +2911,11 @@ s32 func_808356E8(Player* this, PlayState* play) {
|
||||
}
|
||||
|
||||
void func_808357E8(Player* this, Gfx** dLists) {
|
||||
this->leftHandDLists = &dLists[gSaveContext.linkAge];
|
||||
if (LINK_IS_ADULT && (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0))) {
|
||||
this->leftHandDLists = &dLists[1];
|
||||
} else {
|
||||
this->leftHandDLists = &dLists[gSaveContext.linkAge];
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_80835800(Player* this, PlayState* play) {
|
||||
@ -6982,9 +6986,19 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall
|
||||
this->actor.world.pos.z = zVertex1 + (distToInteractWall * wallPolyNormZ);
|
||||
func_80832224(this);
|
||||
this->actor.prevPos = this->actor.world.pos;
|
||||
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_start);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
||||
// increase animation speed when entering a tunnel
|
||||
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
|
||||
((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f), 0.0f,
|
||||
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), ANIMMODE_ONCE,
|
||||
0.0f);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
// #endregion
|
||||
} else {
|
||||
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_start);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -7065,16 +7079,39 @@ s32 Player_TryLeavingCrawlspace(Player* this, PlayState* play) {
|
||||
|
||||
if (this->linearVelocity > 0.0f) {
|
||||
this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
|
||||
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_end);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
||||
// animation when exiting a tunnel forward
|
||||
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_end,
|
||||
((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f), 0.0f,
|
||||
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_end), ANIMMODE_ONCE,
|
||||
0.0f);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
|
||||
// #endregion
|
||||
} else {
|
||||
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_end);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
|
||||
}
|
||||
} else {
|
||||
this->actor.shape.rot.y = this->actor.wallYaw;
|
||||
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f,
|
||||
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE,
|
||||
0.0f);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
|
||||
// #region SOH [Enhancement]
|
||||
// animation when exiting a tunnel backward
|
||||
if (CVarGetInteger("gCrawlSpeed",1) > 1) {
|
||||
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
|
||||
-1.0f * ((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f),
|
||||
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE, 0.0f);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
|
||||
// #endregion
|
||||
}
|
||||
else {
|
||||
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f,
|
||||
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE, 0.0f);
|
||||
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
||||
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
|
||||
}
|
||||
}
|
||||
|
||||
this->currentYaw = this->actor.shape.rot.y;
|
||||
@ -11927,6 +11964,68 @@ void func_8084AEEC(Player* this, f32* arg1, f32 arg2, s16 arg3) {
|
||||
f32 temp1;
|
||||
f32 temp2;
|
||||
|
||||
// #region SOH [Enhancement]
|
||||
f32 swimMod = 1.0f;
|
||||
|
||||
if (CVarGetInteger("gEnableWalkModify", 0) == 1) {
|
||||
if (CVarGetInteger("gWalkSpeedToggle", 0) == 1) {
|
||||
if (gWalkSpeedToggle1) {
|
||||
swimMod *= CVarGetFloat("gSwimModifierOne", 1.0f);
|
||||
} else if (gWalkSpeedToggle2) {
|
||||
swimMod *= CVarGetFloat("gSwimModifierTwo", 1.0f);
|
||||
}
|
||||
} else {
|
||||
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER1)) {
|
||||
swimMod *= CVarGetFloat("gSwimModifierOne", 1.0f);
|
||||
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER2)) {
|
||||
swimMod *= CVarGetFloat("gSwimModifierTwo", 1.0f);
|
||||
}
|
||||
}
|
||||
temp1 = this->skelAnime.curFrame - 10.0f;
|
||||
|
||||
temp2 = (R_RUN_SPEED_LIMIT / 100.0f) * 0.8f * swimMod;
|
||||
if (*arg1 > temp2) {
|
||||
*arg1 = temp2;
|
||||
}
|
||||
|
||||
if ((0.0f < temp1) && (temp1 < 10.0f)) {
|
||||
temp1 *= 6.0f;
|
||||
} else {
|
||||
temp1 = 0.0f;
|
||||
arg2 = 0.0f;
|
||||
}
|
||||
|
||||
Math_AsymStepToF(arg1, arg2 * 0.8f * swimMod, temp1, (fabsf(*arg1) * 0.02f) + 0.05f);
|
||||
Math_ScaledStepToS(&this->currentYaw, arg3, 1600);
|
||||
// #endregion
|
||||
} else {
|
||||
|
||||
temp1 = this->skelAnime.curFrame - 10.0f;
|
||||
|
||||
temp2 = (R_RUN_SPEED_LIMIT / 100.0f) * 0.8f;
|
||||
if (*arg1 > temp2) {
|
||||
*arg1 = temp2;
|
||||
}
|
||||
|
||||
if ((0.0f < temp1) && (temp1 < 10.0f)) {
|
||||
temp1 *= 6.0f;
|
||||
} else {
|
||||
temp1 = 0.0f;
|
||||
arg2 = 0.0f;
|
||||
}
|
||||
|
||||
Math_AsymStepToF(arg1, arg2 * 0.8f, temp1, (fabsf(*arg1) * 0.02f) + 0.05f);
|
||||
Math_ScaledStepToS(&this->currentYaw, arg3, 1600);
|
||||
}
|
||||
}
|
||||
|
||||
// #region SOH [Enhancement]
|
||||
//Diving uses function func_8084AEEC to calculate changes both xz and y velocity (via func_8084DBC4)
|
||||
//Provide original calculation for y velocity when swim speed mod is active
|
||||
void SurfaceWithoutSwimMod(Player* this, f32* arg1, f32 arg2, s16 arg3) {
|
||||
f32 temp1;
|
||||
f32 temp2;
|
||||
|
||||
temp1 = this->skelAnime.curFrame - 10.0f;
|
||||
|
||||
temp2 = (R_RUN_SPEED_LIMIT / 100.0f) * 0.8f;
|
||||
@ -11944,6 +12043,7 @@ void func_8084AEEC(Player* this, f32* arg1, f32 arg2, s16 arg3) {
|
||||
Math_AsymStepToF(arg1, arg2 * 0.8f, temp1, (fabsf(*arg1) * 0.02f) + 0.05f);
|
||||
Math_ScaledStepToS(&this->currentYaw, arg3, 1600);
|
||||
}
|
||||
// #endregion
|
||||
|
||||
void func_8084B000(Player* this) {
|
||||
f32 phi_f18;
|
||||
@ -12562,8 +12662,15 @@ void func_8084C760(Player* this, PlayState* play) {
|
||||
return;
|
||||
}
|
||||
|
||||
// player speed in a tunnel
|
||||
if (!Player_TryLeavingCrawlspace(this, play)) {
|
||||
this->linearVelocity = sControlInput->rel.stick_y * 0.03f;
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
||||
this->linearVelocity = sControlInput->rel.stick_y * 0.03f * CVarGetInteger("gCrawlSpeed", 1);
|
||||
// #endregion
|
||||
} else {
|
||||
this->linearVelocity = sControlInput->rel.stick_y * 0.03f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -13098,7 +13205,14 @@ void func_8084DBC4(PlayState* play, Player* this, f32 arg2) {
|
||||
|
||||
Player_GetMovementSpeedAndYaw(this, &sp2C, &sp2A, 0.0f, play);
|
||||
func_8084AEEC(this, &this->linearVelocity, sp2C * 0.5f, sp2A);
|
||||
func_8084AEEC(this, &this->actor.velocity.y, arg2, this->currentYaw);
|
||||
// Original implementation of func_8084AEEC (SurfaceWithoutSwimMod) to prevent velocity increases via swim mod which push Link into the air
|
||||
// #region SOH [Enhancement]
|
||||
if (CVarGetInteger("gEnableWalkModify", 0)) {
|
||||
SurfaceWithoutSwimMod(this, &this->actor.velocity.y, arg2, this->currentYaw);
|
||||
// #endregion
|
||||
} else {
|
||||
func_8084AEEC(this, &this->actor.velocity.y, arg2, this->currentYaw);
|
||||
}
|
||||
}
|
||||
|
||||
void func_8084DC48(Player* this, PlayState* play) {
|
||||
|
@ -312,6 +312,9 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
KaleidoScope_DrawQuadTextureRGBA32(gfxCtx, gQuestIconGoldSkulltulaTex, 24, 24, 8);
|
||||
}
|
||||
|
||||
// Unique index for both pulse phases
|
||||
uint8_t palettePulseIdx = (mapBgPulseStage ? 40 : 20) - mapBgPulseTimer;
|
||||
|
||||
if ((play->sceneNum >= SCENE_DEKU_TREE) && (play->sceneNum <= SCENE_TREASURE_BOX_SHOP)) {
|
||||
stepR = (mapBgPulseR - mapBgPulseColors[mapBgPulseStage][0]) / mapBgPulseTimer;
|
||||
stepG = (mapBgPulseG - mapBgPulseColors[mapBgPulseStage][1]) / mapBgPulseTimer;
|
||||
@ -324,6 +327,9 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
interfaceCtx->mapPalette[28] = (rgba16 & 0xFF00) >> 8;
|
||||
interfaceCtx->mapPalette[29] = rgba16 & 0xFF;
|
||||
|
||||
interfaceCtx->mapPalettesPulse[palettePulseIdx][28] = (rgba16 & 0xFF00) >> 8;
|
||||
interfaceCtx->mapPalettesPulse[palettePulseIdx][29] = rgba16 & 0xFF;
|
||||
|
||||
mapBgPulseTimer--;
|
||||
if (mapBgPulseTimer == 0) {
|
||||
mapBgPulseStage ^= 1;
|
||||
@ -335,7 +341,8 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
gDPSetTextureFilter(POLY_KAL_DISP++, G_TF_POINT);
|
||||
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha);
|
||||
|
||||
gDPLoadTLUT_pal16(POLY_KAL_DISP++, 0, interfaceCtx->mapPalette);
|
||||
// Use a unique palette address per frame so the renderer/shader can cache all variations
|
||||
gDPLoadTLUT_pal16(POLY_KAL_DISP++, 0, interfaceCtx->mapPalettesPulse[palettePulseIdx]);
|
||||
gDPSetTextureLUT(POLY_KAL_DISP++, G_TT_RGBA16);
|
||||
|
||||
u8 mirroredWorld = CVarGetInteger("gMirroredWorld", 0);
|
||||
@ -349,10 +356,6 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
|
||||
gSPVertex(POLY_KAL_DISP++, &pauseCtx->mapPageVtx[60], 8, 0);
|
||||
|
||||
// The dungeon map textures are recreated each frame, so always invalidate them
|
||||
gSPInvalidateTexCache(POLY_KAL_DISP++, interfaceCtx->mapSegment[0]);
|
||||
gSPInvalidateTexCache(POLY_KAL_DISP++, interfaceCtx->mapSegment[1]);
|
||||
|
||||
gDPLoadTextureBlock_4b(POLY_KAL_DISP++, interfaceCtx->mapSegmentName[0], G_IM_FMT_CI, MAP_48x85_TEX_WIDTH,
|
||||
MAP_48x85_TEX_HEIGHT, 0, G_TX_WRAP | mirrorMode, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK,
|
||||
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
@ -1204,8 +1204,6 @@ Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, void** textures) {
|
||||
return gfx;
|
||||
}
|
||||
|
||||
static uint8_t mapBlendMask[MAP_48x85_TEX_WIDTH * MAP_48x85_TEX_HEIGHT];
|
||||
|
||||
void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
static Color_RGB8 D_8082ACF4[12] = {
|
||||
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 255, 255, 0 }, { 0, 0, 0 },
|
||||
@ -1374,10 +1372,6 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
// Need to invalidate the blend mask every frame. Ideally this would be done in KaleidoScope_DrawDungeonMap
|
||||
// but the reference is not shared between files
|
||||
gSPInvalidateTexCache(POLY_KAL_DISP++, mapBlendMask);
|
||||
|
||||
if (pauseCtx->pageIndex) { // pageIndex != PAUSE_ITEM
|
||||
gDPPipeSync(OVERLAY_DISP++);
|
||||
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
||||
@ -1889,11 +1883,17 @@ void KaleidoScope_DrawInfoPanel(PlayState* play) {
|
||||
gSPMatrix(POLY_KAL_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
|
||||
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 90, 100, 130, 255);
|
||||
const Color_RGBA8 namePanelColor = CVarGetColor("gCosmetics.Kal_NamePanel.Value", (Color_RGBA8){90,100,130,255});
|
||||
|
||||
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, namePanelColor.r, namePanelColor.g, namePanelColor.b, namePanelColor.a);
|
||||
gSPVertex(POLY_KAL_DISP++, &pauseCtx->infoPanelVtx[0], 16, 0);
|
||||
|
||||
gSPDisplayList(POLY_KAL_DISP++, gItemNamePanelDL);
|
||||
|
||||
if (CVarGetInteger("gUniformLR", 0) == 0) { // Restore the misplace gDPSetPrimColor
|
||||
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 90, 100, 130, 255);
|
||||
}
|
||||
|
||||
if ((pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) && (pauseCtx->unk_1E4 == 0)) {
|
||||
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, D_808321A0, D_808321A2, D_808321A4, D_808321A6);
|
||||
} else {
|
||||
@ -1902,6 +1902,7 @@ void KaleidoScope_DrawInfoPanel(PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gSPDisplayList(POLY_KAL_DISP++, gLButtonIconDL);
|
||||
|
||||
if (CVarGetInteger("gUniformLR", 0) == 0) { //Restore the misplace gDPSetPrimColor
|
||||
@ -2311,15 +2312,15 @@ void KaleidoScope_SetView(PauseContext* pauseCtx, f32 x, f32 y, f32 z) {
|
||||
func_800AAA50(&pauseCtx->view, 127);
|
||||
}
|
||||
|
||||
static u8 D_8082AE48[][4] = {
|
||||
static u8 sPageVtxColorR[][4] = {
|
||||
{ 10, 70, 70, 10 }, { 10, 90, 90, 10 }, { 80, 140, 140, 80 },
|
||||
{ 80, 120, 120, 80 }, { 80, 140, 140, 80 }, { 50, 110, 110, 50 },
|
||||
};
|
||||
static u8 D_8082AE60[][4] = {
|
||||
static u8 sPageVtxColorG[][4] = {
|
||||
{ 50, 100, 100, 50 }, { 50, 100, 100, 50 }, { 40, 60, 60, 40 },
|
||||
{ 80, 120, 120, 80 }, { 40, 60, 60, 40 }, { 50, 110, 110, 50 },
|
||||
};
|
||||
static u8 D_8082AE78[][4] = {
|
||||
static u8 sPageVtxColorB[][4] = {
|
||||
{ 80, 130, 130, 80 }, { 40, 60, 60, 40 }, { 30, 60, 60, 30 },
|
||||
{ 50, 70, 70, 50 }, { 30, 60, 60, 30 }, { 50, 110, 110, 50 },
|
||||
};
|
||||
@ -2447,10 +2448,87 @@ static s16 D_8082B0E4[] = {
|
||||
0x0019, 0x000D, 0x0001, 0x0001, 0x000D, 0x0015, 0x000F, 0x000D, 0x000C, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
s16 func_80823A0C(PlayState* play, Vtx* vtx, s16 arg2, s16 arg3) {
|
||||
static const char* gPageVtxColorCvars[][4] = {
|
||||
{
|
||||
"gCosmetics.Kal_ItemSelA.Value",
|
||||
"gCosmetics.Kal_ItemSelB.Value",
|
||||
"gCosmetics.Kal_ItemSelC.Value",
|
||||
"gCosmetics.Kal_ItemSelD.Value",
|
||||
},
|
||||
{
|
||||
"gCosmetics.Kal_EquipSelA.Value",
|
||||
"gCosmetics.Kal_EquipSelB.Value",
|
||||
"gCosmetics.Kal_EquipSelC.Value",
|
||||
"gCosmetics.Kal_EquipSelD.Value",
|
||||
},
|
||||
{
|
||||
"gCosmetics.Kal_MapSelDunA.Value",
|
||||
"gCosmetics.Kal_MapSelDunB.Value",
|
||||
"gCosmetics.Kal_MapSelDunC.Value",
|
||||
"gCosmetics.Kal_MapSelDunD.Value",
|
||||
},
|
||||
{
|
||||
"gCosmetics.Kal_QuestStatusA.Value",
|
||||
"gCosmetics.Kal_QuestStatusB.Value",
|
||||
"gCosmetics.Kal_QuestStatusC.Value",
|
||||
"gCosmetics.Kal_QuestStatusD.Value",
|
||||
},
|
||||
{
|
||||
"gCosmetics.Kal_MapSelectA.Value",
|
||||
"gCosmetics.Kal_MapSelectB.Value",
|
||||
"gCosmetics.Kal_MapSelectC.Value",
|
||||
"gCosmetics.Kal_MapSelectD.Value",
|
||||
},
|
||||
{
|
||||
"gCosmetics.Kal_SaveA.Value",
|
||||
"gCosmetics.Kal_SaveB.Value",
|
||||
"gCosmetics.Kal_SaveC.Value",
|
||||
"gCosmetics.Kal_SaveD.Value",
|
||||
},
|
||||
};
|
||||
|
||||
s16 func_80823A0C(PlayState* play, Vtx* vtx, s16 pageIndex, s16 arg3) {
|
||||
static s16 D_8082B110 = 0;
|
||||
static s16 D_8082B114 = 1;
|
||||
static s16 D_8082B118 = 0;
|
||||
static const Color_RGBA8 pageColors[][4] = {
|
||||
{
|
||||
{ 10, 50, 80, 255 },
|
||||
{ 70, 100, 130, 255 },
|
||||
{ 70, 100, 130, 255 },
|
||||
{ 10, 50, 80, 255 },
|
||||
},
|
||||
{
|
||||
{ 10, 50, 40, 255 },
|
||||
{ 90, 100, 60, 255 },
|
||||
{ 90, 100, 60, 255 },
|
||||
{ 10, 50, 40, 255 },
|
||||
},
|
||||
{
|
||||
{ 80,40,30, 255},
|
||||
{ 140,60,60,255 },
|
||||
{ 140,60,60,255 },
|
||||
{ 80, 40, 30, 255 },
|
||||
},
|
||||
{
|
||||
{ 80,80,50,255 },
|
||||
{ 120,120,70,255 },
|
||||
{ 120,120,70,255 },
|
||||
{ 80, 80, 50, 255 },
|
||||
},
|
||||
{
|
||||
{ 80, 40, 30, 255 },
|
||||
{ 140,60,60,255 },
|
||||
{ 140,60,60,255 },
|
||||
{ 80, 40, 30, 255 },
|
||||
},
|
||||
{
|
||||
{ 50,50,50,255 },
|
||||
{ 110,110,110,255 },
|
||||
{ 110,110,110,255 },
|
||||
{ 50,50,50,255 },
|
||||
},
|
||||
};
|
||||
PauseContext* pauseCtx = &play->pauseCtx;
|
||||
s16* ptr1;
|
||||
s16* ptr2;
|
||||
@ -2460,109 +2538,114 @@ s16 func_80823A0C(PlayState* play, Vtx* vtx, s16 arg2, s16 arg3) {
|
||||
s16 phi_t0;
|
||||
s16 phi_a1;
|
||||
s16 phi_a2;
|
||||
s16 phi_t3;
|
||||
s16 phi_t1;
|
||||
s16 colorIndex; // Also used for other things.
|
||||
s16 vtxIndex;
|
||||
|
||||
phi_t0 = -200;
|
||||
|
||||
for (phi_t1 = 0, phi_t3 = 0; phi_t3 < 3; phi_t3++) {
|
||||
for (vtxIndex = 0, colorIndex = 0; colorIndex < 3; colorIndex++) {
|
||||
phi_t0 += 80;
|
||||
|
||||
for (phi_a1 = 80, phi_a2 = 0; phi_a2 < 5; phi_a2++, phi_t1 += 4, phi_a1 -= 32) {
|
||||
vtx[phi_t1 + 0].v.ob[0] = vtx[phi_t1 + 2].v.ob[0] = phi_t0;
|
||||
for (phi_a1 = 80, phi_a2 = 0; phi_a2 < 5; phi_a2++, vtxIndex += 4, phi_a1 -= 32) {
|
||||
vtx[vtxIndex + 0].v.ob[0] = vtx[vtxIndex + 2].v.ob[0] = phi_t0;
|
||||
|
||||
vtx[phi_t1 + 1].v.ob[0] = vtx[phi_t1 + 3].v.ob[0] = vtx[phi_t1 + 0].v.ob[0] + 80;
|
||||
vtx[vtxIndex + 1].v.ob[0] = vtx[vtxIndex + 3].v.ob[0] = vtx[vtxIndex + 0].v.ob[0] + 80;
|
||||
|
||||
vtx[phi_t1 + 0].v.ob[1] = vtx[phi_t1 + 1].v.ob[1] = phi_a1 + pauseCtx->offsetY;
|
||||
vtx[vtxIndex + 0].v.ob[1] = vtx[vtxIndex + 1].v.ob[1] = phi_a1 + pauseCtx->offsetY;
|
||||
|
||||
vtx[phi_t1 + 2].v.ob[1] = vtx[phi_t1 + 3].v.ob[1] = vtx[phi_t1 + 0].v.ob[1] - 32;
|
||||
vtx[vtxIndex + 2].v.ob[1] = vtx[vtxIndex + 3].v.ob[1] = vtx[vtxIndex + 0].v.ob[1] - 32;
|
||||
|
||||
vtx[phi_t1 + 0].v.ob[2] = vtx[phi_t1 + 1].v.ob[2] = vtx[phi_t1 + 2].v.ob[2] = vtx[phi_t1 + 3].v.ob[2] = 0;
|
||||
vtx[vtxIndex + 0].v.ob[2] = vtx[vtxIndex + 1].v.ob[2] = vtx[vtxIndex + 2].v.ob[2] = vtx[vtxIndex + 3].v.ob[2] = 0;
|
||||
|
||||
vtx[phi_t1 + 0].v.flag = 0;
|
||||
vtx[phi_t1 + 1].v.flag = 0;
|
||||
vtx[phi_t1 + 2].v.flag = 0;
|
||||
vtx[phi_t1 + 3].v.flag = 0;
|
||||
vtx[vtxIndex + 0].v.flag = 0;
|
||||
vtx[vtxIndex + 1].v.flag = 0;
|
||||
vtx[vtxIndex + 2].v.flag = 0;
|
||||
vtx[vtxIndex + 3].v.flag = 0;
|
||||
|
||||
vtx[phi_t1 + 0].v.tc[0] = vtx[phi_t1 + 0].v.tc[1] = vtx[phi_t1 + 1].v.tc[1] = vtx[phi_t1 + 2].v.tc[0] = 0;
|
||||
vtx[vtxIndex + 0].v.tc[0] = vtx[vtxIndex + 0].v.tc[1] = vtx[vtxIndex + 1].v.tc[1] = vtx[vtxIndex + 2].v.tc[0] = 0;
|
||||
|
||||
vtx[phi_t1 + 1].v.tc[0] = vtx[phi_t1 + 3].v.tc[0] = 0xA00;
|
||||
vtx[vtxIndex + 1].v.tc[0] = vtx[vtxIndex + 3].v.tc[0] = 0xA00;
|
||||
|
||||
vtx[phi_t1 + 2].v.tc[1] = vtx[phi_t1 + 3].v.tc[1] = 0x400;
|
||||
vtx[vtxIndex + 2].v.tc[1] = vtx[vtxIndex + 3].v.tc[1] = 0x400;
|
||||
|
||||
vtx[phi_t1 + 0].v.cn[0] = vtx[phi_t1 + 2].v.cn[0] = D_8082AE48[arg2][phi_t3 + 0];
|
||||
//Color in the pages. Pages are drawn in groups. Each group is faded to the next. There are 4 total colors, 1/4 and 2/3 are the same creating a mirrored color set.
|
||||
// TODO, go from 0,1,2,3 to 0,1,1,0 to only use two colors instead of 4.
|
||||
Color_RGBA8 color = CVarGetColor(gPageVtxColorCvars[pageIndex][colorIndex], pageColors[pageIndex][colorIndex]);
|
||||
Color_RGBA8 colorb =
|
||||
CVarGetColor(gPageVtxColorCvars[pageIndex][colorIndex + 1], pageColors[pageIndex][colorIndex+1]);
|
||||
vtx[vtxIndex + 0].v.cn[0] = vtx[vtxIndex + 2].v.cn[0] = color.r; // sPageVtxColorR[pageIndex][colorIndex + 0];
|
||||
|
||||
vtx[phi_t1 + 0].v.cn[1] = vtx[phi_t1 + 2].v.cn[1] = D_8082AE60[arg2][phi_t3 + 0];
|
||||
vtx[vtxIndex + 0].v.cn[1] = vtx[vtxIndex + 2].v.cn[1] = color.g;// sPageVtxColorG[pageIndex][colorIndex + 0];
|
||||
|
||||
vtx[phi_t1 + 0].v.cn[2] = vtx[phi_t1 + 2].v.cn[2] = D_8082AE78[arg2][phi_t3 + 0];
|
||||
vtx[vtxIndex + 0].v.cn[2] = vtx[vtxIndex + 2].v.cn[2] = color.b; // sPageVtxColorB[pageIndex][colorIndex + 0];
|
||||
|
||||
vtx[phi_t1 + 1].v.cn[0] = vtx[phi_t1 + 3].v.cn[0] = D_8082AE48[arg2][phi_t3 + 1];
|
||||
vtx[vtxIndex + 1].v.cn[0] = vtx[vtxIndex + 3].v.cn[0] = colorb.r;//sPageVtxColorR[pageIndex][colorIndex + 1];
|
||||
|
||||
vtx[phi_t1 + 1].v.cn[1] = vtx[phi_t1 + 3].v.cn[1] = D_8082AE60[arg2][phi_t3 + 1];
|
||||
vtx[vtxIndex + 1].v.cn[1] = vtx[vtxIndex + 3].v.cn[1] = colorb.g; // sPageVtxColorG[pageIndex][colorIndex + 1];
|
||||
|
||||
vtx[phi_t1 + 1].v.cn[2] = vtx[phi_t1 + 3].v.cn[2] = D_8082AE78[arg2][phi_t3 + 1];
|
||||
vtx[vtxIndex + 1].v.cn[2] = vtx[vtxIndex + 3].v.cn[2] = colorb.b; // sPageVtxColorB[pageIndex][colorIndex + 1];
|
||||
|
||||
vtx[phi_t1 + 0].v.cn[3] = vtx[phi_t1 + 2].v.cn[3] = vtx[phi_t1 + 1].v.cn[3] = vtx[phi_t1 + 3].v.cn[3] =
|
||||
vtx[vtxIndex + 0].v.cn[3] = vtx[vtxIndex + 2].v.cn[3] = vtx[vtxIndex + 1].v.cn[3] = vtx[vtxIndex + 3].v.cn[3] =
|
||||
pauseCtx->alpha;
|
||||
}
|
||||
}
|
||||
|
||||
phi_s2 = phi_t1;
|
||||
phi_s2 = vtxIndex;
|
||||
|
||||
if (arg3 != 0) {
|
||||
ptr1 = D_8082B000[arg2];
|
||||
ptr2 = D_8082B018[arg2];
|
||||
ptr3 = D_8082B030[arg2];
|
||||
ptr4 = D_8082B048[arg2];
|
||||
ptr1 = D_8082B000[pageIndex];
|
||||
ptr2 = D_8082B018[pageIndex];
|
||||
ptr3 = D_8082B030[pageIndex];
|
||||
ptr4 = D_8082B048[pageIndex];
|
||||
|
||||
for (phi_t3 = 0; phi_t3 < arg3; phi_t3++, phi_t1 += 4) {
|
||||
vtx[phi_t1 + 2].v.ob[0] = vtx[phi_t1 + 0].v.ob[0] = ptr1[phi_t3];
|
||||
for (colorIndex = 0; colorIndex < arg3; colorIndex++, vtxIndex += 4) {
|
||||
vtx[vtxIndex + 2].v.ob[0] = vtx[vtxIndex + 0].v.ob[0] = ptr1[colorIndex];
|
||||
|
||||
vtx[phi_t1 + 1].v.ob[0] = vtx[phi_t1 + 3].v.ob[0] = vtx[phi_t1 + 0].v.ob[0] + ptr2[phi_t3];
|
||||
vtx[vtxIndex + 1].v.ob[0] = vtx[vtxIndex + 3].v.ob[0] = vtx[vtxIndex + 0].v.ob[0] + ptr2[colorIndex];
|
||||
|
||||
if (!((pauseCtx->state >= 8) && (pauseCtx->state <= 0x11))) {
|
||||
vtx[phi_t1 + 0].v.ob[1] = vtx[phi_t1 + 1].v.ob[1] = ptr3[phi_t3] + pauseCtx->offsetY;
|
||||
vtx[vtxIndex + 0].v.ob[1] = vtx[vtxIndex + 1].v.ob[1] = ptr3[colorIndex] + pauseCtx->offsetY;
|
||||
} else {
|
||||
vtx[phi_t1 + 0].v.ob[1] = vtx[phi_t1 + 1].v.ob[1] = YREG(60 + phi_t3) + pauseCtx->offsetY;
|
||||
vtx[vtxIndex + 0].v.ob[1] = vtx[vtxIndex + 1].v.ob[1] = YREG(60 + colorIndex) + pauseCtx->offsetY;
|
||||
}
|
||||
|
||||
vtx[phi_t1 + 2].v.ob[1] = vtx[phi_t1 + 3].v.ob[1] = vtx[phi_t1 + 0].v.ob[1] - ptr4[phi_t3];
|
||||
vtx[vtxIndex + 2].v.ob[1] = vtx[vtxIndex + 3].v.ob[1] = vtx[vtxIndex + 0].v.ob[1] - ptr4[colorIndex];
|
||||
|
||||
vtx[phi_t1 + 0].v.ob[2] = vtx[phi_t1 + 1].v.ob[2] = vtx[phi_t1 + 2].v.ob[2] = vtx[phi_t1 + 3].v.ob[2] = 0;
|
||||
vtx[vtxIndex + 0].v.ob[2] = vtx[vtxIndex + 1].v.ob[2] = vtx[vtxIndex + 2].v.ob[2] = vtx[vtxIndex + 3].v.ob[2] = 0;
|
||||
|
||||
vtx[phi_t1 + 0].v.flag = vtx[phi_t1 + 1].v.flag = vtx[phi_t1 + 2].v.flag = vtx[phi_t1 + 3].v.flag = 0;
|
||||
vtx[vtxIndex + 0].v.flag = vtx[vtxIndex + 1].v.flag = vtx[vtxIndex + 2].v.flag = vtx[vtxIndex + 3].v.flag = 0;
|
||||
|
||||
vtx[phi_t1 + 0].v.tc[0] = vtx[phi_t1 + 0].v.tc[1] = vtx[phi_t1 + 1].v.tc[1] = vtx[phi_t1 + 2].v.tc[0] = 0;
|
||||
vtx[vtxIndex + 0].v.tc[0] = vtx[vtxIndex + 0].v.tc[1] = vtx[vtxIndex + 1].v.tc[1] = vtx[vtxIndex + 2].v.tc[0] = 0;
|
||||
|
||||
vtx[phi_t1 + 1].v.tc[0] = vtx[phi_t1 + 3].v.tc[0] = ptr2[phi_t3] << 5;
|
||||
vtx[vtxIndex + 1].v.tc[0] = vtx[vtxIndex + 3].v.tc[0] = ptr2[colorIndex] << 5;
|
||||
|
||||
vtx[phi_t1 + 2].v.tc[1] = vtx[phi_t1 + 3].v.tc[1] = ptr4[phi_t3] << 5;
|
||||
vtx[vtxIndex + 2].v.tc[1] = vtx[vtxIndex + 3].v.tc[1] = ptr4[colorIndex] << 5;
|
||||
|
||||
vtx[phi_t1 + 0].v.cn[0] = vtx[phi_t1 + 2].v.cn[0] = vtx[phi_t1 + 0].v.cn[1] = vtx[phi_t1 + 2].v.cn[1] =
|
||||
vtx[phi_t1 + 0].v.cn[2] = vtx[phi_t1 + 2].v.cn[2] = vtx[phi_t1 + 1].v.cn[0] = vtx[phi_t1 + 3].v.cn[0] =
|
||||
vtx[phi_t1 + 1].v.cn[1] = vtx[phi_t1 + 3].v.cn[1] = vtx[phi_t1 + 1].v.cn[2] =
|
||||
vtx[phi_t1 + 3].v.cn[2] = 255;
|
||||
vtx[vtxIndex + 0].v.cn[0] = vtx[vtxIndex + 2].v.cn[0] = vtx[vtxIndex + 0].v.cn[1] = vtx[vtxIndex + 2].v.cn[1] =
|
||||
vtx[vtxIndex + 0].v.cn[2] = vtx[vtxIndex + 2].v.cn[2] = vtx[vtxIndex + 1].v.cn[0] = vtx[vtxIndex + 3].v.cn[0] =
|
||||
vtx[vtxIndex + 1].v.cn[1] = vtx[vtxIndex + 3].v.cn[1] = vtx[vtxIndex + 1].v.cn[2] =
|
||||
vtx[vtxIndex + 3].v.cn[2] = 255;
|
||||
|
||||
vtx[phi_t1 + 0].v.cn[3] = vtx[phi_t1 + 2].v.cn[3] = vtx[phi_t1 + 1].v.cn[3] = vtx[phi_t1 + 3].v.cn[3] =
|
||||
vtx[vtxIndex + 0].v.cn[3] = vtx[vtxIndex + 2].v.cn[3] = vtx[vtxIndex + 1].v.cn[3] = vtx[vtxIndex + 3].v.cn[3] =
|
||||
pauseCtx->alpha;
|
||||
}
|
||||
|
||||
if (arg2 == 4) {
|
||||
phi_t1 -= 12;
|
||||
if (pageIndex == 4) {
|
||||
vtxIndex -= 12;
|
||||
|
||||
phi_t3 = gSaveContext.worldMapArea;
|
||||
colorIndex = gSaveContext.worldMapArea;
|
||||
|
||||
vtx[phi_t1 + 0].v.ob[0] = vtx[phi_t1 + 2].v.ob[0] = D_8082B060[phi_t3];
|
||||
vtx[vtxIndex + 0].v.ob[0] = vtx[vtxIndex + 2].v.ob[0] = D_8082B060[colorIndex];
|
||||
|
||||
if (phi_t3) {}
|
||||
if (colorIndex) {}
|
||||
|
||||
vtx[phi_t1 + 1].v.ob[0] = vtx[phi_t1 + 3].v.ob[0] = vtx[phi_t1 + 0].v.ob[0] + D_8082B08C[phi_t3];
|
||||
vtx[vtxIndex + 1].v.ob[0] = vtx[vtxIndex + 3].v.ob[0] = vtx[vtxIndex + 0].v.ob[0] + D_8082B08C[colorIndex];
|
||||
|
||||
vtx[phi_t1 + 0].v.ob[1] = vtx[phi_t1 + 1].v.ob[1] = D_8082B0B8[phi_t3] + pauseCtx->offsetY;
|
||||
vtx[vtxIndex + 0].v.ob[1] = vtx[vtxIndex + 1].v.ob[1] = D_8082B0B8[colorIndex] + pauseCtx->offsetY;
|
||||
|
||||
vtx[phi_t1 + 2].v.ob[1] = vtx[phi_t1 + 3].v.ob[1] = vtx[phi_t1 + 0].v.ob[1] - D_8082B0E4[phi_t3];
|
||||
vtx[vtxIndex + 2].v.ob[1] = vtx[vtxIndex + 3].v.ob[1] = vtx[vtxIndex + 0].v.ob[1] - D_8082B0E4[colorIndex];
|
||||
|
||||
phi_t1 += 12;
|
||||
vtxIndex += 12;
|
||||
|
||||
if (pauseCtx->tradeQuestLocation != 0xFF) {
|
||||
if (D_8082B114 == 0) {
|
||||
@ -2582,14 +2665,14 @@ s16 func_80823A0C(PlayState* play, Vtx* vtx, s16 arg2, s16 arg3) {
|
||||
D_8082B114--;
|
||||
}
|
||||
|
||||
phi_t3 = phi_s2 + (pauseCtx->tradeQuestLocation * 4) + 64;
|
||||
colorIndex = phi_s2 + (pauseCtx->tradeQuestLocation * 4) + 64;
|
||||
phi_a2 = phi_s2 + 116;
|
||||
|
||||
vtx[phi_a2 + 0].v.ob[0] = vtx[phi_a2 + 2].v.ob[0] = vtx[phi_t3 + 0].v.ob[0];
|
||||
vtx[phi_a2 + 0].v.ob[0] = vtx[phi_a2 + 2].v.ob[0] = vtx[colorIndex + 0].v.ob[0];
|
||||
|
||||
vtx[phi_a2 + 1].v.ob[0] = vtx[phi_a2 + 3].v.ob[0] = vtx[phi_a2 + 0].v.ob[0] + 8;
|
||||
|
||||
vtx[phi_a2 + 0].v.ob[1] = vtx[phi_a2 + 1].v.ob[1] = vtx[phi_t3 + 0].v.ob[1] - D_8082B110 + 10;
|
||||
vtx[phi_a2 + 0].v.ob[1] = vtx[phi_a2 + 1].v.ob[1] = vtx[colorIndex + 0].v.ob[1] - D_8082B110 + 10;
|
||||
|
||||
vtx[phi_a2 + 0].v.ob[2] = vtx[phi_a2 + 1].v.ob[2] = vtx[phi_a2 + 2].v.ob[2] = vtx[phi_a2 + 3].v.ob[2] =
|
||||
0;
|
||||
@ -2598,7 +2681,7 @@ s16 func_80823A0C(PlayState* play, Vtx* vtx, s16 arg2, s16 arg3) {
|
||||
|
||||
vtx[phi_a2 + 0].v.flag = vtx[phi_a2 + 1].v.flag = vtx[phi_a2 + 2].v.flag = vtx[phi_a2 + 3].v.flag = 0;
|
||||
|
||||
vtx[phi_t1].v.tc[0] = vtx[phi_t1].v.tc[1] = vtx[phi_a2 + 1].v.tc[1] = vtx[phi_a2 + 2].v.tc[0] = 0;
|
||||
vtx[vtxIndex].v.tc[0] = vtx[vtxIndex].v.tc[1] = vtx[phi_a2 + 1].v.tc[1] = vtx[phi_a2 + 2].v.tc[0] = 0;
|
||||
|
||||
vtx[phi_a2 + 1].v.tc[0] = vtx[phi_a2 + 3].v.tc[0] = 0x100;
|
||||
|
||||
@ -2615,7 +2698,7 @@ s16 func_80823A0C(PlayState* play, Vtx* vtx, s16 arg2, s16 arg3) {
|
||||
}
|
||||
}
|
||||
|
||||
return phi_t1;
|
||||
return vtxIndex;
|
||||
}
|
||||
|
||||
static s16 D_8082B11C[] = { 0, 4, 8, 12, 24, 32, 56 };
|
||||
@ -3325,6 +3408,7 @@ static uint8_t mapLeftTexModified[MAP_48x85_TEX_SIZE];
|
||||
static uint8_t mapRightTexModified[MAP_48x85_TEX_SIZE];
|
||||
static uint8_t* mapLeftTexModifiedRaw = NULL;
|
||||
static uint8_t* mapRightTexModifiedRaw = NULL;
|
||||
static uint8_t mapBlendMask[MAP_48x85_TEX_WIDTH * MAP_48x85_TEX_HEIGHT];
|
||||
|
||||
// Load dungeon maps into the interface context
|
||||
// SoH [General] - Modified to account for our resource system and HD textures
|
||||
@ -3356,19 +3440,16 @@ void KaleidoScope_LoadDungeonMap(PlayState* play) {
|
||||
size_t size = (width * height) / 2; // account for CI4 size
|
||||
|
||||
// Resource size being larger than the calculated CI size means it is most likely not a CI4 texture
|
||||
// Abort early end undo the blended effect by clearing the mask to avoid crashing
|
||||
// Abort early and unregister the blended effect to avoid crashing
|
||||
if (size < ResourceGetTexSizeByName(interfaceCtx->mapSegmentName[0])) {
|
||||
if (mapBlendMask[0] != 0) {
|
||||
for (size_t i = 0; i < ARRAY_COUNT(mapBlendMask); i++) {
|
||||
mapBlendMask[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
interfaceCtx->mapSegment[0] = NULL;
|
||||
interfaceCtx->mapSegment[1] = NULL;
|
||||
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[0], mapBlendMask, NULL);
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[1], mapBlendMask, NULL);
|
||||
Gfx_UnregisterBlendedTexture(interfaceCtx->mapSegmentName[0]);
|
||||
Gfx_UnregisterBlendedTexture(interfaceCtx->mapSegmentName[1]);
|
||||
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[0]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3403,6 +3484,11 @@ void KaleidoScope_LoadDungeonMap(PlayState* play) {
|
||||
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[0], mapBlendMask, interfaceCtx->mapSegment[0]);
|
||||
Gfx_RegisterBlendedTexture(interfaceCtx->mapSegmentName[1], mapBlendMask, interfaceCtx->mapSegment[1]);
|
||||
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[0]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegmentName[1]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegment[0]);
|
||||
Gfx_TextureCacheDelete(interfaceCtx->mapSegment[1]);
|
||||
}
|
||||
|
||||
static uint8_t registeredDungeonMapTextureHook = false;
|
||||
@ -3443,6 +3529,11 @@ void KaleidoScope_UpdateDungeonMap(PlayState* play) {
|
||||
KaleidoScope_LoadDungeonMap(play);
|
||||
Map_SetFloorPalettesData(play, pauseCtx->dungeonMapSlot - 3);
|
||||
|
||||
// Copy the map palette values to all pulse palettes
|
||||
for (uint8_t i = 0; i < ARRAY_COUNT(interfaceCtx->mapPalettesPulse); i++) {
|
||||
memcpy(interfaceCtx->mapPalettesPulse[i], interfaceCtx->mapPalette, sizeof(interfaceCtx->mapPalette));
|
||||
}
|
||||
|
||||
s32 size = MAP_48x85_TEX_SIZE;
|
||||
|
||||
if (ResourceMgr_TexIsRaw(interfaceCtx->mapSegmentName[0])) {
|
||||
|
Loading…
Reference in New Issue
Block a user