mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-02-22 21:51:55 -05:00
Revert "Revert "Merge branch 'develop-zhora' into rando-settings-overhaul""
This reverts commit 109485188cfc8c47698ebb53b009cf852a17ef58.
This commit is contained in:
parent
1c384c5b3e
commit
0e4169ee84
1
.gitignore
vendored
1
.gitignore
vendored
@ -405,3 +405,4 @@ tags
|
|||||||
oot.otr
|
oot.otr
|
||||||
*.sav
|
*.sav
|
||||||
shipofharkinian.ini
|
shipofharkinian.ini
|
||||||
|
shipofharkinian.json
|
@ -12,7 +12,7 @@
|
|||||||
8. Build the solution.
|
8. Build the solution.
|
||||||
9. Launching `OTRExporter/extract_assets.py` will generate an `oot.otr` archive file in `OTRExporter/oot.otr`.
|
9. Launching `OTRExporter/extract_assets.py` will generate an `oot.otr` archive file in `OTRExporter/oot.otr`.
|
||||||
10. Run `soh/soh.sln`
|
10. Run `soh/soh.sln`
|
||||||
11. Switch the solution to `Release x86`.
|
11. Switch the solution to `Release x86` or `Release x64`.
|
||||||
12. Build the solution.
|
12. Build the solution.
|
||||||
13. Copy the `OTRExporter/oot.otr` archive file to `soh/Release`.
|
13. Copy the `OTRExporter/oot.otr` archive file to `soh/Release`.
|
||||||
14. Launch `soh.exe`.
|
14. Launch `soh.exe`.
|
||||||
@ -63,9 +63,10 @@ make setup -j8 DEBUG=0
|
|||||||
# Compile the code (watch the -j parameter as above)
|
# Compile the code (watch the -j parameter as above)
|
||||||
make -j8 DEBUG=0
|
make -j8 DEBUG=0
|
||||||
# Create macOS app bundle
|
# Create macOS app bundle
|
||||||
make filledappbundle
|
make appbundle
|
||||||
```
|
```
|
||||||
9. Launch soh app in the soh folder!
|
9. Copy your OTR file to ~/Library/Application\ Support/com.shipofharkinian.soh
|
||||||
|
10. Launch soh app in the soh folder!
|
||||||
|
|
||||||
# Compatible Roms
|
# Compatible Roms
|
||||||
```
|
```
|
||||||
|
9
Jenkinsfile
vendored
9
Jenkinsfile
vendored
@ -125,6 +125,11 @@ pipeline {
|
|||||||
agent {
|
agent {
|
||||||
label "SoH-Mac-Builders"
|
label "SoH-Mac-Builders"
|
||||||
}
|
}
|
||||||
|
environment {
|
||||||
|
CC = 'clang -arch arm64 -arch x86_64'
|
||||||
|
CXX = 'clang++ -arch arm64 -arch x86_64'
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.15
|
||||||
|
}
|
||||||
steps {
|
steps {
|
||||||
checkout([
|
checkout([
|
||||||
$class: 'GitSCM',
|
$class: 'GitSCM',
|
||||||
@ -137,8 +142,8 @@ pipeline {
|
|||||||
sh '''
|
sh '''
|
||||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||||
cd soh
|
cd soh
|
||||||
export CC="clang -arch arm64 -arch x86_64"; export CXX="clang++ -arch arm64 -arch x86_64"; make setup -j4 OPTFLAGS=-O2 DEBUG=0 LD="ld"
|
make setup -j4 OPTFLAGS=-O2 DEBUG=0 LD="ld"
|
||||||
export CC="clang -arch arm64 -arch x86_64"; export CXX="clang++ -arch arm64 -arch x86_64"; make -j4 DEBUG=0 OPTFLAGS=-O2 LD="ld"
|
make -j4 DEBUG=0 OPTFLAGS=-O2 LD="ld"
|
||||||
make -j4 appbundle
|
make -j4 appbundle
|
||||||
mv ../README.md readme.txt
|
mv ../README.md readme.txt
|
||||||
7z a soh-mac.7z soh.app readme.txt
|
7z a soh-mac.7z soh.app readme.txt
|
||||||
|
@ -4,10 +4,15 @@ import os, sys, shutil
|
|||||||
import shutil
|
import shutil
|
||||||
from rom_info import Z64Rom
|
from rom_info import Z64Rom
|
||||||
import rom_chooser
|
import rom_chooser
|
||||||
|
import struct
|
||||||
|
|
||||||
def BuildOTR(xmlPath, rom):
|
def BuildOTR(xmlPath, rom):
|
||||||
shutil.copytree("assets", "Extract/assets")
|
shutil.copytree("assets", "Extract/assets")
|
||||||
|
|
||||||
|
checksum = int(Z64Rom(rom).checksum.value, 16)
|
||||||
|
with open("Extract/version", "wb") as f:
|
||||||
|
f.write(struct.pack('<L', checksum))
|
||||||
|
|
||||||
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPDTR/ZAPD.out"
|
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPDTR/ZAPD.out"
|
||||||
execStr += " ed -i %s -b %s -fl CFG/filelists -o placeholder -osf placeholder -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, rom)
|
execStr += " ed -i %s -b %s -fl CFG/filelists -o placeholder -osf placeholder -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, rom)
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ Other shortcuts:
|
|||||||
| Alt+Enter | Fullscreen (DirectX) |
|
| Alt+Enter | Fullscreen (DirectX) |
|
||||||
| Ctrl+R | Reset |
|
| Ctrl+R | Reset |
|
||||||
|
|
||||||
Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX.
|
Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.json` configuration file in notepad and add `sdl` to the quotes in `"GfxBackend": ""` for OpenGL or leave blank for DirectX.
|
||||||
|
|
||||||
## Take The Survey
|
## Take The Survey
|
||||||
Want to use cartridge readers in tandem with the OTRGui?
|
Want to use cartridge readers in tandem with the OTRGui?
|
||||||
|
@ -45,11 +45,11 @@ ifneq ($(DEPRECATION_ON),0)
|
|||||||
endif
|
endif
|
||||||
# CXXFLAGS += -DTEXTURE_DEBUG
|
# CXXFLAGS += -DTEXTURE_DEBUG
|
||||||
|
|
||||||
LDFLAGS := -lm -ldl \
|
LDFLAGS := -Llib/libgfxd -L../libultraship -L../StormLib/build \
|
||||||
-L../StormLib/build -L../libultraship -lbz2 -pthread -lultraship -lstorm
|
-pthread -lgfxd -lultraship ZAPDUtils/ZAPDUtils.a -lstorm -lbz2 -lm -ldl
|
||||||
|
|
||||||
ifeq ($(UNAME), Darwin)
|
ifeq ($(UNAME), Darwin)
|
||||||
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL
|
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation
|
||||||
INC += $(shell pkg-config --cflags libpng)
|
INC += $(shell pkg-config --cflags libpng)
|
||||||
else
|
else
|
||||||
LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse
|
LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse
|
||||||
@ -137,4 +137,4 @@ ZAPDUtils:
|
|||||||
|
|
||||||
# Linking
|
# Linking
|
||||||
ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils StormLib
|
ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils StormLib
|
||||||
$(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a ../StormLib/build/libstorm.a $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION)
|
$(CXX) $(CXXFLAGS) $(O_FILES) $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION)
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
curl -sSfLO "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
curl -sSfLO "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
||||||
chmod a+x linuxdeploy*.AppImage
|
chmod a+x linuxdeploy*.AppImage
|
||||||
curl -sSfLO "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
|
curl -sSfL https://github.com$(curl https://github.com/probonopd/go-appimage/releases | grep "mkappimage-.*-x86_64.AppImage" | head -n 1 | cut -d '"' -f 2) -o mkappimage.AppImage
|
||||||
chmod a+x appimagetool*.AppImage
|
chmod a+x mkappimage.AppImage
|
||||||
|
|
||||||
mkdir -p AppDir/usr/bin
|
mkdir -p AppDir/usr/bin
|
||||||
cp appimage/{soh.desktop,soh.sh} AppDir/
|
cp appimage/{soh.desktop,soh.sh} AppDir/
|
||||||
@ -30,5 +30,5 @@ export UPD_INFO="gh-releases-zsync|HarbourMasters|Shipwright-linux|develop|SOH-L
|
|||||||
|
|
||||||
cd /soh
|
cd /soh
|
||||||
|
|
||||||
./appimagetool-x86_64.AppImage --appimage-extract-and-run ./AppDir "SOH-Linux.AppImage"
|
VERSION=Linux ./mkappimage.AppImage --appimage-extract-and-run ./AppDir # "SOH-Linux-x86_64.AppImage"
|
||||||
|
mv SOH-Linux-x86_64.AppImage SOH-Linux.AppImage # Keep Original Name
|
||||||
|
@ -3,6 +3,7 @@ HERE="$(dirname "$(readlink -f "${0}")")"/../..
|
|||||||
|
|
||||||
export PATH="$HERE"/bin:"$HERE"/usr/bin:"$PATH"
|
export PATH="$HERE"/bin:"$HERE"/usr/bin:"$PATH"
|
||||||
export LD_LIBRARY_PATH="$HERE"/usr/lib:"$LD_LIBRARY_PATH"
|
export LD_LIBRARY_PATH="$HERE"/usr/lib:"$LD_LIBRARY_PATH"
|
||||||
|
export ZENITY=$(command -v zenity)
|
||||||
|
|
||||||
while [[ ! -e "$PWD"/oot.otr ]]; do
|
while [[ ! -e "$PWD"/oot.otr ]]; do
|
||||||
export ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)"
|
export ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)"
|
||||||
@ -14,24 +15,38 @@ while [[ ! -e "$PWD"/oot.otr ]]; do
|
|||||||
ln -s "$OLDPWD"/*.*64 "$ASSETDIR"/tmp/rom.z64
|
ln -s "$OLDPWD"/*.*64 "$ASSETDIR"/tmp/rom.z64
|
||||||
cp -r "$ASSETDIR"/assets/game/ship_of_harkinian "$ASSETDIR"/Extract/assets/
|
cp -r "$ASSETDIR"/assets/game/ship_of_harkinian "$ASSETDIR"/Extract/assets/
|
||||||
cd "$ASSETDIR"
|
cd "$ASSETDIR"
|
||||||
case $(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }') in
|
ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')
|
||||||
|
case "$ROMHASH" in
|
||||||
cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
|
cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
|
||||||
ROM=GC_NMQ_D;;
|
ROM=GC_NMQ_D;;
|
||||||
0227d7c0074f2d0ac935631990da8ec5914597b4)
|
0227d7c0074f2d0ac935631990da8ec5914597b4)
|
||||||
ROM=GC_NMQ_PAL_F;;
|
ROM=GC_NMQ_PAL_F;;
|
||||||
*)
|
*)
|
||||||
|
if [ -n "$ZENITY" ]; then
|
||||||
|
zenity --error --timeout=10 --text="ROM hash <b>$ROMHASH</b> does not match" --title="Incorrect ROM file" --width=500 --width=200
|
||||||
|
else
|
||||||
echo -e "\nrom hash does not match\n"
|
echo -e "\nrom hash does not match\n"
|
||||||
|
fi
|
||||||
exit;;
|
exit;;
|
||||||
esac
|
esac
|
||||||
|
if [ -n "$ZENITY" ]; then
|
||||||
|
(echo "# 25%"; echo "25"; sleep 2; echo "# 50%"; echo "50"; sleep 3; echo "# 75%"; echo "75"; sleep 2; echo "# 100%"; echo "100"; sleep 3) |
|
||||||
|
zenity --progress --title="OTR Generating..." --timeout=10 --percentage=0 --icon-name=soh --window-icon=soh.png --height=80 --width=400 &
|
||||||
|
else
|
||||||
echo "Processing..."
|
echo "Processing..."
|
||||||
|
fi
|
||||||
assets/extractor/ZAPD.out ed -eh -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR > /dev/null 2>&1
|
assets/extractor/ZAPD.out ed -eh -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR > /dev/null 2>&1
|
||||||
cp "$ASSETDIR"/oot.otr "$OLDPWD"
|
cp "$ASSETDIR"/oot.otr "$OLDPWD"
|
||||||
echo "Restart $APPIMAGE to play!"
|
echo "Restart $APPIMAGE to play!"
|
||||||
sleep 3
|
sleep 3
|
||||||
rm -r "$ASSETDIR"
|
rm -r "$ASSETDIR"
|
||||||
break
|
break
|
||||||
|
else
|
||||||
|
if [ -n "$ZENITY" ]; then
|
||||||
|
zenity --error --timeout=5 --text="Place ROM in $OWD" --title="Missing ROM file" --width=500 --width=200
|
||||||
else
|
else
|
||||||
echo -e "\nPlace ROM in this folder\n"
|
echo -e "\nPlace ROM in this folder\n"
|
||||||
|
fi
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -11,6 +11,15 @@ DEBUG ?= 1
|
|||||||
OPTFLAGS ?= -O0
|
OPTFLAGS ?= -O0
|
||||||
LTO ?= 0
|
LTO ?= 0
|
||||||
|
|
||||||
|
# flag to save whether the compiler being used is clang or gcc by checking CXX --version
|
||||||
|
CXX_IS_CLANG ?= $(shell $(CXX) --version | grep -c clang)
|
||||||
|
ifeq ($(CXX_IS_CLANG),1)
|
||||||
|
MXX := $(CXX)
|
||||||
|
else
|
||||||
|
MXX ?= clang++
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
WARN := -Wall -Wextra -Werror \
|
WARN := -Wall -Wextra -Werror \
|
||||||
-Wno-unused-variable \
|
-Wno-unused-variable \
|
||||||
-Wno-unused-parameter \
|
-Wno-unused-parameter \
|
||||||
@ -29,8 +38,7 @@ WARN := -Wall -Wextra -Werror \
|
|||||||
CWARN :=
|
CWARN :=
|
||||||
CXXWARN := -Wno-deprecated-enum-enum-conversion -Wno-deprecated-copy
|
CXXWARN := -Wno-deprecated-enum-enum-conversion -Wno-deprecated-copy
|
||||||
|
|
||||||
COMPILER_VERSION := $(shell $(CXX) --version)
|
ifneq ($(CXX_IS_CLANG),1)
|
||||||
ifneq '' '$(findstring g++,$(COMPILER_VERSION))'
|
|
||||||
WARN += -Wno-error=stringop-overflow
|
WARN += -Wno-error=stringop-overflow
|
||||||
CXXWARN += -Wno-error=maybe-uninitialized
|
CXXWARN += -Wno-error=maybe-uninitialized
|
||||||
endif
|
endif
|
||||||
@ -39,12 +47,17 @@ CXXFLAGS := $(WARN) $(CXXWARN) -std=c++20 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG
|
|||||||
CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0
|
CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0
|
||||||
CPPFLAGS := -MMD
|
CPPFLAGS := -MMD
|
||||||
|
|
||||||
ifeq ($(UNAME), Darwin) #APPLE
|
MMFLAGS := -Wno-deprecated-declarations -ObjC++ -fobjc-weak -fobjc-arc
|
||||||
CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL
|
|
||||||
|
# if not using clang, ask clang to use gcc standard library
|
||||||
|
ifneq ($(CXX_IS_CLANG),1)
|
||||||
|
STD_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | head -n 1)
|
||||||
|
CXX_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | tail -n 1)
|
||||||
|
MMFLAGS += -stdlib++-isystem ${STD_ISYSTEM} -cxx-isystem ${CXX_ISYSTEM}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(UNAME), Linux)
|
ifeq ($(UNAME), Darwin) #APPLE
|
||||||
WARN += -Wno-error=stringop-overflow # This is required with clang on Linux.
|
CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL -framework Foundation
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(DEBUG),0)
|
ifneq ($(DEBUG),0)
|
||||||
@ -69,6 +82,7 @@ CXX_FILES := \
|
|||||||
$(shell find libultraship/Lib/Fast3D -name "*.cpp") \
|
$(shell find libultraship/Lib/Fast3D -name "*.cpp") \
|
||||||
$(shell find libultraship -maxdepth 1 -name "*.cpp") \
|
$(shell find libultraship -maxdepth 1 -name "*.cpp") \
|
||||||
$(shell find libultraship/Lib/ImGui -maxdepth 1 -name "*.cpp") \
|
$(shell find libultraship/Lib/ImGui -maxdepth 1 -name "*.cpp") \
|
||||||
|
$(shell find libultraship/Lib/Mercury -maxdepth 1 -name "*.cpp") \
|
||||||
libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \
|
libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \
|
||||||
libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \
|
libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \
|
||||||
libultraship/Lib/StrHash64.cpp \
|
libultraship/Lib/StrHash64.cpp \
|
||||||
@ -78,12 +92,19 @@ C_FILES := \
|
|||||||
libultraship/mixer.c \
|
libultraship/mixer.c \
|
||||||
libultraship/Lib/stb/stb_impl.c
|
libultraship/Lib/stb/stb_impl.c
|
||||||
|
|
||||||
|
MM_FILES := \
|
||||||
|
libultraship/OSXFolderManager.mm
|
||||||
|
|
||||||
FMT_FILES := $(shell find libultraship/ -type f \( -name "*.cpp" -o -name "*.h" \) -a -not -path "libultraship/Lib/*")
|
FMT_FILES := $(shell find libultraship/ -type f \( -name "*.cpp" -o -name "*.h" \) -a -not -path "libultraship/Lib/*")
|
||||||
|
|
||||||
O_FILES := \
|
O_FILES := \
|
||||||
$(CXX_FILES:%.cpp=build/%.o) \
|
$(CXX_FILES:%.cpp=build/%.o) \
|
||||||
$(C_FILES:%.c=build/%.o)
|
$(C_FILES:%.c=build/%.o)
|
||||||
|
|
||||||
|
ifeq ($(UNAME), Darwin) #APPLE
|
||||||
|
O_FILES += $(MM_FILES:%.mm=build/%.o)
|
||||||
|
endif
|
||||||
|
|
||||||
D_FILES := $(O_FILES:%.o=%.d)
|
D_FILES := $(O_FILES:%.o=%.d)
|
||||||
|
|
||||||
LIB := libultraship.a
|
LIB := libultraship.a
|
||||||
@ -94,6 +115,7 @@ INC_DIRS := $(addprefix -I, \
|
|||||||
libultraship/Lib/spdlog \
|
libultraship/Lib/spdlog \
|
||||||
libultraship/Lib/spdlog/include \
|
libultraship/Lib/spdlog/include \
|
||||||
libultraship/Lib/ImGui \
|
libultraship/Lib/ImGui \
|
||||||
|
libultraship/Lib/Mercury \
|
||||||
libultraship \
|
libultraship \
|
||||||
../StormLib/src \
|
../StormLib/src \
|
||||||
)
|
)
|
||||||
@ -117,6 +139,9 @@ build/%.o: %.cpp
|
|||||||
build/%.o: %.c
|
build/%.o: %.c
|
||||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
|
||||||
|
|
||||||
|
build/%.o: %.mm
|
||||||
|
$(MXX) $(MMFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
|
||||||
|
|
||||||
$(LIB): $(O_FILES)
|
$(LIB): $(O_FILES)
|
||||||
$(AR) rcs $@ $^
|
$(AR) rcs $@ $^
|
||||||
|
|
||||||
|
@ -1,164 +0,0 @@
|
|||||||
#include "ConfigFile.h"
|
|
||||||
#include "spdlog/spdlog.h"
|
|
||||||
#include "GlobalCtx2.h"
|
|
||||||
#include "Window.h"
|
|
||||||
#include "GameSettings.h"
|
|
||||||
|
|
||||||
namespace Ship {
|
|
||||||
ConfigFile::ConfigFile(std::shared_ptr<GlobalCtx2> Context, const std::string& Path) : Context(Context), Path(Path), File(Path.c_str()) {
|
|
||||||
if (Path.empty()) {
|
|
||||||
SPDLOG_ERROR("ConfigFile received an empty file name");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!File.read(Val)) {
|
|
||||||
if (!CreateDefaultConfig()) {
|
|
||||||
SPDLOG_ERROR("Failed to create default configs");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigFile::~ConfigFile() {
|
|
||||||
if (!Save()) {
|
|
||||||
SPDLOG_ERROR("Failed to save configs!!!");
|
|
||||||
}
|
|
||||||
|
|
||||||
SPDLOG_INFO("destruct configfile");
|
|
||||||
}
|
|
||||||
|
|
||||||
mINI::INIMap<std::string>& ConfigFile::operator[](const std::string& Section) {
|
|
||||||
return Val[Section];
|
|
||||||
}
|
|
||||||
|
|
||||||
mINI::INIMap<std::string> ConfigFile::get(const std::string& Section) {
|
|
||||||
return Val.get(Section);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigFile::has(const std::string& Section) {
|
|
||||||
return Val.has(Section);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigFile::remove(const std::string& Section) {
|
|
||||||
return Val.remove(Section);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigFile::clear() {
|
|
||||||
Val.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t ConfigFile::size() const {
|
|
||||||
return Val.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigFile::Save() {
|
|
||||||
return File.write(Val);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigFile::CreateDefaultConfig() {
|
|
||||||
(*this)["ARCHIVE"]["Main Archive"] = "oot.otr";
|
|
||||||
(*this)["ARCHIVE"]["Patches Directory"] = "";
|
|
||||||
|
|
||||||
(*this)["SAVE"]["Save Filename"] = "oot_save.sav";
|
|
||||||
|
|
||||||
(*this)["CONTROLLERS"]["CONTROLLER 1"] = "Auto";
|
|
||||||
(*this)["CONTROLLERS"]["CONTROLLER 2"] = "Unplugged";
|
|
||||||
(*this)["CONTROLLERS"]["CONTROLLER 3"] = "Unplugged";
|
|
||||||
(*this)["CONTROLLERS"]["CONTROLLER 4"] = "Unplugged";
|
|
||||||
|
|
||||||
(*this)["KEYBOARD SHORTCUTS"]["KEY_FULLSCREEN"] = std::to_string(0x044);
|
|
||||||
(*this)["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"] = std::to_string(0x029);
|
|
||||||
|
|
||||||
(*this)["WINDOW"]["WINDOW WIDTH"] = std::to_string(640);
|
|
||||||
(*this)["WINDOW"]["WINDOW HEIGHT"] = std::to_string(480);
|
|
||||||
(*this)["WINDOW"]["FULLSCREEN WIDTH"] = std::to_string(1920);
|
|
||||||
(*this)["WINDOW"]["FULLSCREEN HEIGHT"] = std::to_string(1080);
|
|
||||||
(*this)["WINDOW"]["FULLSCREEN"] = std::to_string(false);
|
|
||||||
(*this)["WINDOW"]["GFX BACKEND"] = "";
|
|
||||||
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CRIGHT)] = std::to_string(0x14D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CLEFT)] = std::to_string(0x14B);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CDOWN)] = std::to_string(0x150);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CUP)] = std::to_string(0x148);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_R)] = std::to_string(0x013);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_L)] = std::to_string(0x012);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DRIGHT)] = std::to_string(0x023);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DLEFT)] = std::to_string(0x021);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DDOWN)] = std::to_string(0x022);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DUP)] = std::to_string(0x014);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_START)] = std::to_string(0x039);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_Z)] = std::to_string(0x02C);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_B)] = std::to_string(0x02E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_A)] = std::to_string(0x02D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKRIGHT)] = std::to_string(0x020);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKLEFT)] = std::to_string(0x01E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKDOWN)] = std::to_string(0x01F);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKUP)] = std::to_string(0x011);
|
|
||||||
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CRIGHT)] = std::to_string(0x14D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CLEFT)] = std::to_string(0x14B);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CDOWN)] = std::to_string(0x150);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CUP)] = std::to_string(0x148);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_R)] = std::to_string(0x013);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_L)] = std::to_string(0x012);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DRIGHT)] = std::to_string(0x023);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DLEFT)] = std::to_string(0x021);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DDOWN)] = std::to_string(0x022);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DUP)] = std::to_string(0x014);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_START)] = std::to_string(0x039);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_Z)] = std::to_string(0x02C);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_B)] = std::to_string(0x02E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_A)] = std::to_string(0x02D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKRIGHT)] = std::to_string(0x020);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKLEFT)] = std::to_string(0x01E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKDOWN)] = std::to_string(0x01F);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKUP)] = std::to_string(0x011);
|
|
||||||
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CRIGHT)] = std::to_string(0x14D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CLEFT)] = std::to_string(0x14B);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CDOWN)] = std::to_string(0x150);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CUP)] = std::to_string(0x148);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_R)] = std::to_string(0x013);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_L)] = std::to_string(0x012);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DRIGHT)] = std::to_string(0x023);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DLEFT)] = std::to_string(0x021);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DDOWN)] = std::to_string(0x022);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DUP)] = std::to_string(0x014);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_START)] = std::to_string(0x039);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_Z)] = std::to_string(0x02C);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_B)] = std::to_string(0x02E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_A)] = std::to_string(0x02D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKRIGHT)] = std::to_string(0x020);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKLEFT)] = std::to_string(0x01E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKDOWN)] = std::to_string(0x01F);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKUP)] = std::to_string(0x011);
|
|
||||||
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CRIGHT)] = std::to_string(0x14D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CLEFT)] = std::to_string(0x14B);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CDOWN)] = std::to_string(0x150);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CUP)] = std::to_string(0x148);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_R)] = std::to_string(0x013);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_L)] = std::to_string(0x012);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DRIGHT)] = std::to_string(0x023);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DLEFT)] = std::to_string(0x021);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DDOWN)] = std::to_string(0x022);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DUP)] = std::to_string(0x014);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_START)] = std::to_string(0x039);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_Z)] = std::to_string(0x02C);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_B)] = std::to_string(0x02E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_A)] = std::to_string(0x02D);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKRIGHT)] = std::to_string(0x020);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKLEFT)] = std::to_string(0x01E);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKDOWN)] = std::to_string(0x01F);
|
|
||||||
(*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKUP)] = std::to_string(0x011);
|
|
||||||
|
|
||||||
(*this)["ENHANCEMENT SETTINGS"]["TEXT_SPEED"] = "1";
|
|
||||||
|
|
||||||
(*this)["SDL CONTROLLER 1"]["GUID"] = "";
|
|
||||||
(*this)["SDL CONTROLLER 2"]["GUID"] = "";
|
|
||||||
(*this)["SDL CONTROLLER 3"]["GUID"] = "";
|
|
||||||
(*this)["SDL CONTROLLER 4"]["GUID"] = "";
|
|
||||||
|
|
||||||
return File.generate(Val);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
#ifndef CONFIG_FILE_H
|
|
||||||
#define CONFIG_FILE_H
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include "Lib/mINI/src/mini/ini.h"
|
|
||||||
#include "UltraController.h"
|
|
||||||
#include "LUSMacros.h"
|
|
||||||
|
|
||||||
namespace Ship {
|
|
||||||
class GlobalCtx2;
|
|
||||||
|
|
||||||
class ConfigFile {
|
|
||||||
public:
|
|
||||||
ConfigFile(std::shared_ptr<GlobalCtx2> Context, const std::string& Path);
|
|
||||||
~ConfigFile();
|
|
||||||
|
|
||||||
bool Save();
|
|
||||||
|
|
||||||
// Expose the ini values.
|
|
||||||
mINI::INIMap<std::string>& operator[](const std::string& Section);
|
|
||||||
mINI::INIMap<std::string> get(const std::string& Section);
|
|
||||||
bool has(const std::string& Section);
|
|
||||||
bool remove(const std::string& Section);
|
|
||||||
void clear();
|
|
||||||
std::size_t size() const;
|
|
||||||
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool CreateDefaultConfig();
|
|
||||||
|
|
||||||
private:
|
|
||||||
mINI::INIStructure Val;
|
|
||||||
std::weak_ptr<GlobalCtx2> Context;
|
|
||||||
std::string Path;
|
|
||||||
mINI::INIFile File;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
146
libultraship/libultraship/ControlDeck.cpp
Normal file
146
libultraship/libultraship/ControlDeck.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include "ControlDeck.h"
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
|
#include "Controller.h"
|
||||||
|
#include "DisconnectedController.h"
|
||||||
|
#include "KeyboardController.h"
|
||||||
|
#include "SDLController.h"
|
||||||
|
#include <Utils/StringHelper.h>
|
||||||
|
|
||||||
|
uint8_t* controllerBits;
|
||||||
|
|
||||||
|
void Ship::ControlDeck::Init(uint8_t* bits) {
|
||||||
|
ScanPhysicalDevices();
|
||||||
|
controllerBits = bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ship::ControlDeck::ScanPhysicalDevices() {
|
||||||
|
|
||||||
|
virtualDevices.clear();
|
||||||
|
physicalDevices.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
||||||
|
if (SDL_IsGameController(i)) {
|
||||||
|
auto sdl = std::make_shared<SDLController>(i);
|
||||||
|
sdl->Open();
|
||||||
|
physicalDevices.push_back(sdl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
physicalDevices.push_back(std::make_shared<KeyboardController>());
|
||||||
|
physicalDevices.push_back(std::make_shared<DisconnectedController>());
|
||||||
|
|
||||||
|
for (const auto& device : physicalDevices) {
|
||||||
|
for (int i = 0; i < MAXCONTROLLERS; i++) {
|
||||||
|
device->CreateDefaultBinding(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAXCONTROLLERS; i++) {
|
||||||
|
virtualDevices.push_back(i == 0 ? 0 : static_cast<int>(physicalDevices.size()) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadControllerSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ship::ControlDeck::SetPhysicalDevice(int slot, int deviceSlot) {
|
||||||
|
const std::shared_ptr<Controller> backend = physicalDevices[deviceSlot];
|
||||||
|
virtualDevices[slot] = deviceSlot;
|
||||||
|
*controllerBits |= (backend->Connected()) << slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ship::ControlDeck::WriteToPad(OSContPad* pad) const {
|
||||||
|
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||||
|
physicalDevices[virtualDevices[i]]->Read(&pad[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NESTED(key, ...) StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), slot, __VA_ARGS__)
|
||||||
|
|
||||||
|
void Ship::ControlDeck::LoadControllerSettings() {
|
||||||
|
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
|
|
||||||
|
for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) {
|
||||||
|
int slot = std::stoi(val.key().substr(5));
|
||||||
|
|
||||||
|
for (size_t dev = 0; dev < physicalDevices.size(); dev++) {
|
||||||
|
std::string guid = physicalDevices[dev]->GetGuid();
|
||||||
|
if(guid != val.value()) continue;
|
||||||
|
|
||||||
|
virtualDevices[slot] = dev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||||
|
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
|
||||||
|
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& device : physicalDevices) {
|
||||||
|
|
||||||
|
std::string guid = device->GetGuid();
|
||||||
|
|
||||||
|
for (int slot = 0; slot < MAXCONTROLLERS; slot++) {
|
||||||
|
|
||||||
|
if (!(Config->rjson["Controllers"].contains(guid) && Config->rjson["Controllers"][guid].contains(StringHelper::Sprintf("Slot_%d", slot)))) continue;
|
||||||
|
|
||||||
|
auto& profile = device->profiles[slot];
|
||||||
|
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
|
||||||
|
|
||||||
|
profile.Mappings.clear();
|
||||||
|
profile.Thresholds.clear();
|
||||||
|
profile.UseRumble = Config->getBool(NESTED("Rumble.Enabled", ""));
|
||||||
|
profile.RumbleStrength = Config->getFloat(NESTED("Rumble.Strength", ""));
|
||||||
|
profile.UseGyro = Config->getBool(NESTED("Gyro.Enabled", ""));
|
||||||
|
|
||||||
|
for (auto const& val : rawProfile["Thresholds"].items()) {
|
||||||
|
profile.Thresholds[static_cast<ControllerThresholds>(std::stoi(val.key()))] = val.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& val : rawProfile["Mappings"].items()) {
|
||||||
|
device->SetButtonMapping(slot, std::stoi(val.key().substr(4)), val.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ship::ControlDeck::SaveControllerSettings() {
|
||||||
|
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||||
|
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
|
||||||
|
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& device : physicalDevices) {
|
||||||
|
|
||||||
|
int slot = 0;
|
||||||
|
std::string guid = device->GetGuid();
|
||||||
|
|
||||||
|
for (const auto& profile : device->profiles) {
|
||||||
|
|
||||||
|
if (!device->Connected()) continue;
|
||||||
|
|
||||||
|
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
|
||||||
|
Config->setBool(NESTED("Rumble.Enabled", ""), profile.UseRumble);
|
||||||
|
Config->setFloat(NESTED("Rumble.Strength", ""), profile.RumbleStrength);
|
||||||
|
Config->setBool(NESTED("Gyro.Enabled", ""), profile.UseGyro);
|
||||||
|
|
||||||
|
for (auto const& val : rawProfile["Mappings"].items()) {
|
||||||
|
Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& [key, val] : profile.Thresholds) {
|
||||||
|
Config->setFloat(NESTED("Thresholds.%d", key), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& [key, val] : profile.Mappings) {
|
||||||
|
Config->setInt(NESTED("Mappings.BTN_%d", val), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
slot++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Config->save();
|
||||||
|
}
|
20
libultraship/libultraship/ControlDeck.h
Normal file
20
libultraship/libultraship/ControlDeck.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Controller.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Ship {
|
||||||
|
|
||||||
|
class ControlDeck {
|
||||||
|
public:
|
||||||
|
std::vector<int> virtualDevices;
|
||||||
|
std::vector<std::shared_ptr<Controller>> physicalDevices = {};
|
||||||
|
void Init(uint8_t* controllerBits);
|
||||||
|
void ScanPhysicalDevices();
|
||||||
|
void WriteToPad(OSContPad* pad) const;
|
||||||
|
void LoadControllerSettings();
|
||||||
|
void SaveControllerSettings();
|
||||||
|
void SetPhysicalDevice(int slot, int deviceSlot);
|
||||||
|
};
|
||||||
|
}
|
@ -1,96 +1,80 @@
|
|||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "GlobalCtx2.h"
|
|
||||||
#include "stox.h"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
#if __APPLE__
|
||||||
|
#include <SDL_events.h>
|
||||||
|
#else
|
||||||
|
#include <SDL2/SDL_events.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
Controller::Controller(int32_t dwControllerNumber) : dwControllerNumber(dwControllerNumber) {
|
|
||||||
dwPressedButtons = 0;
|
Controller::Controller() : isRumbling(false), wStickX(0), wStickY(0), wGyroX(0), wGyroY(0), dwPressedButtons(0){
|
||||||
wStickX = 0;
|
|
||||||
wStickY = 0;
|
|
||||||
wGyroX = 0;
|
|
||||||
wGyroY = 0;
|
|
||||||
Attachment = nullptr;
|
Attachment = nullptr;
|
||||||
|
profiles.resize(MAXCONTROLLERS);
|
||||||
|
for(int slot = 0; slot < MAXCONTROLLERS; slot++) {
|
||||||
|
dwPressedButtons.push_back(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::Read(OSContPad* pad) {
|
void Controller::Read(OSContPad* pad, int32_t slot) {
|
||||||
ReadFromSource();
|
ReadFromSource(slot);
|
||||||
|
|
||||||
pad->button |= dwPressedButtons & 0xFFFF;
|
SDL_PumpEvents();
|
||||||
|
|
||||||
if (pad->stick_x == 0) {
|
// Button Inputs
|
||||||
if (dwPressedButtons & BTN_STICKLEFT) {
|
pad->button |= dwPressedButtons[slot] & 0xFFFF;
|
||||||
|
|
||||||
|
// Stick Inputs
|
||||||
|
if (wStickX == 0) {
|
||||||
|
if (dwPressedButtons[slot] & BTN_STICKLEFT) {
|
||||||
pad->stick_x = -128;
|
pad->stick_x = -128;
|
||||||
}
|
} else if (dwPressedButtons[slot] & BTN_STICKRIGHT) {
|
||||||
else if (dwPressedButtons & BTN_STICKRIGHT) {
|
|
||||||
pad->stick_x = 127;
|
pad->stick_x = 127;
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
pad->stick_x = wStickX;
|
pad->stick_x = wStickX;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (pad->stick_y == 0) {
|
if (wStickY == 0) {
|
||||||
if (dwPressedButtons & BTN_STICKDOWN) {
|
if (dwPressedButtons[slot] & BTN_STICKDOWN) {
|
||||||
pad->stick_y = -128;
|
pad->stick_y = -128;
|
||||||
}
|
} else if (dwPressedButtons[slot] & BTN_STICKUP) {
|
||||||
else if (dwPressedButtons & BTN_STICKUP) {
|
|
||||||
pad->stick_y = 127;
|
pad->stick_y = 127;
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
pad->stick_y = wStickY;
|
pad->stick_y = wStickY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stick Inputs
|
||||||
|
if (wCamX == 0) {
|
||||||
|
if (dwPressedButtons[slot] & BTN_VSTICKLEFT) {
|
||||||
|
pad->cam_x = -128 * 10.0f;
|
||||||
|
} else if (dwPressedButtons[slot] & BTN_VSTICKRIGHT) {
|
||||||
|
pad->cam_x = 127 * 10.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pad->cam_x = wCamX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wCamY == 0) {
|
||||||
|
if (dwPressedButtons[slot] & BTN_VSTICKDOWN) {
|
||||||
|
pad->cam_y = -128 * 10.0f;
|
||||||
|
} else if (dwPressedButtons[slot] & BTN_VSTICKUP) {
|
||||||
|
pad->cam_y = 127 * 10.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pad->cam_y = wCamY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gyro
|
||||||
pad->gyro_x = wGyroX;
|
pad->gyro_x = wGyroX;
|
||||||
pad->gyro_y = wGyroY;
|
pad->gyro_y = wGyroY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::SetButtonMapping(const std::string& szButtonName, int32_t dwScancode) {
|
void Controller::SetButtonMapping(int slot, int32_t n64Button, int32_t dwScancode) {
|
||||||
// Update the config value.
|
std::map<int32_t, int32_t>& Mappings = profiles[slot].Mappings;
|
||||||
std::string ConfSection = GetBindingConfSection();
|
std::erase_if(Mappings, [n64Button](const std::pair<int32_t, int32_t>& bin) { return bin.second == n64Button; });
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
Mappings[dwScancode] = n64Button;
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
Conf[ConfSection][szButtonName] = dwScancode;
|
|
||||||
|
|
||||||
// Reload the button mapping from Config
|
|
||||||
LoadBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::LoadBinding() {
|
|
||||||
std::string ConfSection = GetBindingConfSection();
|
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CRIGHT)])] = BTN_CRIGHT;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CLEFT)])] = BTN_CLEFT;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CDOWN)])] = BTN_CDOWN;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CUP)])] = BTN_CUP;
|
|
||||||
//ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CRIGHT + "_2")])] = BTN_CRIGHT;
|
|
||||||
//ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CLEFT + "_2")])] = BTN_CLEFT;
|
|
||||||
//ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CDOWN + "_2")])] = BTN_CDOWN;
|
|
||||||
//ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CUP + "_2")])] = BTN_CUP;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_R)])] = BTN_R;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_L)])] = BTN_L;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DRIGHT)])] = BTN_DRIGHT;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DLEFT)])] = BTN_DLEFT;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DDOWN)])] = BTN_DDOWN;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DUP)])] = BTN_DUP;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_START)])] = BTN_START;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_Z)])] = BTN_Z;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_B)])] = BTN_B;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_A)])] = BTN_A;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKRIGHT)])] = BTN_STICKRIGHT;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKLEFT)])] = BTN_STICKLEFT;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKDOWN)])] = BTN_STICKDOWN;
|
|
||||||
ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKUP)])] = BTN_STICKUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Controller::GetConfSection() {
|
|
||||||
return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Controller::GetBindingConfSection() {
|
|
||||||
return GetControllerType() + " CONTROLLER BINDING " + std::to_string(GetControllerNumber() + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,51 +1,81 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "UltraController.h"
|
#include "UltraController.h"
|
||||||
#include "ControllerAttachment.h"
|
#include "ControllerAttachment.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#define EXTENDED_SCANCODE_BIT (1 << 8)
|
#define EXTENDED_SCANCODE_BIT (1 << 8)
|
||||||
#define AXIS_SCANCODE_BIT (1 << 9)
|
#define AXIS_SCANCODE_BIT (1 << 9)
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
|
|
||||||
|
enum ControllerThresholds {
|
||||||
|
LEFT_STICK = 1,
|
||||||
|
RIGHT_STICK = 2,
|
||||||
|
LEFT_TRIGGER = 3,
|
||||||
|
RIGHT_TRIGGER = 4,
|
||||||
|
DRIFT_X = 5,
|
||||||
|
DRIFT_Y = 6,
|
||||||
|
SENSITIVITY = 7,
|
||||||
|
GYRO_SENSITIVITY = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceProfile {
|
||||||
|
bool UseRumble = false;
|
||||||
|
bool UseGyro = false;
|
||||||
|
float RumbleStrength = 1.0f;
|
||||||
|
std::unordered_map<ControllerThresholds, float> Thresholds;
|
||||||
|
std::map<int32_t, int32_t> Mappings;
|
||||||
|
};
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Controller(int32_t dwControllerNumber);
|
virtual ~Controller() = default;
|
||||||
|
Controller();
|
||||||
void Read(OSContPad* pad);
|
void Read(OSContPad* pad, int32_t slot);
|
||||||
virtual void ReadFromSource() = 0;
|
virtual void ReadFromSource(int32_t slot) = 0;
|
||||||
virtual void WriteToSource(ControllerCallback* controller) = 0;
|
virtual void WriteToSource(int32_t slot, ControllerCallback* controller) = 0;
|
||||||
virtual bool Connected() const = 0;
|
virtual bool Connected() const = 0;
|
||||||
virtual bool CanRumble() const = 0;
|
virtual bool CanRumble() const = 0;
|
||||||
|
virtual bool CanGyro() const = 0;
|
||||||
|
virtual void CreateDefaultBinding(int32_t slot) = 0;
|
||||||
bool isRumbling;
|
bool isRumbling;
|
||||||
|
std::vector<DeviceProfile> profiles;
|
||||||
|
|
||||||
void SetButtonMapping(const std::string& szButtonName, int32_t dwScancode);
|
virtual void ClearRawPress() = 0;
|
||||||
|
virtual int32_t ReadRawPress() = 0;
|
||||||
|
void SetButtonMapping(int slot, int32_t n64Button, int32_t dwScancode);
|
||||||
std::shared_ptr<ControllerAttachment> GetAttachment() { return Attachment; }
|
std::shared_ptr<ControllerAttachment> GetAttachment() { return Attachment; }
|
||||||
int32_t GetControllerNumber() { return dwControllerNumber; }
|
|
||||||
|
|
||||||
virtual bool HasPadConf() const = 0;
|
std::string GetGuid() { return GUID; }
|
||||||
virtual std::optional<std::string> GetPadConfSection() = 0;
|
virtual const char* GetButtonName(int slot, int n64Button) = 0;
|
||||||
|
virtual const char* GetControllerName() = 0;
|
||||||
|
|
||||||
protected:
|
|
||||||
int32_t dwPressedButtons;
|
|
||||||
std::map<int32_t, int32_t> ButtonMapping;
|
|
||||||
int8_t wStickX;
|
int8_t wStickX;
|
||||||
int8_t wStickY;
|
int8_t wStickY;
|
||||||
float wGyroX;
|
float wGyroX;
|
||||||
float wGyroY;
|
float wGyroY;
|
||||||
|
float wCamX;
|
||||||
|
float wCamY;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<int32_t> dwPressedButtons;
|
||||||
|
std::string GUID;
|
||||||
|
|
||||||
virtual std::string GetControllerType() = 0;
|
|
||||||
virtual std::string GetConfSection() = 0;
|
|
||||||
virtual std::string GetBindingConfSection() = 0;
|
|
||||||
void LoadBinding();
|
void LoadBinding();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<ControllerAttachment> Attachment;
|
std::shared_ptr<ControllerAttachment> Attachment;
|
||||||
int32_t dwControllerNumber;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ControllerEntry {
|
||||||
|
uint8_t* controllerBits;
|
||||||
|
Controller* entryIO;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <PR/ultra64/gbi.h>
|
#include <PR/ultra64/gbi.h>
|
||||||
|
#include "imgui_internal.h"
|
||||||
|
|
||||||
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ extern "C" void CVar_SetString(const char* name, const char* value) {
|
|||||||
cvar = std::make_unique<CVar>();
|
cvar = std::make_unique<CVar>();
|
||||||
}
|
}
|
||||||
cvar->type = CVAR_TYPE_STRING;
|
cvar->type = CVAR_TYPE_STRING;
|
||||||
cvar->value.valueStr = value;
|
cvar->value.valueStr = ImStrdup(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) {
|
extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) {
|
||||||
|
31
libultraship/libultraship/DisconnectedController.h
Normal file
31
libultraship/libultraship/DisconnectedController.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "Controller.h"
|
||||||
|
|
||||||
|
class DisconnectedController final : public Ship::Controller {
|
||||||
|
public:
|
||||||
|
DisconnectedController() {
|
||||||
|
GUID = "Disconnected";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::vector<std::string>, int32_t> ReadButtonPress();
|
||||||
|
void ReadFromSource(int32_t slot) override {}
|
||||||
|
const char* GetControllerName() override { return "Disconnected"; }
|
||||||
|
const char* GetButtonName(int slot, int n64Button) override { return "None"; }
|
||||||
|
void WriteToSource(int32_t slot, ControllerCallback* controller) override { }
|
||||||
|
bool Connected() const override { return false; }
|
||||||
|
bool CanRumble() const override { return false; }
|
||||||
|
bool CanGyro() const override { return false; }
|
||||||
|
|
||||||
|
void ClearRawPress() override {}
|
||||||
|
int32_t ReadRawPress() override { return -1; }
|
||||||
|
bool HasPadConf() const { return true; }
|
||||||
|
std::optional<std::string> GetPadConfSection() { return "Unk"; }
|
||||||
|
void CreateDefaultBinding(int32_t slot) override {}
|
||||||
|
protected:
|
||||||
|
std::string GetControllerType() { return "Unk"; }
|
||||||
|
std::string GetConfSection() { return "Unk"; }
|
||||||
|
std::string GetBindingConfSection() { return "Unk"; }
|
||||||
|
};
|
@ -7,7 +7,6 @@
|
|||||||
#include <PR/ultra64/pi.h>
|
#include <PR/ultra64/pi.h>
|
||||||
#include <PR/ultra64/message.h>
|
#include <PR/ultra64/message.h>
|
||||||
|
|
||||||
#include "ConfigFile.h"
|
|
||||||
#include "Cvar.h"
|
#include "Cvar.h"
|
||||||
#include "GlobalCtx2.h"
|
#include "GlobalCtx2.h"
|
||||||
#include "ImGuiImpl.h"
|
#include "ImGuiImpl.h"
|
||||||
@ -33,18 +32,6 @@ namespace Game {
|
|||||||
Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1));
|
Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadPadSettings() {
|
|
||||||
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf;
|
|
||||||
|
|
||||||
for (const auto& [i, controllers] : Ship::Window::Controllers) {
|
|
||||||
for (const auto& controller : controllers) {
|
|
||||||
if (auto padConfSection = controller->GetPadConfSection()) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadSettings() {
|
void LoadSettings() {
|
||||||
DebugConsole_LoadCVars();
|
DebugConsole_LoadCVars();
|
||||||
}
|
}
|
||||||
@ -58,6 +45,7 @@ namespace Game {
|
|||||||
ModInternal::RegisterHook<ModInternal::GfxInit>([] {
|
ModInternal::RegisterHook<ModInternal::GfxInit>([] {
|
||||||
gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", FILTER_THREE_POINT));
|
gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", FILTER_THREE_POINT));
|
||||||
SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
||||||
|
SohImGui::controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0);
|
||||||
UpdateAudio();
|
UpdateAudio();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
#include "spdlog/sinks/sohconsole_sink.h"
|
#include "spdlog/sinks/sohconsole_sink.h"
|
||||||
#include "ModManager.h"
|
#include "ModManager.h"
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "OSXFolderManager.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
std::weak_ptr<GlobalCtx2> GlobalCtx2::Context;
|
std::weak_ptr<GlobalCtx2> GlobalCtx2::Context;
|
||||||
@ -29,7 +32,23 @@ namespace Ship {
|
|||||||
return GetInstance();
|
return GetInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalCtx2::GlobalCtx2(const std::string& Name) : Name(Name), MainPath(""), PatchesPath("") {
|
std::string GlobalCtx2::GetAppDirectoryPath() {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
FolderManager folderManager;
|
||||||
|
std::string fpath = std::string(folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask));
|
||||||
|
fpath.append("/com.shipofharkinian.soh");
|
||||||
|
return fpath;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ".";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GlobalCtx2::GetPathRelativeToAppDirectory(const char* path) {
|
||||||
|
return GlobalCtx2::GetAppDirectoryPath() + "/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalCtx2::GlobalCtx2(std::string Name) : Name(std::move(Name)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,22 +59,19 @@ namespace Ship {
|
|||||||
|
|
||||||
void GlobalCtx2::InitWindow() {
|
void GlobalCtx2::InitWindow() {
|
||||||
InitLogging();
|
InitLogging();
|
||||||
Config = std::make_shared<ConfigFile>(GlobalCtx2::GetInstance(), "shipofharkinian.ini");
|
Config = std::make_shared<Mercury>(GetPathRelativeToAppDirectory("shipofharkinian.json"));
|
||||||
MainPath = (*Config)["ARCHIVE"]["Main Archive"];
|
Config->reload();
|
||||||
if (MainPath.empty()) {
|
|
||||||
MainPath = "oot.otr";
|
MainPath = Config->getString("Game.Main Archive", GetPathRelativeToAppDirectory("oot.otr"));
|
||||||
}
|
PatchesPath = Config->getString("Game.Patches Archive", GetAppDirectoryPath() + "/mods");
|
||||||
PatchesPath = (*Config)["ARCHIVE"]["Patches Directory"];
|
|
||||||
if (PatchesPath.empty()) {
|
ResMan = std::make_shared<ResourceMgr>(GetInstance(), MainPath, PatchesPath);
|
||||||
PatchesPath = "./";
|
Win = std::make_shared<Window>(GetInstance());
|
||||||
}
|
|
||||||
ResMan = std::make_shared<ResourceMgr>(GlobalCtx2::GetInstance(), MainPath, PatchesPath);
|
|
||||||
Win = std::make_shared<Window>(GlobalCtx2::GetInstance());
|
|
||||||
|
|
||||||
if (!ResMan->DidLoadSuccessfully())
|
if (!ResMan->DidLoadSuccessfully())
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
MessageBox(NULL, L"Main OTR file not found!", L"Uh oh", MB_OK);
|
MessageBox(nullptr, L"Main OTR file not found!", L"Uh oh", MB_OK);
|
||||||
#else
|
#else
|
||||||
SPDLOG_ERROR("Main OTR file not found!");
|
SPDLOG_ERROR("Main OTR file not found!");
|
||||||
#endif
|
#endif
|
||||||
@ -67,11 +83,13 @@ namespace Ship {
|
|||||||
|
|
||||||
void GlobalCtx2::InitLogging() {
|
void GlobalCtx2::InitLogging() {
|
||||||
try {
|
try {
|
||||||
|
auto logPath = GetPathRelativeToAppDirectory(("logs/" + GetName() + ".log").c_str());
|
||||||
|
|
||||||
// Setup Logging
|
// Setup Logging
|
||||||
spdlog::init_thread_pool(8192, 1);
|
spdlog::init_thread_pool(8192, 1);
|
||||||
auto SohConsoleSink = std::make_shared<spdlog::sinks::soh_sink_mt>();
|
auto SohConsoleSink = std::make_shared<spdlog::sinks::soh_sink_mt>();
|
||||||
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||||
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("logs/" + GetName() + ".log", 1024 * 1024 * 10, 10);
|
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath, 1024 * 1024 * 10, 10);
|
||||||
SohConsoleSink->set_level(spdlog::level::trace);
|
SohConsoleSink->set_level(spdlog::level::trace);
|
||||||
ConsoleSink->set_level(spdlog::level::trace);
|
ConsoleSink->set_level(spdlog::level::trace);
|
||||||
FileSink->set_level(spdlog::level::trace);
|
FileSink->set_level(spdlog::level::trace);
|
||||||
@ -87,7 +105,7 @@ namespace Ship {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalCtx2::WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size) {
|
void GlobalCtx2::WriteSaveFile(const std::filesystem::path& savePath, const uintptr_t addr, void* dramAddr, const size_t size) {
|
||||||
std::ofstream saveFile = std::ofstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
|
std::ofstream saveFile = std::ofstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
|
||||||
saveFile.seekp(addr);
|
saveFile.seekp(addr);
|
||||||
saveFile.write((char*)dramAddr, size);
|
saveFile.write((char*)dramAddr, size);
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <fstream>
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "ConfigFile.h"
|
#include "Lib/Mercury/Mercury.h"
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
class ResourceMgr;
|
class ResourceMgr;
|
||||||
@ -22,12 +23,15 @@ namespace Ship {
|
|||||||
std::shared_ptr<Window> GetWindow() { return Win; }
|
std::shared_ptr<Window> GetWindow() { return Win; }
|
||||||
std::shared_ptr<ResourceMgr> GetResourceManager() { return ResMan; }
|
std::shared_ptr<ResourceMgr> GetResourceManager() { return ResMan; }
|
||||||
std::shared_ptr<spdlog::logger> GetLogger() { return Logger; }
|
std::shared_ptr<spdlog::logger> GetLogger() { return Logger; }
|
||||||
std::shared_ptr<ConfigFile> GetConfig() { return Config; }
|
std::shared_ptr<Mercury> GetConfig() { return Config; }
|
||||||
|
|
||||||
void WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);
|
static std::string GetAppDirectoryPath();
|
||||||
|
static std::string GetPathRelativeToAppDirectory(const char* path);
|
||||||
|
|
||||||
|
void WriteSaveFile(const std::filesystem::path& savePath, uintptr_t addr, void* dramAddr, size_t size);
|
||||||
void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);
|
void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);
|
||||||
|
|
||||||
GlobalCtx2(const std::string& Name);
|
GlobalCtx2(std::string Name);
|
||||||
~GlobalCtx2();
|
~GlobalCtx2();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -38,7 +42,7 @@ namespace Ship {
|
|||||||
static std::weak_ptr <GlobalCtx2> Context;
|
static std::weak_ptr <GlobalCtx2> Context;
|
||||||
std::shared_ptr<spdlog::logger> Logger;
|
std::shared_ptr<spdlog::logger> Logger;
|
||||||
std::shared_ptr<Window> Win;
|
std::shared_ptr<Window> Win;
|
||||||
std::shared_ptr<ConfigFile> Config; // Config needs to be after the Window because we call the Window during it's destructor.
|
std::shared_ptr<Mercury> Config; // Config needs to be after the Window because we call the Window during it's destructor.
|
||||||
std::shared_ptr<ResourceMgr> ResMan;
|
std::shared_ptr<ResourceMgr> ResMan;
|
||||||
std::string Name;
|
std::string Name;
|
||||||
std::string MainPath;
|
std::string MainPath;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "UltraController.h"
|
#include "UltraController.h"
|
||||||
|
#include "Controller.h"
|
||||||
|
|
||||||
#define DEFINE_HOOK(name, type) struct name { typedef std::function<type> fn; }
|
#define DEFINE_HOOK(name, type) struct name { typedef std::function<type> fn; }
|
||||||
|
|
||||||
@ -28,12 +29,11 @@ namespace ModInternal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_HOOK(ControllerRead, void(OSContPad* cont_pad));
|
DEFINE_HOOK(ControllerRead, void(OSContPad* cont_pad));
|
||||||
|
DEFINE_HOOK(ControllerRawInput, void(Ship::Controller* backend, uint32_t raw));
|
||||||
DEFINE_HOOK(AudioInit, void());
|
DEFINE_HOOK(AudioInit, void());
|
||||||
|
|
||||||
DEFINE_HOOK(LoadTexture, void(const char* path, uint8_t** texture));
|
DEFINE_HOOK(LoadTexture, void(const char* path, uint8_t** texture));
|
||||||
|
|
||||||
DEFINE_HOOK(GfxInit, void());
|
DEFINE_HOOK(GfxInit, void());
|
||||||
|
DEFINE_HOOK(ExitGame, void());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "GameSettings.h"
|
#include "GameSettings.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "Hooks.h"
|
#include "Hooks.h"
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
#include "Lib/ImGui/imgui_internal.h"
|
#include "Lib/ImGui/imgui_internal.h"
|
||||||
#include "GlobalCtx2.h"
|
#include "GlobalCtx2.h"
|
||||||
#include "ResourceMgr.h"
|
#include "ResourceMgr.h"
|
||||||
@ -63,8 +64,11 @@ namespace SohImGui {
|
|||||||
ImGuiIO* io;
|
ImGuiIO* io;
|
||||||
Console* console = new Console;
|
Console* console = new Console;
|
||||||
GameOverlay* overlay = new GameOverlay;
|
GameOverlay* overlay = new GameOverlay;
|
||||||
|
InputEditor* controller = new InputEditor;
|
||||||
|
static ImVector<ImRect> s_GroupPanelLabelStack;
|
||||||
bool p_open = false;
|
bool p_open = false;
|
||||||
bool needs_save = false;
|
bool needs_save = false;
|
||||||
|
int lastBackendID = 0;
|
||||||
|
|
||||||
const char* filters[3] = {
|
const char* filters[3] = {
|
||||||
"Three-Point",
|
"Three-Point",
|
||||||
@ -72,10 +76,45 @@ namespace SohImGui {
|
|||||||
"None"
|
"None"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::pair<const char*, const char*> backends[] = {
|
||||||
|
#ifdef _WIN32
|
||||||
|
{ "dx11", "DirectX" },
|
||||||
|
#endif
|
||||||
|
{ "sdl", "OpenGL" }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const char* powers[9] = {
|
||||||
|
"Vanilla (1x)",
|
||||||
|
"Double (2x)",
|
||||||
|
"Quadruple (4x)",
|
||||||
|
"Octuple (8x)",
|
||||||
|
"Hexadecuple (16x)",
|
||||||
|
"Duotrigintuple (32x)",
|
||||||
|
"Quattuorsexagintuple (64x)",
|
||||||
|
"Octoviginticentuple (128x)",
|
||||||
|
"Hexaquinquagintiducentuple (256x)"
|
||||||
|
};
|
||||||
|
|
||||||
std::map<std::string, std::vector<std::string>> hiddenwindowCategories;
|
std::map<std::string, std::vector<std::string>> hiddenwindowCategories;
|
||||||
std::map<std::string, std::vector<std::string>> windowCategories;
|
std::map<std::string, std::vector<std::string>> windowCategories;
|
||||||
std::map<std::string, CustomWindow> customWindows;
|
std::map<std::string, CustomWindow> customWindows;
|
||||||
|
|
||||||
|
int GetBackendID(std::shared_ptr<Mercury> cfg) {
|
||||||
|
std::string backend = cfg->getString("Window.GfxBackend");
|
||||||
|
if (backend.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < (sizeof(backends) / sizeof(backends[0])); i++) {
|
||||||
|
if(backend == backends[i].first) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ClampFloatToInt(float value, int min, int max) {
|
int ClampFloatToInt(float value, int min, int max) {
|
||||||
return fmin(fmax(value, min), max);
|
return fmin(fmax(value, min), max);
|
||||||
}
|
}
|
||||||
@ -300,15 +339,23 @@ namespace SohImGui {
|
|||||||
io = &ImGui::GetIO();
|
io = &ImGui::GetIO();
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
io->Fonts->AddFontDefault();
|
io->Fonts->AddFontDefault();
|
||||||
|
|
||||||
|
lastBackendID = GetBackendID(GlobalCtx2::GetInstance()->GetConfig());
|
||||||
if (CVar_GetS32("gOpenMenuBar", 0) != 1) {
|
if (CVar_GetS32("gOpenMenuBar", 0) != 1) {
|
||||||
SohImGui::overlay->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu");
|
SohImGui::overlay->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto imguiIniPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui.ini");
|
||||||
|
auto imguiLogPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui_log.txt");
|
||||||
|
io->IniFilename = strcpy(new char[imguiIniPath.length() + 1], imguiIniPath.c_str());
|
||||||
|
io->LogFilename = strcpy(new char[imguiLogPath.length() + 1], imguiLogPath.c_str());
|
||||||
|
|
||||||
if (UseViewports()) {
|
if (UseViewports()) {
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||||
}
|
}
|
||||||
console->Init();
|
console->Init();
|
||||||
overlay->Init();
|
overlay->Init();
|
||||||
|
controller->Init();
|
||||||
ImGuiWMInit();
|
ImGuiWMInit();
|
||||||
ImGuiBackendInit();
|
ImGuiBackendInit();
|
||||||
|
|
||||||
@ -329,23 +376,17 @@ namespace SohImGui {
|
|||||||
LoadTexture("C-Down", "assets/ship_of_harkinian/buttons/CDown.png");
|
LoadTexture("C-Down", "assets/ship_of_harkinian/buttons/CDown.png");
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const auto& [i, controllers] : Ship::Window::Controllers)
|
|
||||||
{
|
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0);
|
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0);
|
|
||||||
needs_save = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModInternal::RegisterHook<ModInternal::ControllerRead>([](OSContPad* cont_pad) {
|
ModInternal::RegisterHook<ModInternal::ControllerRead>([](OSContPad* cont_pad) {
|
||||||
pads = cont_pad;
|
pads = cont_pad;
|
||||||
});
|
});
|
||||||
|
|
||||||
Game::InitSettings();
|
Game::InitSettings();
|
||||||
|
|
||||||
CVar_SetS32("gRandoGenerating", 0);
|
CVar_SetS32("gRandoGenerating", 0);
|
||||||
CVar_SetS32("gNewSeedGenerated", 0);
|
CVar_SetS32("gNewSeedGenerated", 0);
|
||||||
CVar_SetS32("gNewFileDropped", 0);
|
CVar_SetS32("gNewFileDropped", 0);
|
||||||
CVar_SetString("gDroppedFile", "");
|
CVar_SetString("gDroppedFile", "None");
|
||||||
Game::SaveSettings();
|
// Game::SaveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(EventImpl event) {
|
void Update(EventImpl event) {
|
||||||
@ -436,11 +477,21 @@ namespace SohImGui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue)
|
void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton)
|
||||||
{
|
{
|
||||||
int val = CVar_GetS32(cvarName, defaultValue);
|
int val = CVar_GetS32(cvarName, defaultValue);
|
||||||
|
|
||||||
ImGui::Text(text, val);
|
ImGui::Text(text, val);
|
||||||
|
if(PlusMinusButton) {
|
||||||
|
std::string MinusBTNName = " - ##";
|
||||||
|
MinusBTNName += cvarName;
|
||||||
|
if (ImGui::Button(MinusBTNName.c_str())) {
|
||||||
|
val--;
|
||||||
|
CVar_SetS32(cvarName, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::SliderInt(id, &val, min, max, format))
|
if (ImGui::SliderInt(id, &val, min, max, format))
|
||||||
{
|
{
|
||||||
@ -448,6 +499,18 @@ namespace SohImGui {
|
|||||||
needs_save = true;
|
needs_save = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(PlusMinusButton) {
|
||||||
|
std::string PlusBTNName = " + ##";
|
||||||
|
PlusBTNName += cvarName;
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
if (ImGui::Button(PlusBTNName.c_str())) {
|
||||||
|
val++;
|
||||||
|
CVar_SetS32(cvarName, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (val < min)
|
if (val < min)
|
||||||
{
|
{
|
||||||
val = min;
|
val = min;
|
||||||
@ -463,7 +526,7 @@ namespace SohImGui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage)
|
void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton)
|
||||||
{
|
{
|
||||||
float val = CVar_GetFloat(cvarName, defaultValue);
|
float val = CVar_GetFloat(cvarName, defaultValue);
|
||||||
|
|
||||||
@ -472,12 +535,36 @@ namespace SohImGui {
|
|||||||
else
|
else
|
||||||
ImGui::Text(text, static_cast<int>(100 * val));
|
ImGui::Text(text, static_cast<int>(100 * val));
|
||||||
|
|
||||||
|
if(PlusMinusButton) {
|
||||||
|
std::string MinusBTNName = " - ##";
|
||||||
|
MinusBTNName += cvarName;
|
||||||
|
if (ImGui::Button(MinusBTNName.c_str())) {
|
||||||
|
val -= 0.1f;
|
||||||
|
CVar_SetFloat(cvarName, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::SliderFloat(id, &val, min, max, format))
|
if (ImGui::SliderFloat(id, &val, min, max, format))
|
||||||
{
|
{
|
||||||
CVar_SetFloat(cvarName, val);
|
CVar_SetFloat(cvarName, val);
|
||||||
needs_save = true;
|
needs_save = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(PlusMinusButton) {
|
||||||
|
std::string PlusBTNName = " + ##";
|
||||||
|
PlusBTNName += cvarName;
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
if (ImGui::Button(PlusBTNName.c_str())) {
|
||||||
|
val += 0.1f;
|
||||||
|
CVar_SetFloat(cvarName, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (val < min)
|
if (val < min)
|
||||||
{
|
{
|
||||||
val = min;
|
val = min;
|
||||||
@ -638,6 +725,8 @@ namespace SohImGui {
|
|||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
const std::shared_ptr<Window> wnd = GlobalCtx2::GetInstance()->GetWindow();
|
const std::shared_ptr<Window> wnd = GlobalCtx2::GetInstance()->GetWindow();
|
||||||
|
const std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
|
|
||||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground |
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground |
|
||||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
|
||||||
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize;
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize;
|
||||||
@ -674,18 +763,14 @@ namespace SohImGui {
|
|||||||
needs_save = true;
|
needs_save = true;
|
||||||
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar;
|
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar;
|
||||||
ShowCursor(menu_bar, Dialogues::dMenubar);
|
ShowCursor(menu_bar, Dialogues::dMenubar);
|
||||||
|
GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->SaveControllerSettings();
|
||||||
if (CVar_GetS32("gControlNav", 0)) {
|
if (CVar_GetS32("gControlNav", 0)) {
|
||||||
if (CVar_GetS32("gOpenMenuBar", 0)) {
|
if (CVar_GetS32("gOpenMenuBar", 0)) {
|
||||||
io->ConfigFlags |=ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard;
|
io->ConfigFlags |=ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
|
io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
|
io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -725,6 +810,10 @@ namespace SohImGui {
|
|||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImGui::SetCursorPosY(0.0f);
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Audio")) {
|
if (ImGui::BeginMenu("Audio")) {
|
||||||
EnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true);
|
EnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true);
|
||||||
|
|
||||||
@ -736,11 +825,16 @@ namespace SohImGui {
|
|||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SetCursorPosY(0.0f);
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Controller"))
|
if (ImGui::BeginMenu("Controller"))
|
||||||
{
|
{
|
||||||
EnhancementCheckbox("Use Controller Navigation", "gControlNav");
|
EnhancementCheckbox("Use Controller Navigation", "gControlNav");
|
||||||
Tooltip("Allows controller navigation of the menu bar\nD-pad to move between items, A to select, and X to grab focus on the menu bar");
|
Tooltip("Allows controller navigation of the menu bar\nD-pad to move between items, A to select, and X to grab focus on the menu bar");
|
||||||
|
|
||||||
|
EnhancementCheckbox("Controller Configuration", "gControllerConfigurationEnabled");
|
||||||
|
controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
// TODO mutual exclusions -- There should be some system to prevent conclifting enhancements from being selected
|
// TODO mutual exclusions -- There should be some system to prevent conclifting enhancements from being selected
|
||||||
@ -754,44 +848,14 @@ namespace SohImGui {
|
|||||||
|
|
||||||
EnhancementCheckbox("Show Inputs", "gInputEnabled");
|
EnhancementCheckbox("Show Inputs", "gInputEnabled");
|
||||||
Tooltip("Shows currently pressed inputs on the bottom right of the screen");
|
Tooltip("Shows currently pressed inputs on the bottom right of the screen");
|
||||||
EnhancementCheckbox("Rumble Enabled", "gRumbleEnabled");
|
|
||||||
|
|
||||||
EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false);
|
EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false);
|
||||||
Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting");
|
Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting");
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
for (const auto& [i, controllers] : Ship::Window::Controllers)
|
|
||||||
{
|
|
||||||
bool hasPad = std::find_if(controllers.begin(), controllers.end(), [](const auto& c) {
|
|
||||||
return c->HasPadConf() && c->Connected();
|
|
||||||
}) != controllers.end();
|
|
||||||
|
|
||||||
if (!hasPad) continue;
|
|
||||||
|
|
||||||
auto menuLabel = "Controller " + std::to_string(i + 1);
|
|
||||||
if (ImGui::BeginMenu(menuLabel.c_str()))
|
|
||||||
{
|
|
||||||
EnhancementSliderFloat("Gyro Sensitivity: %d %%", "##GYROSCOPE", StringHelper::Sprintf("gCont%i_GyroSensitivity", i).c_str(), 0.0f, 1.0f, "", 1.0f, true);
|
|
||||||
|
|
||||||
if (ImGui::Button("Recalibrate Gyro"))
|
|
||||||
{
|
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0);
|
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0);
|
|
||||||
needs_save = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
EnhancementSliderFloat("Rumble Strength: %d %%", "##RUMBLE", StringHelper::Sprintf("gCont%i_RumbleStrength", i).c_str(), 0.0f, 1.0f, "", 1.0f, true);
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
ImGui::Separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::SetCursorPosY(0.0f);
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Graphics"))
|
if (ImGui::BeginMenu("Graphics"))
|
||||||
{
|
{
|
||||||
@ -818,6 +882,16 @@ namespace SohImGui {
|
|||||||
ImGui::Text("Jitter fix: >= %d FPS", fps);
|
ImGui::Text("Jitter fix: >= %d FPS", fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MinusBTNELT = " - ##ExtraLatencyThreshold";
|
||||||
|
std::string PlusBTNELT = " + ##ExtraLatencyThreshold";
|
||||||
|
if (ImGui::Button(MinusBTNELT.c_str())) {
|
||||||
|
val--;
|
||||||
|
CVar_SetS32(cvar, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
|
||||||
if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 250, "", ImGuiSliderFlags_AlwaysClamp))
|
if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 250, "", ImGuiSliderFlags_AlwaysClamp))
|
||||||
{
|
{
|
||||||
CVar_SetS32(cvar, val);
|
CVar_SetS32(cvar, val);
|
||||||
@ -830,6 +904,26 @@ namespace SohImGui {
|
|||||||
"to work on one frame while GPU works on the previous frame.\n"
|
"to work on one frame while GPU works on the previous frame.\n"
|
||||||
"This setting should be used when your computer is too slow\n"
|
"This setting should be used when your computer is too slow\n"
|
||||||
"to do CPU + GPU work in time.");
|
"to do CPU + GPU work in time.");
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
if (ImGui::Button(PlusBTNELT.c_str())) {
|
||||||
|
val++;
|
||||||
|
CVar_SetS32(cvar, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::Text("Renderer API (Needs reload)");
|
||||||
|
if (ImGui::BeginCombo("##RApi", backends[lastBackendID].second)) {
|
||||||
|
for (uint8_t i = 0; i < sizeof(backends) / sizeof(backends[0]); i++) {
|
||||||
|
if (ImGui::Selectable(backends[i].second, i == lastBackendID)) {
|
||||||
|
pConf->setString("Window.GfxBackend", backends[i].first);
|
||||||
|
lastBackendID = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPERIMENTAL();
|
EXPERIMENTAL();
|
||||||
@ -841,6 +935,8 @@ namespace SohImGui {
|
|||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SetCursorPosY(0.0f);
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Languages")) {
|
if (ImGui::BeginMenu("Languages")) {
|
||||||
EnhancementRadioButton("English", "gLanguages", 0);
|
EnhancementRadioButton("English", "gLanguages", 0);
|
||||||
EnhancementRadioButton("German", "gLanguages", 1);
|
EnhancementRadioButton("German", "gLanguages", 1);
|
||||||
@ -848,6 +944,8 @@ namespace SohImGui {
|
|||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SetCursorPosY(0.0f);
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Enhancements"))
|
if (ImGui::BeginMenu("Enhancements"))
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("Gameplay"))
|
if (ImGui::BeginMenu("Gameplay"))
|
||||||
@ -881,12 +979,36 @@ namespace SohImGui {
|
|||||||
|
|
||||||
if (ImGui::BeginMenu("Difficulty Options"))
|
if (ImGui::BeginMenu("Difficulty Options"))
|
||||||
{
|
{
|
||||||
EnhancementSliderInt("Damage Multiplier %dx", "##DAMAGEMUL", "gDamageMul", 1, 4, "");
|
ImGui::Text("Damage Multiplier");
|
||||||
Tooltip("Modifies all sources of damage not affected by other sliders");
|
EnhancementCombobox("gDamageMul", powers, 9, 0);
|
||||||
EnhancementSliderInt("Fall Damage Multiplier %dx", "##FALLDAMAGEMUL", "gFallDamageMul", 1, 4, "");
|
Tooltip("Modifies all sources of damage not affected by other sliders\n\
|
||||||
Tooltip("Modifies all fall damage");
|
2x: Can survive all common attacks from the start of the game\n\
|
||||||
EnhancementSliderInt("Void Damage Multiplier %dx", "##VOIDDAMAGEMUL", "gVoidDamageMul", 1, 4, "");
|
4x: Dies in 1 hit to any substantial attack from the start of the game\n\
|
||||||
Tooltip("Modifies damage taken after falling into a void");
|
8x: Can only survive trivial damage from the start of the game\n\
|
||||||
|
16x: Can survive all common attacks with max health without double defense\n\
|
||||||
|
32x: Can survive all common attacks with max health and double defense\n\
|
||||||
|
64x: Can survive trivial damage with max health without double defense\n\
|
||||||
|
128x: Can survive trivial damage with max health and double defense\n\
|
||||||
|
256x: Cannot survive damage");
|
||||||
|
ImGui::Text("Fall Damage Multiplier");
|
||||||
|
EnhancementCombobox("gFallDamageMul", powers, 8, 0);
|
||||||
|
Tooltip("Modifies all fall damage\n\
|
||||||
|
2x: Can survive all fall damage from the start of the game\n\
|
||||||
|
4x: Can only survive short fall damage from the start of the game\n\
|
||||||
|
8x: Cannot survive any fall damage from the start of the game\n\
|
||||||
|
16x: Can survive all fall damage with max health without double defense\n\
|
||||||
|
32x: Can survive all fall damage with max health and double defense\n\
|
||||||
|
64x: Can survive short fall damage with double defense\n\
|
||||||
|
128x: Cannot survive fall damage");
|
||||||
|
ImGui::Text("Void Damage Multiplier");
|
||||||
|
EnhancementCombobox("gVoidDamageMul", powers, 7, 0);
|
||||||
|
Tooltip("Modifies damage taken after falling into a void\n\
|
||||||
|
2x: Can survive void damage from the start of the game\n\
|
||||||
|
4x: Cannot survive void damage from the start of the game\n\
|
||||||
|
8x: Can survive void damage twice with max health without double defense\n\
|
||||||
|
16x: Can survive void damage with max health without double defense\n\
|
||||||
|
32x: Can survive void damage with max health and double defense\n\
|
||||||
|
64x: Cannot survive void damage");
|
||||||
|
|
||||||
EnhancementCheckbox("No Random Drops", "gNoRandomDrops");
|
EnhancementCheckbox("No Random Drops", "gNoRandomDrops");
|
||||||
Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses");
|
Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses");
|
||||||
@ -897,54 +1019,54 @@ namespace SohImGui {
|
|||||||
{
|
{
|
||||||
EnhancementCheckbox("Change Red Potion Effect", "gRedPotionEffect");
|
EnhancementCheckbox("Change Red Potion Effect", "gRedPotionEffect");
|
||||||
Tooltip("Enable the following changes to the amount of health restored by Red Potions");
|
Tooltip("Enable the following changes to the amount of health restored by Red Potions");
|
||||||
EnhancementSliderInt("Red Potion Health: %d", "##REDPOTIONHEALTH", "gRedPotionHealth", 1, 100, "");
|
EnhancementSliderInt("Red Potion Health: %d", "##REDPOTIONHEALTH", "gRedPotionHealth", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of health restored by Red Potions");
|
Tooltip("Changes the amount of health restored by Red Potions");
|
||||||
EnhancementCheckbox("Red Potion Percent Restore", "gRedPercentRestore");
|
EnhancementCheckbox("Red Potion Percent Restore", "gRedPercentRestore");
|
||||||
Tooltip("Toggles from Red Potions restoring a fixed amount of health to a percent of the player's current max health");
|
Tooltip("Toggles from Red Potions restoring a fixed amount of health to a percent of the player's current max health");
|
||||||
|
|
||||||
EnhancementCheckbox("Change Green Potion Effect", "gGreenPotionEffect");
|
EnhancementCheckbox("Change Green Potion Effect", "gGreenPotionEffect");
|
||||||
Tooltip("Enable the following changes to the amount of mana restored by Green Potions");
|
Tooltip("Enable the following changes to the amount of mana restored by Green Potions");
|
||||||
EnhancementSliderInt("Green Potion Mana: %d", "##GREENPOTIONMANA", "gGreenPotionMana", 1, 100, "");
|
EnhancementSliderInt("Green Potion Mana: %d", "##GREENPOTIONMANA", "gGreenPotionMana", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of mana restored by Green Potions, base max mana is 48, max upgraded mana is 96");
|
Tooltip("Changes the amount of mana restored by Green Potions, base max mana is 48, max upgraded mana is 96");
|
||||||
EnhancementCheckbox("Green Potion Percent Restore", "gGreenPercentRestore");
|
EnhancementCheckbox("Green Potion Percent Restore", "gGreenPercentRestore");
|
||||||
Tooltip("Toggles from Green Potions restoring a fixed amount of mana to a percent of the player's current max mana");
|
Tooltip("Toggles from Green Potions restoring a fixed amount of mana to a percent of the player's current max mana");
|
||||||
|
|
||||||
EnhancementCheckbox("Change Blue Potion Effects", "gBluePotionEffects");
|
EnhancementCheckbox("Change Blue Potion Effects", "gBluePotionEffects");
|
||||||
Tooltip("Enable the following changes to the amount of health and mana restored by Blue Potions");
|
Tooltip("Enable the following changes to the amount of health and mana restored by Blue Potions");
|
||||||
EnhancementSliderInt("Blue Potion Health: %d", "##BLUEPOTIONHEALTH", "gBluePotionHealth", 1, 100, "");
|
EnhancementSliderInt("Blue Potion Health: %d", "##BLUEPOTIONHEALTH", "gBluePotionHealth", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of health restored by Blue Potions");
|
Tooltip("Changes the amount of health restored by Blue Potions");
|
||||||
EnhancementCheckbox("Blue Potion Health Percent Restore", "gBlueHealthPercentRestore");
|
EnhancementCheckbox("Blue Potion Health Percent Restore", "gBlueHealthPercentRestore");
|
||||||
Tooltip("Toggles from Blue Potions restoring a fixed amount of health to a percent of the player's current max health");
|
Tooltip("Toggles from Blue Potions restoring a fixed amount of health to a percent of the player's current max health");
|
||||||
|
|
||||||
EnhancementSliderInt("Blue Potion Mana: %d", "##BLUEPOTIONMANA", "gBluePotionMana", 1, 100, "");
|
EnhancementSliderInt("Blue Potion Mana: %d", "##BLUEPOTIONMANA", "gBluePotionMana", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of mana restored by Blue Potions, base max mana is 48, max upgraded mana is 96");
|
Tooltip("Changes the amount of mana restored by Blue Potions, base max mana is 48, max upgraded mana is 96");
|
||||||
EnhancementCheckbox("Blue Potion Mana Percent Restore", "gBlueManaPercentRestore");
|
EnhancementCheckbox("Blue Potion Mana Percent Restore", "gBlueManaPercentRestore");
|
||||||
Tooltip("Toggles from Blue Potions restoring a fixed amount of mana to a percent of the player's current max mana");
|
Tooltip("Toggles from Blue Potions restoring a fixed amount of mana to a percent of the player's current max mana");
|
||||||
|
|
||||||
EnhancementCheckbox("Change Milk Effect", "gMilkEffect");
|
EnhancementCheckbox("Change Milk Effect", "gMilkEffect");
|
||||||
Tooltip("Enable the following changes to the amount of health restored by Milk");
|
Tooltip("Enable the following changes to the amount of health restored by Milk");
|
||||||
EnhancementSliderInt("Milk Health: %d", "##MILKHEALTH", "gMilkHealth", 1, 100, "");
|
EnhancementSliderInt("Milk Health: %d", "##MILKHEALTH", "gMilkHealth", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of health restored by Milk");
|
Tooltip("Changes the amount of health restored by Milk");
|
||||||
EnhancementCheckbox("Milk Percent Restore", "gMilkPercentRestore");
|
EnhancementCheckbox("Milk Percent Restore", "gMilkPercentRestore");
|
||||||
Tooltip("Toggles from Milk restoring a fixed amount of health to a percent of the player's current max health");
|
Tooltip("Toggles from Milk restoring a fixed amount of health to a percent of the player's current max health");
|
||||||
|
|
||||||
EnhancementCheckbox("Separate Half Milk Effect", "gSeparateHalfMilkEffect");
|
EnhancementCheckbox("Separate Half Milk Effect", "gSeparateHalfMilkEffect");
|
||||||
Tooltip("Enable the following changes to the amount of health restored by Half Milk\nIf this is disabled, Half Milk will behave the same as Full Milk.");
|
Tooltip("Enable the following changes to the amount of health restored by Half Milk\nIf this is disabled, Half Milk will behave the same as Full Milk.");
|
||||||
EnhancementSliderInt("Half Milk Health: %d", "##HALFMILKHEALTH", "gHalfMilkHealth", 1, 100, "");
|
EnhancementSliderInt("Half Milk Health: %d", "##HALFMILKHEALTH", "gHalfMilkHealth", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of health restored by Half Milk");
|
Tooltip("Changes the amount of health restored by Half Milk");
|
||||||
EnhancementCheckbox("Half Milk Percent Restore", "gHalfMilkPercentRestore");
|
EnhancementCheckbox("Half Milk Percent Restore", "gHalfMilkPercentRestore");
|
||||||
Tooltip("Toggles from Half Milk restoring a fixed amount of health to a percent of the player's current max health");
|
Tooltip("Toggles from Half Milk restoring a fixed amount of health to a percent of the player's current max health");
|
||||||
|
|
||||||
EnhancementCheckbox("Change Fairy Effect", "gFairyEffect");
|
EnhancementCheckbox("Change Fairy Effect", "gFairyEffect");
|
||||||
Tooltip("Enable the following changes to the amount of health restored by Fairies");
|
Tooltip("Enable the following changes to the amount of health restored by Fairies");
|
||||||
EnhancementSliderInt("Fairy: %d", "##FAIRYHEALTH", "gFairyHealth", 1, 100, "");
|
EnhancementSliderInt("Fairy: %d", "##FAIRYHEALTH", "gFairyHealth", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of health restored by Fairies");
|
Tooltip("Changes the amount of health restored by Fairies");
|
||||||
EnhancementCheckbox("Fairy Percent Restore", "gFairyPercentRestore");
|
EnhancementCheckbox("Fairy Percent Restore", "gFairyPercentRestore");
|
||||||
Tooltip("Toggles from Fairies restoring a fixed amount of health to a percent of the player's current max health");
|
Tooltip("Toggles from Fairies restoring a fixed amount of health to a percent of the player's current max health");
|
||||||
|
|
||||||
EnhancementCheckbox("Change Fairy Revive Effect", "gFairyReviveEffect");
|
EnhancementCheckbox("Change Fairy Revive Effect", "gFairyReviveEffect");
|
||||||
Tooltip("Enable the following changes to the amount of health restored by Fairy Revivals");
|
Tooltip("Enable the following changes to the amount of health restored by Fairy Revivals");
|
||||||
EnhancementSliderInt("Fairy Revival: %d", "##FAIRYREVIVEHEALTH", "gFairyReviveHealth", 1, 100, "");
|
EnhancementSliderInt("Fairy Revival: %d", "##FAIRYREVIVEHEALTH", "gFairyReviveHealth", 1, 100, "", 0, true);
|
||||||
Tooltip("Changes the amount of health restored by Fairy Revivals");
|
Tooltip("Changes the amount of health restored by Fairy Revivals");
|
||||||
EnhancementCheckbox("Fairy Revive Percent Restore", "gFairyRevivePercentRestore");
|
EnhancementCheckbox("Fairy Revive Percent Restore", "gFairyRevivePercentRestore");
|
||||||
Tooltip("Toggles from Fairy Revivals restoring a fixed amount of health to a percent of the player's current max health");
|
Tooltip("Toggles from Fairy Revivals restoring a fixed amount of health to a percent of the player's current max health");
|
||||||
@ -1033,7 +1155,7 @@ namespace SohImGui {
|
|||||||
EnhancementRadioButton("Random cycle", "gPauseLiveLink", 16);
|
EnhancementRadioButton("Random cycle", "gPauseLiveLink", 16);
|
||||||
Tooltip("Randomize the animation played on the menu after a certain time");
|
Tooltip("Randomize the animation played on the menu after a certain time");
|
||||||
if (CVar_GetS32("gPauseLiveLink", 0) >= 16) {
|
if (CVar_GetS32("gPauseLiveLink", 0) >= 16) {
|
||||||
EnhancementSliderInt("Frame to wait: %d", "##MinFrameCount", "gMinFrameCount", 1, 1000, "");
|
EnhancementSliderInt("Frame to wait: %d", "##MinFrameCount", "gMinFrameCount", 1, 1000, "", 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
@ -1105,6 +1227,16 @@ namespace SohImGui {
|
|||||||
ImGui::Text("Frame interpolation: %d FPS", fps);
|
ImGui::Text("Frame interpolation: %d FPS", fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MinusBTNFPSI = " - ##FPSInterpolation";
|
||||||
|
std::string PlusBTNFPSI = " + ##FPSInterpolation";
|
||||||
|
if (ImGui::Button(MinusBTNFPSI.c_str())) {
|
||||||
|
val--;
|
||||||
|
CVar_SetS32(fps_cvar, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
|
||||||
if (ImGui::SliderInt("##FPSInterpolation", &val, 20, 250, "", ImGuiSliderFlags_AlwaysClamp))
|
if (ImGui::SliderInt("##FPSInterpolation", &val, 20, 250, "", ImGuiSliderFlags_AlwaysClamp))
|
||||||
{
|
{
|
||||||
CVar_SetS32(fps_cvar, val);
|
CVar_SetS32(fps_cvar, val);
|
||||||
@ -1117,6 +1249,14 @@ namespace SohImGui {
|
|||||||
"and might give a worse result.\n"
|
"and might give a worse result.\n"
|
||||||
"For consistent input lag, set this value and your monitor's refresh rate to a multiple of 20\n"
|
"For consistent input lag, set this value and your monitor's refresh rate to a multiple of 20\n"
|
||||||
"Ctrl+Click for keyboard input");
|
"Ctrl+Click for keyboard input");
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||||
|
if (ImGui::Button(PlusBTNFPSI.c_str())) {
|
||||||
|
val++;
|
||||||
|
CVar_SetS32(fps_cvar, val);
|
||||||
|
needs_save = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (impl.backend == Backend::DX11)
|
if (impl.backend == Backend::DX11)
|
||||||
{
|
{
|
||||||
@ -1143,9 +1283,14 @@ namespace SohImGui {
|
|||||||
EnhancementCheckbox("Skip Text", "gSkipText");
|
EnhancementCheckbox("Skip Text", "gSkipText");
|
||||||
Tooltip("Holding down B skips text\nKnown to cause a cutscene softlock in Water Temple\nSoftlock can be fixed by pressing D-Right in Debug mode");
|
Tooltip("Holding down B skips text\nKnown to cause a cutscene softlock in Water Temple\nSoftlock can be fixed by pressing D-Right in Debug mode");
|
||||||
|
|
||||||
|
EnhancementCheckbox("Free Camera", "gFreeCamera");
|
||||||
|
Tooltip("Enables camera control\nNote: You must remap C buttons off of\nthe right stick in the controller\nconfig menu, and map the camera stick\nto the right stick.");
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SetCursorPosY(0.0f);
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Cheats"))
|
if (ImGui::BeginMenu("Cheats"))
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("Infinite...")) {
|
if (ImGui::BeginMenu("Infinite...")) {
|
||||||
@ -1183,6 +1328,8 @@ namespace SohImGui {
|
|||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SetCursorPosY(0.0f);
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Developer Tools"))
|
if (ImGui::BeginMenu("Developer Tools"))
|
||||||
{
|
{
|
||||||
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
|
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
|
||||||
@ -1203,6 +1350,7 @@ namespace SohImGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& category : windowCategories) {
|
for (const auto& category : windowCategories) {
|
||||||
|
ImGui::SetCursorPosY(0.0f);
|
||||||
if (ImGui::BeginMenu(category.first.c_str())) {
|
if (ImGui::BeginMenu(category.first.c_str())) {
|
||||||
for (const std::string& name : category.second) {
|
for (const std::string& name : category.second) {
|
||||||
std::string varName(name);
|
std::string varName(name);
|
||||||
@ -1224,12 +1372,13 @@ namespace SohImGui {
|
|||||||
for (const auto& category : hiddenwindowCategories) {
|
for (const auto& category : hiddenwindowCategories) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||||
ImGui::SetNextWindowSize(ImVec2 (0,0));
|
ImGui::SetNextWindowSize(ImVec2 (0,0));
|
||||||
ImGui::SetNextWindowPos(ImVec2 (-100,-100));
|
ImGuiWindowFlags HiddenWndFlags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoSavedSettings |
|
||||||
ImGui::Begin(category.first.c_str(), nullptr, ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNavFocus);
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs |
|
||||||
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoDecoration;
|
||||||
|
ImGui::Begin(category.first.c_str(), nullptr, HiddenWndFlags);
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CVar_GetS32("gStatsEnabled", 0)) {
|
if (CVar_GetS32("gStatsEnabled", 0)) {
|
||||||
const float framerate = ImGui::GetIO().Framerate;
|
const float framerate = ImGui::GetIO().Framerate;
|
||||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
|
||||||
@ -1248,6 +1397,7 @@ namespace SohImGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console->Draw();
|
console->Draw();
|
||||||
|
controller->DrawHud();
|
||||||
|
|
||||||
for (auto& windowIter : customWindows) {
|
for (auto& windowIter : customWindows) {
|
||||||
CustomWindow& window = windowIter.second;
|
CustomWindow& window = windowIter.second;
|
||||||
@ -1413,4 +1563,124 @@ namespace SohImGui {
|
|||||||
#endif
|
#endif
|
||||||
return reinterpret_cast<ImTextureID>(id);
|
return reinterpret_cast<ImTextureID>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BeginGroupPanel(const char* name, const ImVec2& size)
|
||||||
|
{
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
// auto cursorPos = ImGui::GetCursorScreenPos();
|
||||||
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
ImVec2 effectiveSize = size;
|
||||||
|
if (size.x < 0.0f)
|
||||||
|
effectiveSize.x = ImGui::GetContentRegionAvail().x;
|
||||||
|
else
|
||||||
|
effectiveSize.x = size.x;
|
||||||
|
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f));
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::TextUnformatted(name);
|
||||||
|
auto labelMin = ImGui::GetItemRectMin();
|
||||||
|
auto labelMax = ImGui::GetItemRectMax();
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
//ImGui::GetWindowDrawList()->AddRect(labelMin, labelMax, IM_COL32(255, 0, 255, 255));
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
|
||||||
|
#if IMGUI_VERSION_NUM >= 17301
|
||||||
|
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
#else
|
||||||
|
ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
#endif
|
||||||
|
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
|
||||||
|
|
||||||
|
auto itemWidth = ImGui::CalcItemWidth();
|
||||||
|
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
|
||||||
|
s_GroupPanelLabelStack.push_back(ImRect(labelMin, labelMax));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndGroupPanel(float minHeight) {
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
//ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(0, 255, 0, 64), 4.0f);
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||||
|
ImGui::Dummy(ImVec2(0.0, std::max(frameHeight - frameHeight * 0.5f - itemSpacing.y, minHeight)));
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
auto itemMin = ImGui::GetItemRectMin();
|
||||||
|
auto itemMax = ImGui::GetItemRectMax();
|
||||||
|
//ImGui::GetWindowDrawList()->AddRectFilled(itemMin, itemMax, IM_COL32(255, 0, 0, 64), 4.0f);
|
||||||
|
|
||||||
|
auto labelRect = s_GroupPanelLabelStack.back();
|
||||||
|
s_GroupPanelLabelStack.pop_back();
|
||||||
|
|
||||||
|
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
|
||||||
|
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
|
||||||
|
labelRect.Min.x -= itemSpacing.x;
|
||||||
|
labelRect.Max.x += itemSpacing.x;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
// left half-plane
|
||||||
|
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
|
||||||
|
// right half-plane
|
||||||
|
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
||||||
|
// top
|
||||||
|
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break;
|
||||||
|
// bottom
|
||||||
|
case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::GetWindowDrawList()->AddRect(
|
||||||
|
frameRect.Min, frameRect.Max,
|
||||||
|
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
|
||||||
|
halfFrame.x);
|
||||||
|
|
||||||
|
ImGui::PopClipRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
|
||||||
|
#if IMGUI_VERSION_NUM >= 17301
|
||||||
|
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
|
||||||
|
#else
|
||||||
|
ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x += frameHeight * 0.5f;
|
||||||
|
#endif
|
||||||
|
ImGui::GetCurrentWindow()->Size.x += frameHeight;
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "GameOverlay.h"
|
#include "GameOverlay.h"
|
||||||
#include "Lib/ImGui/imgui.h"
|
#include "Lib/ImGui/imgui.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
#include "InputEditor.h"
|
||||||
|
|
||||||
struct GameAsset {
|
struct GameAsset {
|
||||||
uint32_t textureId;
|
uint32_t textureId;
|
||||||
@ -59,6 +60,7 @@ namespace SohImGui {
|
|||||||
} CustomWindow;
|
} CustomWindow;
|
||||||
|
|
||||||
extern Console* console;
|
extern Console* console;
|
||||||
|
extern Ship::InputEditor* controller;
|
||||||
extern Ship::GameOverlay* overlay;
|
extern Ship::GameOverlay* overlay;
|
||||||
extern bool needs_save;
|
extern bool needs_save;
|
||||||
void Init(WindowImpl window_impl);
|
void Init(WindowImpl window_impl);
|
||||||
@ -68,8 +70,8 @@ namespace SohImGui {
|
|||||||
void EnhancementRadioButton(const char* text, const char* cvarName, int id);
|
void EnhancementRadioButton(const char* text, const char* cvarName, int id);
|
||||||
void EnhancementCheckbox(const char* text, const char* cvarName);
|
void EnhancementCheckbox(const char* text, const char* cvarName);
|
||||||
void EnhancementButton(const char* text, const char* cvarName);
|
void EnhancementButton(const char* text, const char* cvarName);
|
||||||
void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0);
|
void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false);
|
||||||
void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage);
|
void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = false);
|
||||||
void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue);
|
void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue);
|
||||||
void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha=false, bool TitleSameLine=false);
|
void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha=false, bool TitleSameLine=false);
|
||||||
void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector<std::string>& items, int defaultValue = 0);
|
void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector<std::string>& items, int defaultValue = 0);
|
||||||
@ -90,4 +92,6 @@ namespace SohImGui {
|
|||||||
void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha);
|
void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha);
|
||||||
ImTextureID GetTextureByID(int id);
|
ImTextureID GetTextureByID(int id);
|
||||||
ImTextureID GetTextureByName(const std::string& name);
|
ImTextureID GetTextureByName(const std::string& name);
|
||||||
|
void BeginGroupPanel(const char* name, const ImVec2 & size = ImVec2(0.0f, 0.0f));
|
||||||
|
void EndGroupPanel(float minHeight = 0.0f);
|
||||||
}
|
}
|
||||||
|
279
libultraship/libultraship/InputEditor.cpp
Normal file
279
libultraship/libultraship/InputEditor.cpp
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
#include "InputEditor.h"
|
||||||
|
#include "Controller.h"
|
||||||
|
#include "Window.h"
|
||||||
|
#include "Lib/ImGui/imgui.h"
|
||||||
|
#include "ImGuiImpl.h"
|
||||||
|
#include "Utils/StringHelper.h"
|
||||||
|
#include "Lib/ImGui/imgui_internal.h"
|
||||||
|
#include "Cvar.h"
|
||||||
|
|
||||||
|
namespace Ship {
|
||||||
|
|
||||||
|
extern "C" uint8_t __enableGameInput;
|
||||||
|
#define SEPARATION() ImGui::Dummy(ImVec2(0, 5))
|
||||||
|
|
||||||
|
void InputEditor::Init() {
|
||||||
|
BtnReading = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Controller> GetControllerPerSlot(int slot) {
|
||||||
|
const std::vector<int> vDevices = Window::ControllerApi->virtualDevices;
|
||||||
|
return Window::ControllerApi->physicalDevices[vDevices[slot]];
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputEditor::DrawButton(const char* label, int n64Btn) {
|
||||||
|
const std::shared_ptr<Controller> backend = GetControllerPerSlot(CurrentPort);
|
||||||
|
|
||||||
|
float size = 40;
|
||||||
|
bool readingMode = BtnReading == n64Btn;
|
||||||
|
bool disabled = BtnReading != -1 && !readingMode || !backend->Connected();
|
||||||
|
ImVec2 len = ImGui::CalcTextSize(label);
|
||||||
|
ImVec2 pos = ImGui::GetCursorPos();
|
||||||
|
ImGui::SetCursorPosY(pos.y + len.y / 4);
|
||||||
|
ImGui::SetCursorPosX(pos.x + abs(len.x - size));
|
||||||
|
ImGui::Text("%s", label);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosY(pos.y);
|
||||||
|
|
||||||
|
if(disabled) {
|
||||||
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(readingMode) {
|
||||||
|
const int32_t btn = backend->ReadRawPress();
|
||||||
|
|
||||||
|
if(btn != -1) {
|
||||||
|
backend->SetButtonMapping(CurrentPort, n64Btn, btn);
|
||||||
|
BtnReading = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* BtnName = backend->GetButtonName(CurrentPort, n64Btn);
|
||||||
|
|
||||||
|
if (ImGui::Button(StringHelper::Sprintf("%s##HBTNID_%d", readingMode ? "Press a Key..." : BtnName, n64Btn).c_str())) {
|
||||||
|
BtnReading = n64Btn;
|
||||||
|
backend->ClearRawPress();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(disabled) {
|
||||||
|
ImGui::PopItemFlag();
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputEditor::DrawVirtualStick(const char* label, ImVec2 stick) {
|
||||||
|
ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 5, ImGui::GetCursorPos().y));
|
||||||
|
ImGui::BeginChild(label, ImVec2(68, 75), false);
|
||||||
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||||
|
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||||
|
|
||||||
|
float sz = 45.0f;
|
||||||
|
float rad = sz * 0.5f;
|
||||||
|
ImVec2 pos = ImVec2(p.x + sz * 0.5f + 12, p.y + sz * 0.5f + 11);
|
||||||
|
|
||||||
|
float stickX = (stick.x / 83.0f) * (rad * 0.5f);
|
||||||
|
float stickY = -(stick.y / 83.0f) * (rad * 0.5f);
|
||||||
|
|
||||||
|
ImVec4 rect = ImVec4(p.x + 2, p.y + 2, 65, 65);
|
||||||
|
draw_list->AddRect(ImVec2(rect.x, rect.y), ImVec2(rect.x + rect.z, rect.y + rect.w), ImColor(100, 100, 100, 255), 0.0f, 0, 1.5f);
|
||||||
|
draw_list->AddCircleFilled(pos, rad, ImColor(130, 130, 130, 255), 8);
|
||||||
|
draw_list->AddCircleFilled(ImVec2(pos.x + stickX, pos.y + stickY), 5, ImColor(15, 15, 15, 255), 7);
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputEditor::DrawControllerSchema() {
|
||||||
|
|
||||||
|
const std::vector<int> vDevices = Window::ControllerApi->virtualDevices;
|
||||||
|
const std::vector<std::shared_ptr<Controller>> devices = Window::ControllerApi->physicalDevices;
|
||||||
|
|
||||||
|
std::shared_ptr<Controller> Backend = devices[vDevices[CurrentPort]];
|
||||||
|
DeviceProfile& profile =Backend->profiles[CurrentPort];
|
||||||
|
float sensitivity = profile.Thresholds[SENSITIVITY];
|
||||||
|
bool IsKeyboard = Backend->GetGuid() == "Keyboard" || !Backend->Connected();
|
||||||
|
const char* ControllerName = Backend->GetControllerName();
|
||||||
|
|
||||||
|
if (ControllerName != nullptr && ImGui::BeginCombo("##ControllerEntries", ControllerName)) {
|
||||||
|
for (uint8_t i = 0; i < devices.size(); i++) {
|
||||||
|
if (ImGui::Selectable(devices[i]->GetControllerName(), i == vDevices[CurrentPort])) {
|
||||||
|
Window::ControllerApi->SetPhysicalDevice(CurrentPort, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if(ImGui::Button("Refresh")) {
|
||||||
|
Window::ControllerApi->ScanPhysicalDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
SohImGui::BeginGroupPanel("Buttons", ImVec2(150, 20));
|
||||||
|
DrawButton("A", BTN_A);
|
||||||
|
DrawButton("B", BTN_B);
|
||||||
|
DrawButton("L", BTN_L);
|
||||||
|
DrawButton("R", BTN_R);
|
||||||
|
DrawButton("Z", BTN_Z);
|
||||||
|
DrawButton("START", BTN_START);
|
||||||
|
SEPARATION();
|
||||||
|
SohImGui::EndGroupPanel(IsKeyboard ? 7.0f : 48.0f);
|
||||||
|
ImGui::SameLine();
|
||||||
|
SohImGui::BeginGroupPanel("Digital Pad", ImVec2(150, 20));
|
||||||
|
DrawButton("Up", BTN_DUP);
|
||||||
|
DrawButton("Down", BTN_DDOWN);
|
||||||
|
DrawButton("Left", BTN_DLEFT);
|
||||||
|
DrawButton("Right", BTN_DRIGHT);
|
||||||
|
SEPARATION();
|
||||||
|
SohImGui::EndGroupPanel(IsKeyboard ? 53.0f : 94.0f);
|
||||||
|
ImGui::SameLine();
|
||||||
|
SohImGui::BeginGroupPanel("Analog Stick", ImVec2(150, 20));
|
||||||
|
DrawButton("Up", BTN_STICKUP);
|
||||||
|
DrawButton("Down", BTN_STICKDOWN);
|
||||||
|
DrawButton("Left", BTN_STICKLEFT);
|
||||||
|
DrawButton("Right", BTN_STICKRIGHT);
|
||||||
|
|
||||||
|
if (!IsKeyboard) {
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8);
|
||||||
|
DrawVirtualStick("##MainVirtualStick", ImVec2(Backend->wStickX, Backend->wStickY));
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
||||||
|
|
||||||
|
ImGui::BeginChild("##MSInput", ImVec2(90, 50), false);
|
||||||
|
ImGui::Text("Deadzone");
|
||||||
|
ImGui::PushItemWidth(80);
|
||||||
|
ImGui::InputFloat("##MDZone", &profile.Thresholds[LEFT_STICK], 1.0f, 0.0f, "%.0f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::EndChild();
|
||||||
|
} else {
|
||||||
|
ImGui::Dummy(ImVec2(0, 6));
|
||||||
|
}
|
||||||
|
SohImGui::EndGroupPanel(IsKeyboard ? 52.0f : 24.0f);
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if (!IsKeyboard) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
SohImGui::BeginGroupPanel("Camera Stick", ImVec2(150, 20));
|
||||||
|
DrawButton("Up", BTN_VSTICKUP);
|
||||||
|
DrawButton("Down", BTN_VSTICKDOWN);
|
||||||
|
DrawButton("Left", BTN_VSTICKLEFT);
|
||||||
|
DrawButton("Right", BTN_VSTICKRIGHT);
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8);
|
||||||
|
DrawVirtualStick("##CameraVirtualStick", ImVec2(Backend->wCamX / sensitivity, Backend->wCamY / sensitivity));
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
||||||
|
ImGui::BeginChild("##CSInput", ImVec2(90, 85), false);
|
||||||
|
ImGui::Text("Deadzone");
|
||||||
|
ImGui::PushItemWidth(80);
|
||||||
|
ImGui::InputFloat("##MDZone", &profile.Thresholds[RIGHT_STICK], 1.0f, 0.0f, "%.0f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::Text("Sensitivity");
|
||||||
|
ImGui::PushItemWidth(80);
|
||||||
|
ImGui::InputFloat("##MSensitivity", &profile.Thresholds[SENSITIVITY], 1.0f, 0.0f, "%.0f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::EndChild();
|
||||||
|
SohImGui::EndGroupPanel(14.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Backend->CanGyro()) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
SohImGui::BeginGroupPanel("Gyro Options", ImVec2(175, 20));
|
||||||
|
float cursorX = ImGui::GetCursorPosX() + 5;
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
ImGui::Checkbox("Enable Gyro", &profile.UseGyro);
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
ImGui::Text("Gyro Sensitivity: %d%%", static_cast<int>(100.0f * profile.Thresholds[GYRO_SENSITIVITY]));
|
||||||
|
ImGui::PushItemWidth(135.0f);
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
ImGui::SliderFloat("##GSensitivity", &profile.Thresholds[GYRO_SENSITIVITY], 0.0f, 1.0f, "");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::Dummy(ImVec2(0, 1));
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
if (ImGui::Button("Recalibrate Gyro##RGyro")) {
|
||||||
|
profile.Thresholds[DRIFT_X] = 0.0f;
|
||||||
|
profile.Thresholds[DRIFT_Y] = 0.0f;
|
||||||
|
}
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
DrawVirtualStick("##GyroPreview", ImVec2(-10.0f * Backend->wGyroY, 10.0f * Backend->wGyroX));
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
||||||
|
ImGui::BeginChild("##GyInput", ImVec2(90, 85), false);
|
||||||
|
ImGui::Text("Drift X");
|
||||||
|
ImGui::PushItemWidth(80);
|
||||||
|
ImGui::InputFloat("##GDriftX", &profile.Thresholds[DRIFT_X], 1.0f, 0.0f, "%.1f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::Text("Drift Y");
|
||||||
|
ImGui::PushItemWidth(80);
|
||||||
|
ImGui::InputFloat("##GDriftY", &profile.Thresholds[DRIFT_Y], 1.0f, 0.0f, "%.1f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::EndChild();
|
||||||
|
SohImGui::EndGroupPanel(14.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
const ImVec2 cursor = ImGui::GetCursorPos();
|
||||||
|
|
||||||
|
SohImGui::BeginGroupPanel("C-Buttons", ImVec2(158, 20));
|
||||||
|
DrawButton("Up", BTN_CUP);
|
||||||
|
DrawButton("Down", BTN_CDOWN);
|
||||||
|
DrawButton("Left", BTN_CLEFT);
|
||||||
|
DrawButton("Right", BTN_CRIGHT);
|
||||||
|
ImGui::Dummy(ImVec2(0, 5));
|
||||||
|
SohImGui::EndGroupPanel();
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX(cursor.x);
|
||||||
|
ImGui::SetCursorPosY(cursor.y + 120);
|
||||||
|
SohImGui::BeginGroupPanel("Options", ImVec2(158, 20));
|
||||||
|
float cursorX = ImGui::GetCursorPosX() + 5;
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
ImGui::Checkbox("Rumble Enabled", &profile.UseRumble);
|
||||||
|
if (Backend->CanRumble()) {
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
ImGui::Text("Rumble Force: %d%%", static_cast<int>(100.0f * profile.RumbleStrength));
|
||||||
|
ImGui::SetCursorPosX(cursorX);
|
||||||
|
ImGui::PushItemWidth(135.0f);
|
||||||
|
ImGui::SliderFloat("##RStrength", &profile.RumbleStrength, 0.0f, 1.0f, "");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
}
|
||||||
|
ImGui::Dummy(ImVec2(0, 5));
|
||||||
|
SohImGui::EndGroupPanel(IsKeyboard ? 0.0f : 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputEditor::DrawHud() {
|
||||||
|
|
||||||
|
__enableGameInput = true;
|
||||||
|
|
||||||
|
if (!this->Opened) {
|
||||||
|
BtnReading = -1;
|
||||||
|
CVar_SetS32("gControllerConfigurationEnabled", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextWindowSizeConstraints(ImVec2(641, 250), ImVec2(1200, 290));
|
||||||
|
//OTRTODO: Disable this stupid workaround ( ReadRawPress() only works when the window is on the main viewport )
|
||||||
|
ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID);
|
||||||
|
ImGui::Begin("Controller Configuration", &this->Opened, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize);
|
||||||
|
|
||||||
|
ImGui::BeginTabBar("##Controllers");
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (ImGui::BeginTabItem(StringHelper::Sprintf("Port %d", i + 1).c_str())) {
|
||||||
|
CurrentPort = i;
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTabBar();
|
||||||
|
|
||||||
|
// Draw current cfg
|
||||||
|
|
||||||
|
DrawControllerSchema();
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
20
libultraship/libultraship/InputEditor.h
Normal file
20
libultraship/libultraship/InputEditor.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Lib/ImGui/imgui.h"
|
||||||
|
|
||||||
|
namespace Ship {
|
||||||
|
|
||||||
|
class InputEditor {
|
||||||
|
int CurrentPort = 0;
|
||||||
|
int BtnReading = -1;
|
||||||
|
public:
|
||||||
|
bool Opened = false;
|
||||||
|
void Init();
|
||||||
|
void DrawButton(const char* label, int n64Btn);
|
||||||
|
void DrawVirtualStick(const char* label, ImVec2 stick);
|
||||||
|
void DrawControllerSchema();
|
||||||
|
void DrawHud();
|
||||||
|
};
|
||||||
|
}
|
@ -1,56 +1,105 @@
|
|||||||
#include "KeyboardController.h"
|
#include "KeyboardController.h"
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
|
#include <SDL_keyboard.h>
|
||||||
|
#else
|
||||||
|
#include <SDL2/SDL_keyboard.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Hooks.h"
|
||||||
#include "GlobalCtx2.h"
|
#include "GlobalCtx2.h"
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
KeyboardController::KeyboardController(int32_t dwControllerNumber) : Controller(dwControllerNumber) {
|
|
||||||
LoadBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyboardController::~KeyboardController() {
|
|
||||||
|
|
||||||
|
KeyboardController::KeyboardController() : Controller(), lastScancode(-1) {
|
||||||
|
GUID = "Keyboard";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardController::PressButton(int32_t dwScancode) {
|
bool KeyboardController::PressButton(int32_t dwScancode) {
|
||||||
if (ButtonMapping.contains(dwScancode)) {
|
|
||||||
dwPressedButtons |= ButtonMapping[dwScancode];
|
lastKey = dwScancode;
|
||||||
|
|
||||||
|
for (int slot = 0; slot < MAXCONTROLLERS; slot++) {
|
||||||
|
|
||||||
|
if (profiles[slot].Mappings.contains(dwScancode)) {
|
||||||
|
dwPressedButtons[slot] |= profiles[slot].Mappings[dwScancode];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyboardController::ReleaseButton(int32_t dwScancode) {
|
bool KeyboardController::ReleaseButton(int32_t dwScancode) {
|
||||||
if (ButtonMapping.contains(dwScancode)) {
|
for (int slot = 0; slot < MAXCONTROLLERS; slot++) {
|
||||||
dwPressedButtons &= ~ButtonMapping[dwScancode];
|
if (profiles[slot].Mappings.contains(dwScancode)) {
|
||||||
|
dwPressedButtons[slot] &= ~profiles[slot].Mappings[dwScancode];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardController::ReleaseAllButtons() {
|
void KeyboardController::ReleaseAllButtons() {
|
||||||
dwPressedButtons = 0;
|
for(int slot = 0; slot < MAXCONTROLLERS; slot++) {
|
||||||
|
dwPressedButtons[slot] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardController::ReadFromSource() {
|
void KeyboardController::ReadFromSource(int32_t slot) {
|
||||||
wStickX = 0;
|
wStickX = 0;
|
||||||
wStickY = 0;
|
wStickY = 0;
|
||||||
|
wCamX = 0;
|
||||||
|
wCamY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardController::WriteToSource(ControllerCallback* controller)
|
int32_t KeyboardController::ReadRawPress() {
|
||||||
|
return lastKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void KeyboardController::WriteToSource(int32_t slot, ControllerCallback* controller)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string KeyboardController::GetControllerType() {
|
const char* KeyboardController::GetButtonName(int slot, int n64Button) {
|
||||||
return "KEYBOARD";
|
std::map<int32_t, int32_t>& Mappings = profiles[slot].Mappings;
|
||||||
|
const auto find = std::find_if(Mappings.begin(), Mappings.end(), [n64Button](const std::pair<int32_t, int32_t>& pair) {
|
||||||
|
return pair.second == n64Button;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (find == Mappings.end()) return "Unknown";
|
||||||
|
const char* name = GlobalCtx2::GetInstance()->GetWindow()->GetKeyName(find->first);
|
||||||
|
return strlen(name) == 0 ? "Unknown" : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string KeyboardController::GetConfSection() {
|
|
||||||
return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1);
|
void KeyboardController::CreateDefaultBinding(int32_t slot) {
|
||||||
|
DeviceProfile& profile = profiles[slot];
|
||||||
|
profile.Mappings[0x14D] = BTN_CRIGHT;
|
||||||
|
profile.Mappings[0x14B] = BTN_CLEFT;
|
||||||
|
profile.Mappings[0x150] = BTN_CDOWN;
|
||||||
|
profile.Mappings[0x148] = BTN_CUP;
|
||||||
|
profile.Mappings[0x13] = BTN_R;
|
||||||
|
profile.Mappings[0x12] = BTN_L;
|
||||||
|
profile.Mappings[0x023] = BTN_DRIGHT;
|
||||||
|
profile.Mappings[0x021] = BTN_DLEFT;
|
||||||
|
profile.Mappings[0x022] = BTN_DDOWN;
|
||||||
|
profile.Mappings[0x014] = BTN_DUP;
|
||||||
|
profile.Mappings[0x039] = BTN_START;
|
||||||
|
profile.Mappings[0x02C] = BTN_Z;
|
||||||
|
profile.Mappings[0x02E] = BTN_B;
|
||||||
|
profile.Mappings[0x02D] = BTN_A;
|
||||||
|
profile.Mappings[0x020] = BTN_STICKRIGHT;
|
||||||
|
profile.Mappings[0x01E] = BTN_STICKLEFT;
|
||||||
|
profile.Mappings[0x01F] = BTN_STICKDOWN;
|
||||||
|
profile.Mappings[0x011] = BTN_STICKUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string KeyboardController::GetBindingConfSection() {
|
const char* KeyboardController::GetControllerName() {
|
||||||
return GetControllerType() + " CONTROLLER BINDING " + std::to_string(GetControllerNumber() + 1);
|
return "Keyboard";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,24 +5,34 @@
|
|||||||
namespace Ship {
|
namespace Ship {
|
||||||
class KeyboardController : public Controller {
|
class KeyboardController : public Controller {
|
||||||
public:
|
public:
|
||||||
KeyboardController(int32_t dwControllerNumber);
|
KeyboardController();
|
||||||
~KeyboardController();
|
|
||||||
|
|
||||||
void ReadFromSource();
|
|
||||||
void WriteToSource(ControllerCallback* controller);
|
|
||||||
bool Connected() const { return true; }
|
|
||||||
bool CanRumble() const { return false; }
|
|
||||||
|
|
||||||
|
void ReadFromSource(int32_t slot) override;
|
||||||
|
void WriteToSource(int32_t slot, ControllerCallback* controller) override;
|
||||||
|
bool Connected() const override { return true; }
|
||||||
|
bool CanRumble() const override { return false; }
|
||||||
|
bool CanGyro() const override { return false; }
|
||||||
|
const char* GetControllerName() override;
|
||||||
|
const char* GetButtonName(int slot, int n64Button) override;
|
||||||
bool PressButton(int32_t dwScancode);
|
bool PressButton(int32_t dwScancode);
|
||||||
bool ReleaseButton(int32_t dwScancode);
|
bool ReleaseButton(int32_t dwScancode);
|
||||||
|
|
||||||
|
void ClearRawPress() override {
|
||||||
|
lastKey = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ReadRawPress() override;
|
||||||
void ReleaseAllButtons();
|
void ReleaseAllButtons();
|
||||||
|
|
||||||
bool HasPadConf() const { return false; }
|
void SetLastScancode(int32_t key) {
|
||||||
std::optional<std::string> GetPadConfSection() { return {}; }
|
lastScancode = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t GetLastScancode() { return lastScancode; }
|
||||||
|
void CreateDefaultBinding(int32_t slot) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string GetControllerType();
|
int32_t lastScancode;
|
||||||
std::string GetConfSection();
|
int32_t lastKey = -1;
|
||||||
std::string GetBindingConfSection();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,9 @@ typedef struct {
|
|||||||
/* 0x04 */ u8 err_no;
|
/* 0x04 */ u8 err_no;
|
||||||
/* 0x05 */ f32 gyro_x;
|
/* 0x05 */ f32 gyro_x;
|
||||||
/* 0x09 */ f32 gyro_y;
|
/* 0x09 */ f32 gyro_y;
|
||||||
} OSContPad; // size = 0x0D
|
/* 0x1C */ f32 cam_x;
|
||||||
|
/* 0x20 */ f32 cam_y;
|
||||||
|
} OSContPad; // size = 0x24
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ u8 rumble;
|
/* 0x00 */ u8 rumble;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "gfx_pc.h"
|
#include "gfx_pc.h"
|
||||||
#include "../../ImGuiImpl.h"
|
#include "../../ImGuiImpl.h"
|
||||||
#include "../../Cvar.h"
|
#include "../../Cvar.h"
|
||||||
|
#include "../../Hooks.h"
|
||||||
|
|
||||||
#define DECLARE_GFX_DXGI_FUNCTIONS
|
#define DECLARE_GFX_DXGI_FUNCTIONS
|
||||||
#include "gfx_dxgi.h"
|
#include "gfx_dxgi.h"
|
||||||
@ -228,9 +229,8 @@ static void onkeyup(WPARAM w_param, LPARAM l_param) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char fileName[256];
|
|
||||||
|
|
||||||
static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param) {
|
static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param) {
|
||||||
|
char fileName[256];
|
||||||
SohImGui::EventImpl event_impl;
|
SohImGui::EventImpl event_impl;
|
||||||
event_impl.win32 = { h_wnd, static_cast<int>(message), static_cast<int>(w_param), static_cast<int>(l_param) };
|
event_impl.win32 = { h_wnd, static_cast<int>(message), static_cast<int>(w_param), static_cast<int>(l_param) };
|
||||||
SohImGui::Update(event_impl);
|
SohImGui::Update(event_impl);
|
||||||
@ -240,6 +240,7 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
|
|||||||
dxgi.current_height = (uint32_t)(l_param >> 16);
|
dxgi.current_height = (uint32_t)(l_param >> 16);
|
||||||
break;
|
break;
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
|
ModInternal::ExecuteHooks<ModInternal::ExitGame>();
|
||||||
exit(0);
|
exit(0);
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
if (dxgi.in_paint) {
|
if (dxgi.in_paint) {
|
||||||
@ -718,6 +719,12 @@ void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* gfx_dxgi_get_key_name(int scancode) {
|
||||||
|
TCHAR* Text = new TCHAR[64];
|
||||||
|
GetKeyNameText(scancode << 16, Text, 64);
|
||||||
|
return (char*) Text;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = {
|
extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = {
|
||||||
gfx_dxgi_init,
|
gfx_dxgi_init,
|
||||||
gfx_dxgi_set_keyboard_callbacks,
|
gfx_dxgi_set_keyboard_callbacks,
|
||||||
@ -734,6 +741,7 @@ extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = {
|
|||||||
gfx_dxgi_set_target_fps,
|
gfx_dxgi_set_target_fps,
|
||||||
gfx_dxgi_set_maximum_frame_latency,
|
gfx_dxgi_set_maximum_frame_latency,
|
||||||
gfx_dxgi_get_detected_hz,
|
gfx_dxgi_get_detected_hz,
|
||||||
|
gfx_dxgi_get_key_name
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "../../ImGuiImpl.h"
|
#include "../../ImGuiImpl.h"
|
||||||
#include "../../Cvar.h"
|
#include "../../Cvar.h"
|
||||||
|
#include "../../Hooks.h"
|
||||||
|
|
||||||
#include "gfx_window_manager_api.h"
|
#include "gfx_window_manager_api.h"
|
||||||
#include "gfx_screen_config.h"
|
#include "gfx_screen_config.h"
|
||||||
@ -108,7 +109,7 @@ static void set_fullscreen(bool on, bool call_callback) {
|
|||||||
SDL_GetDesktopDisplayMode(0, &mode);
|
SDL_GetDesktopDisplayMode(0, &mode);
|
||||||
window_width = mode.w;
|
window_width = mode.w;
|
||||||
window_height = mode.h;
|
window_height = mode.h;
|
||||||
//SDL_ShowCursor(false);
|
SDL_ShowCursor(false);
|
||||||
} else {
|
} else {
|
||||||
window_width = DESIRED_SCREEN_WIDTH;
|
window_width = DESIRED_SCREEN_WIDTH;
|
||||||
window_height = DESIRED_SCREEN_HEIGHT;
|
window_height = DESIRED_SCREEN_HEIGHT;
|
||||||
@ -229,6 +230,15 @@ static int translate_scancode(int scancode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int untranslate_scancode(int translatedScancode) {
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
if (inverted_scancode_table[i] == translatedScancode) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void gfx_sdl_onkeydown(int scancode) {
|
static void gfx_sdl_onkeydown(int scancode) {
|
||||||
int key = translate_scancode(scancode);
|
int key = translate_scancode(scancode);
|
||||||
if (on_key_down_callback != NULL) {
|
if (on_key_down_callback != NULL) {
|
||||||
@ -270,6 +280,7 @@ static void gfx_sdl_handle_events(void) {
|
|||||||
Game::SaveSettings();
|
Game::SaveSettings();
|
||||||
break;
|
break;
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
|
ModInternal::ExecuteHooks<ModInternal::ExitGame>();
|
||||||
SDL_Quit(); // bandaid fix for linux window closing issue
|
SDL_Quit(); // bandaid fix for linux window closing issue
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@ -339,6 +350,10 @@ static float gfx_sdl_get_detected_hz(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* gfx_sdl_get_key_name(int scancode) {
|
||||||
|
return SDL_GetScancodeName((SDL_Scancode) untranslate_scancode(scancode));
|
||||||
|
}
|
||||||
|
|
||||||
struct GfxWindowManagerAPI gfx_sdl = {
|
struct GfxWindowManagerAPI gfx_sdl = {
|
||||||
gfx_sdl_init,
|
gfx_sdl_init,
|
||||||
gfx_sdl_set_keyboard_callbacks,
|
gfx_sdl_set_keyboard_callbacks,
|
||||||
@ -354,7 +369,8 @@ struct GfxWindowManagerAPI gfx_sdl = {
|
|||||||
gfx_sdl_get_time,
|
gfx_sdl_get_time,
|
||||||
gfx_sdl_set_target_fps,
|
gfx_sdl_set_target_fps,
|
||||||
gfx_sdl_set_maximum_frame_latency,
|
gfx_sdl_set_maximum_frame_latency,
|
||||||
gfx_sdl_get_detected_hz
|
gfx_sdl_get_detected_hz,
|
||||||
|
gfx_sdl_get_key_name
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,6 +20,7 @@ struct GfxWindowManagerAPI {
|
|||||||
void (*set_target_fps)(int fps);
|
void (*set_target_fps)(int fps);
|
||||||
void (*set_maximum_frame_latency)(int latency);
|
void (*set_maximum_frame_latency)(int latency);
|
||||||
float (*get_detected_hz)(void);
|
float (*get_detected_hz)(void);
|
||||||
|
const char* (*get_key_name)(int scancode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
134
libultraship/libultraship/Lib/Mercury/Mercury.cpp
Normal file
134
libultraship/libultraship/Lib/Mercury/Mercury.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "Mercury.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::any> ramMap;
|
||||||
|
|
||||||
|
Mercury::Mercury(std::string path) : path_(std::move(path)) {
|
||||||
|
this->reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string& s, const char delimiter) {
|
||||||
|
std::vector<std::string> result;
|
||||||
|
std::stringstream ss(s);
|
||||||
|
std::string item;
|
||||||
|
while (getline(ss, item, delimiter)) {
|
||||||
|
result.push_back(item);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Mercury::formatNestedKey(const std::string& key) {
|
||||||
|
const std::vector<std::string> dots = split(key, '.');
|
||||||
|
std::string tmp;
|
||||||
|
if (dots.size() > 1)
|
||||||
|
for (const auto& dot : dots) {
|
||||||
|
tmp += "/" + dot;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tmp = "/" + dots[0];
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
json Mercury::nested(const std::string& key) {
|
||||||
|
std::vector<std::string> dots = split(key, '.');
|
||||||
|
if (!this->vjson.is_object())
|
||||||
|
return this->vjson;
|
||||||
|
json gjson = this->vjson.unflatten();
|
||||||
|
|
||||||
|
if (dots.size() > 1) {
|
||||||
|
for (auto& key : dots) {
|
||||||
|
if (key == "*" || gjson.contains(key))
|
||||||
|
gjson = gjson[key];
|
||||||
|
}
|
||||||
|
return gjson;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gjson[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Mercury::getString(const std::string& key, const std::string& def) {
|
||||||
|
json n = this->nested(key);
|
||||||
|
if (n.is_string() && !n.get<std::string>().empty())
|
||||||
|
return n;
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Mercury::getFloat(const std::string& key, float def) {
|
||||||
|
json n = this->nested(key);
|
||||||
|
if (n.is_number_float())
|
||||||
|
return n;
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mercury::getBool(const std::string& key, bool def) {
|
||||||
|
json n = this->nested(key);
|
||||||
|
if (n.is_boolean())
|
||||||
|
return n;
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mercury::getInt(const std::string& key, int def) {
|
||||||
|
json n = this->nested(key);
|
||||||
|
if (n.is_number_integer())
|
||||||
|
return n;
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mercury::contains(const std::string& key) {
|
||||||
|
return !this->nested(key).is_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::setString(const std::string& key, const std::string& value) {
|
||||||
|
this->vjson[formatNestedKey(key)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::setFloat(const std::string& key, float value) {
|
||||||
|
this->vjson[formatNestedKey(key)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::setBool(const std::string& key, bool value) {
|
||||||
|
this->vjson[formatNestedKey(key)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::setInt(const std::string& key, int value) {
|
||||||
|
this->vjson[formatNestedKey(key)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::setUInt(const std::string& key, uint32_t value) {
|
||||||
|
this->vjson[formatNestedKey(key)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::erase(const std::string& key) {
|
||||||
|
this->vjson.erase(formatNestedKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::reload() {
|
||||||
|
if (this->path_ == "None" || !fs::exists(this->path_) || !fs::is_regular_file(this->path_)) {
|
||||||
|
this->isNewInstance = true;
|
||||||
|
this->vjson = json::object();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::ifstream ifs(this->path_);
|
||||||
|
try {
|
||||||
|
this->rjson = json::parse(ifs);
|
||||||
|
this->vjson = this->rjson.flatten();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
this->vjson = json::object();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mercury::save() const {
|
||||||
|
std::ofstream file(this->path_);
|
||||||
|
file << this->vjson.unflatten().dump(4);
|
||||||
|
}
|
47
libultraship/libultraship/Lib/Mercury/Mercury.h
Normal file
47
libultraship/libultraship/Lib/Mercury/Mercury.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <any>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "../nlohmann/json.hpp"
|
||||||
|
|
||||||
|
class Mercury {
|
||||||
|
protected:
|
||||||
|
std::string path_;
|
||||||
|
public:
|
||||||
|
explicit Mercury(std::string path);
|
||||||
|
|
||||||
|
nlohmann::json vjson;
|
||||||
|
nlohmann::json rjson;
|
||||||
|
nlohmann::json nested(const std::string& key);
|
||||||
|
static std::string formatNestedKey(const std::string& key);
|
||||||
|
std::string getString(const std::string& key, const std::string& def = "");
|
||||||
|
float getFloat(const std::string& key, float defValue = 0.0f);
|
||||||
|
bool getBool(const std::string& key, bool defValue = false);
|
||||||
|
int getInt(const std::string& key, int defValue = 0);
|
||||||
|
bool contains(const std::string& key);
|
||||||
|
template< typename T > std::vector<T> getArray(const std::string& key);
|
||||||
|
void setString(const std::string& key, const std::string& value);
|
||||||
|
void setFloat(const std::string& key, float value);
|
||||||
|
void setBool(const std::string& key, bool value);
|
||||||
|
void setInt(const std::string& key, int value);
|
||||||
|
void setUInt(const std::string& key, uint32_t value);
|
||||||
|
void erase(const std::string& key);
|
||||||
|
void set(const std::string& key, std::any value);
|
||||||
|
template< typename T > void setArray(const std::string& key, std::vector<T> array);
|
||||||
|
|
||||||
|
void reload();
|
||||||
|
void save() const;
|
||||||
|
bool isNewInstance = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
std::vector<T> Mercury::getArray(const std::string& key) {
|
||||||
|
if (nlohmann::json tmp = this->nested(key); tmp.is_array())
|
||||||
|
return tmp.get<std::vector<T>>();
|
||||||
|
return std::vector<T>();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Mercury::setArray(const std::string& key, std::vector<T> array) {
|
||||||
|
this->vjson[formatNestedKey(key)] = nlohmann::json(array);
|
||||||
|
}
|
60
libultraship/libultraship/OSXFolderManager.h
Normal file
60
libultraship/libultraship/OSXFolderManager.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// OSXFolderManager.h
|
||||||
|
// libultraship
|
||||||
|
//
|
||||||
|
// Created by David Chavez on 28.06.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef OSXFolderManager_h
|
||||||
|
#define OSXFolderManager_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
namespace Ship {
|
||||||
|
enum {
|
||||||
|
NSApplicationDirectory = 1,
|
||||||
|
NSDemoApplicationDirectory,
|
||||||
|
NSDeveloperApplicationDirectory,
|
||||||
|
NSAdminApplicationDirectory,
|
||||||
|
NSLibraryDirectory,
|
||||||
|
NSDeveloperDirectory,
|
||||||
|
NSUserDirectory,
|
||||||
|
NSDocumentationDirectory,
|
||||||
|
NSDocumentDirectory,
|
||||||
|
NSCoreServiceDirectory,
|
||||||
|
NSAutosavedInformationDirectory = 11,
|
||||||
|
NSDesktopDirectory = 12,
|
||||||
|
NSCachesDirectory = 13,
|
||||||
|
NSApplicationSupportDirectory = 14,
|
||||||
|
NSDownloadsDirectory = 15,
|
||||||
|
NSInputMethodsDirectory = 16,
|
||||||
|
NSMoviesDirectory = 17,
|
||||||
|
NSMusicDirectory = 18,
|
||||||
|
NSPicturesDirectory = 19,
|
||||||
|
NSPrinterDescriptionDirectory = 20,
|
||||||
|
NSSharedPublicDirectory = 21,
|
||||||
|
NSPreferencePanesDirectory = 22,
|
||||||
|
NSApplicationScriptsDirectory = 23,
|
||||||
|
NSItemReplacementDirectory = 99,
|
||||||
|
NSAllApplicationsDirectory = 100,
|
||||||
|
NSAllLibrariesDirectory = 101,
|
||||||
|
NSTrashDirectory = 102
|
||||||
|
};
|
||||||
|
typedef unsigned long SearchPathDirectory;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~)
|
||||||
|
NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine (/Library)
|
||||||
|
NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network)
|
||||||
|
NSSystemDomainMask = 8, // provided by Apple, unmodifiable (/System)
|
||||||
|
NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items
|
||||||
|
};
|
||||||
|
typedef unsigned long SearchPathDomainMask;
|
||||||
|
|
||||||
|
class FolderManager {
|
||||||
|
public:
|
||||||
|
const char *pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask);
|
||||||
|
const char *pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, SearchPathDomainMask domainMask, const char *itemPath, bool create = false);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* OSXFolderManager_h */
|
37
libultraship/libultraship/OSXFolderManager.mm
Normal file
37
libultraship/libultraship/OSXFolderManager.mm
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// OSXFolderManager.m
|
||||||
|
// libultraship
|
||||||
|
//
|
||||||
|
// Created by David Chavez on 28.06.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "OSXFolderManager.h"
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
using namespace Ship;
|
||||||
|
|
||||||
|
const char * FolderManager::pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask) {
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
NSArray *URLs = [fileManager URLsForDirectory:(NSSearchPathDirectory)directory inDomains:domainMask];
|
||||||
|
if (URLs.count == 0) return NULL;
|
||||||
|
|
||||||
|
NSURL *URL = [URLs objectAtIndex:0];
|
||||||
|
NSString *path = URL.path;
|
||||||
|
|
||||||
|
// `fileSystemRepresentation` on an `NSString` gives a path suitable for POSIX APIs
|
||||||
|
return path.fileSystemRepresentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * FolderManager::pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory,
|
||||||
|
SearchPathDomainMask domainMask, const char *itemPath, bool create) {
|
||||||
|
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
NSString *nsPath = [fileManager stringWithFileSystemRepresentation:itemPath length:strlen(itemPath)];
|
||||||
|
NSURL *itemURL = (nsPath ? [NSURL fileURLWithPath:nsPath] : nil);
|
||||||
|
|
||||||
|
NSURL *URL = [fileManager URLForDirectory:(NSSearchPathDirectory)directory
|
||||||
|
inDomain:domainMask
|
||||||
|
appropriateForURL:itemURL
|
||||||
|
create:create error:NULL];
|
||||||
|
return URL.path.fileSystemRepresentation;
|
||||||
|
}
|
@ -63,8 +63,7 @@ namespace Ship
|
|||||||
Deckard = 0,
|
Deckard = 0,
|
||||||
Roy = 1,
|
Roy = 1,
|
||||||
Rachael = 2,
|
Rachael = 2,
|
||||||
Leon = 3,
|
Zhora = 3,
|
||||||
Zhora = 4,
|
|
||||||
// ...
|
// ...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,103 +1,36 @@
|
|||||||
#include "SDLController.h"
|
#include "SDLController.h"
|
||||||
|
|
||||||
#include "GameSettings.h"
|
|
||||||
#include "GlobalCtx2.h"
|
#include "GlobalCtx2.h"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "stox.h"
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "Cvar.h"
|
|
||||||
#include <Utils/StringHelper.h>
|
#include <Utils/StringHelper.h>
|
||||||
|
|
||||||
extern "C" uint8_t __osMaxControllers;
|
extern "C" uint8_t __osMaxControllers;
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
SDLController::SDLController(int32_t dwControllerNumber) : Controller(dwControllerNumber), Cont(nullptr), guid(INVALID_SDL_CONTROLLER_GUID) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SDLController::~SDLController() {
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDLController::IsGuidInUse(const std::string& guid) {
|
|
||||||
// Check if the GUID is loaded in any other controller;
|
|
||||||
for (size_t i = 0; i < __osMaxControllers; i++) {
|
|
||||||
for (size_t j = 0; j < Window::Controllers[i].size(); j++) {
|
|
||||||
SDLController* OtherCont = dynamic_cast<SDLController*>(Window::Controllers[i][j].get());
|
|
||||||
|
|
||||||
if (OtherCont != nullptr && OtherCont->GetGuid().compare(guid) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDLController::Open() {
|
bool SDLController::Open() {
|
||||||
std::string ConfSection = GetConfSection();
|
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
const auto NewCont = SDL_GameControllerOpen(physicalSlot);
|
||||||
if (SDL_IsGameController(i)) {
|
|
||||||
// Get the GUID from SDL
|
|
||||||
char GuidBuf[33];
|
|
||||||
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), GuidBuf, sizeof(GuidBuf));
|
|
||||||
auto NewGuid = std::string(GuidBuf);
|
|
||||||
|
|
||||||
// Invalid GUID read. Go to next.
|
|
||||||
if (NewGuid.compare(INVALID_SDL_CONTROLLER_GUID) == 0) {
|
|
||||||
SPDLOG_ERROR("SDL Controller returned invalid guid");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The GUID is in use, we want to use a different physical controller. Go to next.
|
|
||||||
if (IsGuidInUse(NewGuid)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the GUID is blank from the config, OR if the config GUID matches, load the controller.
|
|
||||||
if (Conf[ConfSection]["GUID"].compare("") == 0 || Conf[ConfSection]["GUID"].compare(INVALID_SDL_CONTROLLER_GUID) == 0 || Conf[ConfSection]["GUID"].compare(NewGuid) == 0) {
|
|
||||||
auto NewCont = SDL_GameControllerOpen(i);
|
|
||||||
|
|
||||||
// We failed to load the controller. Go to next.
|
// We failed to load the controller. Go to next.
|
||||||
if (NewCont == nullptr) {
|
if (NewCont == nullptr) {
|
||||||
SPDLOG_ERROR("SDL Controller failed to open: ({})", SDL_GetError());
|
SPDLOG_ERROR("SDL Controller failed to open: ({})", SDL_GetError());
|
||||||
continue;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_GameControllerHasSensor(NewCont, SDL_SENSOR_GYRO))
|
if (SDL_GameControllerHasSensor(NewCont, SDL_SENSOR_GYRO)) {
|
||||||
{
|
|
||||||
SDL_GameControllerSetSensorEnabled(NewCont, SDL_SENSOR_GYRO, SDL_TRUE);
|
SDL_GameControllerSetSensorEnabled(NewCont, SDL_SENSOR_GYRO, SDL_TRUE);
|
||||||
|
supportsGyro = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
guid = NewGuid;
|
char GuidBuf[33];
|
||||||
|
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(physicalSlot), GuidBuf, sizeof(GuidBuf));
|
||||||
|
GUID = std::string(GuidBuf);
|
||||||
Cont = NewCont;
|
Cont = NewCont;
|
||||||
|
wCamX = 0;
|
||||||
|
wCamY = 0;
|
||||||
|
|
||||||
std::string BindingConfSection = GetBindingConfSection();
|
return true;
|
||||||
std::string PadConfSection = *GetPadConfSection();
|
|
||||||
std::shared_ptr<ConfigFile> config = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
|
|
||||||
if (!config->has(BindingConfSection)) {
|
|
||||||
CreateDefaultBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config->has(PadConfSection)) {
|
|
||||||
CreateDefaultPadConf();
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadBinding();
|
|
||||||
LoadAxisThresholds();
|
|
||||||
// Update per-controller settings in ImGui menu after opening controller.
|
|
||||||
Game::LoadPadSettings();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Cont != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDLController::Close() {
|
bool SDLController::Close() {
|
||||||
@ -108,31 +41,14 @@ namespace Ship {
|
|||||||
SDL_GameControllerClose(Cont);
|
SDL_GameControllerClose(Cont);
|
||||||
}
|
}
|
||||||
Cont = nullptr;
|
Cont = nullptr;
|
||||||
guid = "";
|
|
||||||
ButtonMapping.clear();
|
|
||||||
ThresholdMapping.clear();
|
|
||||||
dwPressedButtons = 0;
|
|
||||||
wStickX = 0;
|
wStickX = 0;
|
||||||
wStickY = 0;
|
wStickY = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLController::LoadAxisThresholds() {
|
|
||||||
std::string ConfSection = GetBindingConfSection();
|
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
ThresholdMapping[SDL_CONTROLLER_AXIS_LEFTX] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTX) + "_threshold"]);
|
void SDLController::NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick, float sensitivity) {
|
||||||
ThresholdMapping[SDL_CONTROLLER_AXIS_LEFTY] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTY) + "_threshold"]);
|
|
||||||
ThresholdMapping[SDL_CONTROLLER_AXIS_RIGHTX] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTX) + "_threshold"]);
|
|
||||||
ThresholdMapping[SDL_CONTROLLER_AXIS_RIGHTY] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTY) + "_threshold"]);
|
|
||||||
ThresholdMapping[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERLEFT) + "_threshold"]);
|
|
||||||
ThresholdMapping[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + "_threshold"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SDLController::NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold) {
|
|
||||||
//scale {-32768 ... +32767} to {-84 ... +84}
|
//scale {-32768 ... +32767} to {-84 ... +84}
|
||||||
auto ax = wAxisValueX * 85.0 / 32767.0;
|
auto ax = wAxisValueX * 85.0 / 32767.0;
|
||||||
auto ay = wAxisValueY * 85.0 / 32767.0;
|
auto ay = wAxisValueY * 85.0 / 32767.0;
|
||||||
@ -163,14 +79,59 @@ namespace Ship {
|
|||||||
ay *= scale;
|
ay *= scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isRightStick) {
|
||||||
wStickX = +ax;
|
wStickX = +ax;
|
||||||
wStickY = -ay;
|
wStickY = -ay;
|
||||||
|
} else {
|
||||||
|
wCamX = +ax * sensitivity;
|
||||||
|
wCamY = -ay * sensitivity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLController::ReadFromSource() {
|
|
||||||
std::string ConfSection = GetBindingConfSection();
|
int32_t SDLController::ReadRawPress() {
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
SDL_GameControllerUpdate();
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
|
for (int32_t i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
|
||||||
|
if (SDL_GameControllerGetButton(Cont, static_cast<SDL_GameControllerButton>(i))) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) {
|
||||||
|
const auto Axis = static_cast<SDL_GameControllerAxis>(i);
|
||||||
|
const auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis) / 32767.0f;
|
||||||
|
|
||||||
|
if (AxisValue < -0.7f) {
|
||||||
|
return -(Axis + AXIS_SCANCODE_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AxisValue > 0.7f) {
|
||||||
|
return (Axis + AXIS_SCANCODE_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerThresholds SDLAxisToThreshold( uint32_t axis ){
|
||||||
|
switch(axis){
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||||
|
return LEFT_STICK;
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||||
|
return RIGHT_STICK;
|
||||||
|
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||||
|
return LEFT_TRIGGER;
|
||||||
|
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||||
|
return RIGHT_TRIGGER;
|
||||||
|
default: return DRIFT_X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLController::ReadFromSource(int32_t slot) {
|
||||||
|
DeviceProfile& profile = profiles[slot];
|
||||||
|
|
||||||
SDL_GameControllerUpdate();
|
SDL_GameControllerUpdate();
|
||||||
|
|
||||||
@ -187,17 +148,14 @@ namespace Ship {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_GameControllerHasSensor(Cont, SDL_SENSOR_GYRO))
|
if (supportsGyro && profile.UseGyro) {
|
||||||
{
|
|
||||||
size_t contNumber = GetControllerNumber();
|
|
||||||
|
|
||||||
float gyroData[3];
|
float gyroData[3];
|
||||||
SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3);
|
SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3);
|
||||||
|
|
||||||
const char* contName = SDL_GameControllerName(Cont);
|
float gyro_drift_x = profile.Thresholds[DRIFT_X] / 100.0f;
|
||||||
float gyro_drift_x = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), 0.0f);
|
float gyro_drift_y = profile.Thresholds[DRIFT_Y] / 100.0f;
|
||||||
float gyro_drift_y = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), 0.0f);
|
const float gyro_sensitivity = profile.Thresholds[GYRO_SENSITIVITY];
|
||||||
const float gyro_sensitivity = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroSensitivity", contNumber).c_str(), 1.0f);
|
|
||||||
|
|
||||||
if (gyro_drift_x == 0) {
|
if (gyro_drift_x == 0) {
|
||||||
gyro_drift_x = gyroData[0];
|
gyro_drift_x = gyroData[0];
|
||||||
@ -207,8 +165,8 @@ namespace Ship {
|
|||||||
gyro_drift_y = gyroData[1];
|
gyro_drift_y = gyroData[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), gyro_drift_x);
|
profile.Thresholds[DRIFT_X] = gyro_drift_x * 100.0f;
|
||||||
CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), gyro_drift_y);
|
profile.Thresholds[DRIFT_Y] = gyro_drift_y * 100.0f;
|
||||||
|
|
||||||
wGyroX = gyroData[0] - gyro_drift_x;
|
wGyroX = gyroData[0] - gyro_drift_x;
|
||||||
wGyroY = gyroData[1] - gyro_drift_y;
|
wGyroY = gyroData[1] - gyro_drift_y;
|
||||||
@ -217,29 +175,35 @@ namespace Ship {
|
|||||||
wGyroY *= gyro_sensitivity;
|
wGyroY *= gyro_sensitivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dwPressedButtons[slot] = 0;
|
||||||
|
|
||||||
for (int32_t i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
|
for (int32_t i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
|
||||||
if (ButtonMapping.contains(i)) {
|
if (profile.Mappings.contains(i)) {
|
||||||
if (SDL_GameControllerGetButton(Cont, (SDL_GameControllerButton)i)) {
|
if (SDL_GameControllerGetButton(Cont, static_cast<SDL_GameControllerButton>(i))) {
|
||||||
dwPressedButtons |= ButtonMapping[i];
|
dwPressedButtons[slot] |= profile.Mappings[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dwPressedButtons &= ~ButtonMapping[i];
|
dwPressedButtons[slot] &= ~profile.Mappings[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GameControllerAxis StickAxisX = SDL_CONTROLLER_AXIS_INVALID;
|
SDL_GameControllerAxis LStickAxisX = SDL_CONTROLLER_AXIS_INVALID;
|
||||||
SDL_GameControllerAxis StickAxisY = SDL_CONTROLLER_AXIS_INVALID;
|
SDL_GameControllerAxis LStickAxisY = SDL_CONTROLLER_AXIS_INVALID;
|
||||||
int32_t StickDeadzone = 0;
|
int32_t LStickDeadzone = 0;
|
||||||
|
|
||||||
|
SDL_GameControllerAxis RStickAxisX = SDL_CONTROLLER_AXIS_INVALID;
|
||||||
|
SDL_GameControllerAxis RStickAxisY = SDL_CONTROLLER_AXIS_INVALID;
|
||||||
|
int32_t RStickDeadzone = 0;
|
||||||
|
|
||||||
for (int32_t i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) {
|
for (int32_t i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) {
|
||||||
auto Axis = (SDL_GameControllerAxis)i;
|
const auto Axis = static_cast<SDL_GameControllerAxis>(i);
|
||||||
auto PosScancode = i + AXIS_SCANCODE_BIT;
|
const auto PosScancode = i + AXIS_SCANCODE_BIT;
|
||||||
auto NegScancode = -PosScancode;
|
const auto NegScancode = -PosScancode;
|
||||||
auto AxisThreshold = ThresholdMapping[i];
|
const auto AxisThreshold = static_cast<int>(profile.Thresholds[SDLAxisToThreshold(i)]);
|
||||||
auto PosButton = ButtonMapping[PosScancode];
|
const auto PosButton = profile.Mappings[PosScancode];
|
||||||
auto NegButton = ButtonMapping[NegScancode];
|
const auto NegButton = profile.Mappings[NegScancode];
|
||||||
auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis);
|
const auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis);
|
||||||
|
|
||||||
#ifdef TARGET_WEB
|
#ifdef TARGET_WEB
|
||||||
// Firefox has a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1606562
|
// Firefox has a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1606562
|
||||||
@ -252,94 +216,176 @@ namespace Ship {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If the axis is NOT mapped to the control stick.
|
|
||||||
if (!(
|
if (!(
|
||||||
PosButton == BTN_STICKLEFT || PosButton == BTN_STICKRIGHT ||
|
PosButton == BTN_STICKLEFT || PosButton == BTN_STICKRIGHT ||
|
||||||
PosButton == BTN_STICKUP || PosButton == BTN_STICKDOWN ||
|
PosButton == BTN_STICKUP || PosButton == BTN_STICKDOWN ||
|
||||||
NegButton == BTN_STICKLEFT || NegButton == BTN_STICKRIGHT ||
|
NegButton == BTN_STICKLEFT || NegButton == BTN_STICKRIGHT ||
|
||||||
NegButton == BTN_STICKUP || NegButton == BTN_STICKDOWN)) {
|
NegButton == BTN_STICKUP || NegButton == BTN_STICKDOWN)) {
|
||||||
if (AxisValue > AxisThreshold) {
|
|
||||||
dwPressedButtons |= PosButton;
|
if (AxisValue > 0x1E00) {
|
||||||
dwPressedButtons &= ~NegButton;
|
dwPressedButtons[slot] |= PosButton;
|
||||||
|
dwPressedButtons[slot] &= ~NegButton;
|
||||||
}
|
}
|
||||||
else if (AxisValue < -AxisThreshold) {
|
else if (AxisValue < -0x1E00) {
|
||||||
dwPressedButtons &= ~PosButton;
|
dwPressedButtons[slot] &= ~PosButton;
|
||||||
dwPressedButtons |= NegButton;
|
dwPressedButtons[slot] |= NegButton;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dwPressedButtons &= ~PosButton;
|
dwPressedButtons[slot] &= ~PosButton;
|
||||||
dwPressedButtons &= ~NegButton;
|
dwPressedButtons[slot] &= ~NegButton;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (PosButton == BTN_STICKLEFT || PosButton == BTN_STICKRIGHT) {
|
if (PosButton == BTN_STICKLEFT || PosButton == BTN_STICKRIGHT) {
|
||||||
if (StickAxisX != SDL_CONTROLLER_AXIS_INVALID && StickAxisX != Axis) {
|
if (LStickAxisX != SDL_CONTROLLER_AXIS_INVALID && LStickAxisX != Axis) {
|
||||||
SPDLOG_TRACE("Invalid PosStickX configured. Neg was {} and Pos is {}", StickAxisX, Axis);
|
SPDLOG_TRACE("Invalid PosStickX configured. Neg was {} and Pos is {}", LStickAxisX, Axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) {
|
if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) {
|
||||||
SPDLOG_TRACE("Invalid Deadzone configured. Up/Down was {} and Left/Right is {}", StickDeadzone, AxisThreshold);
|
SPDLOG_TRACE("Invalid Deadzone configured. Up/Down was {} and Left/Right is {}", LStickDeadzone, AxisThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
StickDeadzone = AxisThreshold;
|
LStickDeadzone = AxisThreshold;
|
||||||
StickAxisX = Axis;
|
LStickAxisX = Axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PosButton == BTN_STICKUP || PosButton == BTN_STICKDOWN) {
|
if (PosButton == BTN_STICKUP || PosButton == BTN_STICKDOWN) {
|
||||||
if (StickAxisY != SDL_CONTROLLER_AXIS_INVALID && StickAxisY != Axis) {
|
if (LStickAxisY != SDL_CONTROLLER_AXIS_INVALID && LStickAxisY != Axis) {
|
||||||
SPDLOG_TRACE("Invalid PosStickY configured. Neg was {} and Pos is {}", StickAxisY, Axis);
|
SPDLOG_TRACE("Invalid PosStickY configured. Neg was {} and Pos is {}", LStickAxisY, Axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) {
|
if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) {
|
||||||
SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", StickDeadzone, AxisThreshold);
|
SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", LStickDeadzone, AxisThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
StickDeadzone = AxisThreshold;
|
LStickDeadzone = AxisThreshold;
|
||||||
StickAxisY = Axis;
|
LStickAxisY = Axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NegButton == BTN_STICKLEFT || NegButton == BTN_STICKRIGHT) {
|
if (NegButton == BTN_STICKLEFT || NegButton == BTN_STICKRIGHT) {
|
||||||
if (StickAxisX != SDL_CONTROLLER_AXIS_INVALID && StickAxisX != Axis) {
|
if (LStickAxisX != SDL_CONTROLLER_AXIS_INVALID && LStickAxisX != Axis) {
|
||||||
SPDLOG_TRACE("Invalid NegStickX configured. Pos was {} and Neg is {}", StickAxisX, Axis);
|
SPDLOG_TRACE("Invalid NegStickX configured. Pos was {} and Neg is {}", LStickAxisX, Axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) {
|
if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) {
|
||||||
SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", StickDeadzone, AxisThreshold);
|
SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", LStickDeadzone, AxisThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
StickDeadzone = AxisThreshold;
|
LStickDeadzone = AxisThreshold;
|
||||||
StickAxisX = Axis;
|
LStickAxisX = Axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NegButton == BTN_STICKUP || NegButton == BTN_STICKDOWN) {
|
if (NegButton == BTN_STICKUP || NegButton == BTN_STICKDOWN) {
|
||||||
if (StickAxisY != SDL_CONTROLLER_AXIS_INVALID && StickAxisY != Axis) {
|
if (LStickAxisY != SDL_CONTROLLER_AXIS_INVALID && LStickAxisY != Axis) {
|
||||||
SPDLOG_TRACE("Invalid NegStickY configured. Pos was {} and Neg is {}", StickAxisY, Axis);
|
SPDLOG_TRACE("Invalid NegStickY configured. Pos was {} and Neg is {}", LStickAxisY, Axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) {
|
if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) {
|
||||||
SPDLOG_TRACE("Invalid Deadzone misconfigured. Left/Right was {} and Up/Down is {}", StickDeadzone, AxisThreshold);
|
SPDLOG_TRACE("Invalid Deadzone misconfigured. Left/Right was {} and Up/Down is {}", LStickDeadzone, AxisThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
StickDeadzone = AxisThreshold;
|
LStickDeadzone = AxisThreshold;
|
||||||
StickAxisY = Axis;
|
LStickAxisY = Axis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StickAxisX != SDL_CONTROLLER_AXIS_INVALID && StickAxisY != SDL_CONTROLLER_AXIS_INVALID) {
|
if (LStickAxisX != SDL_CONTROLLER_AXIS_INVALID && LStickAxisY != SDL_CONTROLLER_AXIS_INVALID) {
|
||||||
auto AxisValueX = SDL_GameControllerGetAxis(Cont, StickAxisX);
|
const auto AxisValueX = SDL_GameControllerGetAxis(Cont, LStickAxisX);
|
||||||
auto AxisValueY = SDL_GameControllerGetAxis(Cont, StickAxisY);
|
const auto AxisValueY = SDL_GameControllerGetAxis(Cont, LStickAxisY);
|
||||||
NormalizeStickAxis(AxisValueX, AxisValueY, StickDeadzone);
|
NormalizeStickAxis(AxisValueX, AxisValueY, LStickDeadzone, false, profile.Thresholds[SENSITIVITY]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Right Stick
|
||||||
|
// If the axis is NOT mapped to the control stick.
|
||||||
|
if (!(
|
||||||
|
PosButton == BTN_VSTICKLEFT || PosButton == BTN_VSTICKRIGHT ||
|
||||||
|
PosButton == BTN_VSTICKUP || PosButton == BTN_VSTICKDOWN ||
|
||||||
|
NegButton == BTN_VSTICKLEFT || NegButton == BTN_VSTICKRIGHT ||
|
||||||
|
NegButton == BTN_VSTICKUP || NegButton == BTN_VSTICKDOWN)) {
|
||||||
|
|
||||||
|
if (AxisValue > 0x1E00) {
|
||||||
|
dwPressedButtons[slot] |= PosButton;
|
||||||
|
dwPressedButtons[slot] &= ~NegButton;
|
||||||
|
}
|
||||||
|
else if (AxisValue < -0x1E00) {
|
||||||
|
dwPressedButtons[slot] &= ~PosButton;
|
||||||
|
dwPressedButtons[slot] |= NegButton;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dwPressedButtons[slot] &= ~PosButton;
|
||||||
|
dwPressedButtons[slot] &= ~NegButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLController::WriteToSource(ControllerCallback* controller)
|
|
||||||
{
|
|
||||||
if (CanRumble()) {
|
|
||||||
if (controller->rumble > 0) {
|
|
||||||
float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", GetControllerNumber()).c_str(), 1.0f);
|
|
||||||
SDL_GameControllerRumble(Cont, 0xFFFF * rumble_strength, 0xFFFF * rumble_strength, 0);
|
|
||||||
} else {
|
} else {
|
||||||
|
if (PosButton == BTN_VSTICKLEFT || PosButton == BTN_VSTICKRIGHT) {
|
||||||
|
if (RStickAxisX != SDL_CONTROLLER_AXIS_INVALID && RStickAxisX != Axis) {
|
||||||
|
SPDLOG_TRACE("Invalid PosStickX configured. Neg was {} and Pos is {}", RStickAxisX, Axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) {
|
||||||
|
SPDLOG_TRACE("Invalid Deadzone configured. Up/Down was {} and Left/Right is {}", RStickDeadzone, AxisThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
RStickDeadzone = AxisThreshold;
|
||||||
|
RStickAxisX = Axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PosButton == BTN_VSTICKUP || PosButton == BTN_VSTICKDOWN) {
|
||||||
|
if (RStickAxisY != SDL_CONTROLLER_AXIS_INVALID && RStickAxisY != Axis) {
|
||||||
|
SPDLOG_TRACE("Invalid PosStickY configured. Neg was {} and Pos is {}", RStickAxisY, Axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) {
|
||||||
|
SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", RStickDeadzone, AxisThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
RStickDeadzone = AxisThreshold;
|
||||||
|
RStickAxisY = Axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NegButton == BTN_VSTICKLEFT || NegButton == BTN_VSTICKRIGHT) {
|
||||||
|
if (RStickAxisX != SDL_CONTROLLER_AXIS_INVALID && RStickAxisX != Axis) {
|
||||||
|
SPDLOG_TRACE("Invalid NegStickX configured. Pos was {} and Neg is {}", RStickAxisX, Axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) {
|
||||||
|
SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", RStickDeadzone, AxisThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
RStickDeadzone = AxisThreshold;
|
||||||
|
RStickAxisX = Axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NegButton == BTN_VSTICKUP || NegButton == BTN_VSTICKDOWN) {
|
||||||
|
if (RStickAxisY != SDL_CONTROLLER_AXIS_INVALID && RStickAxisY != Axis) {
|
||||||
|
SPDLOG_TRACE("Invalid NegStickY configured. Pos was {} and Neg is {}", RStickAxisY, Axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) {
|
||||||
|
SPDLOG_TRACE("Invalid Deadzone misconfigured. Left/Right was {} and Up/Down is {}", RStickDeadzone, AxisThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
RStickDeadzone = AxisThreshold;
|
||||||
|
RStickAxisY = Axis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RStickAxisX != SDL_CONTROLLER_AXIS_INVALID && RStickAxisY != SDL_CONTROLLER_AXIS_INVALID) {
|
||||||
|
const auto AxisValueX = SDL_GameControllerGetAxis(Cont, RStickAxisX);
|
||||||
|
const auto AxisValueY = SDL_GameControllerGetAxis(Cont, RStickAxisY);
|
||||||
|
NormalizeStickAxis(AxisValueX, AxisValueY, RStickDeadzone, true, profile.Thresholds[SENSITIVITY]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDLController::WriteToSource(int32_t slot, ControllerCallback* controller)
|
||||||
|
{
|
||||||
|
if (CanRumble() && profiles[slot].UseRumble) {
|
||||||
|
if (controller->rumble > 0) {
|
||||||
|
float rumble_strength = profiles[slot].RumbleStrength;
|
||||||
|
SDL_GameControllerRumble(Cont, 0xFFFF * rumble_strength, 0xFFFF * rumble_strength, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
SDL_GameControllerRumble(Cont, 0, 0, 0);
|
SDL_GameControllerRumble(Cont, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,73 +408,74 @@ namespace Ship {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLController::CreateDefaultBinding() {
|
const char* AxisNames[] = {
|
||||||
std::string ConfSection = GetBindingConfSection();
|
"Left Stick X",
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
"Left Stick Y",
|
||||||
ConfigFile& Conf = *pConf.get();
|
"Right Stick X",
|
||||||
|
"Right Stick Y",
|
||||||
|
"Left Trigger",
|
||||||
|
"Right Trigger",
|
||||||
|
"Start Button"
|
||||||
|
};
|
||||||
|
|
||||||
Conf[ConfSection][STR(BTN_CRIGHT)] = std::to_string((SDL_CONTROLLER_AXIS_RIGHTX + AXIS_SCANCODE_BIT));
|
char buffer[50];
|
||||||
Conf[ConfSection][STR(BTN_CLEFT)] = std::to_string(-(SDL_CONTROLLER_AXIS_RIGHTX + AXIS_SCANCODE_BIT));
|
const char* SDLController::GetButtonName(int slot, int n64Button) {
|
||||||
Conf[ConfSection][STR(BTN_CDOWN)] = std::to_string((SDL_CONTROLLER_AXIS_RIGHTY + AXIS_SCANCODE_BIT));
|
std::map<int32_t, int32_t>& Mappings = profiles[slot].Mappings;
|
||||||
Conf[ConfSection][STR(BTN_CUP)] = std::to_string(-(SDL_CONTROLLER_AXIS_RIGHTY + AXIS_SCANCODE_BIT));
|
const auto find = std::find_if(Mappings.begin(), Mappings.end(), [n64Button](const std::pair<int32_t, int32_t>& pair) {
|
||||||
//Conf[ConfSection][STR(BTN_CRIGHT + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_X);
|
return pair.second == n64Button;
|
||||||
//Conf[ConfSection][STR(BTN_CLEFT + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_Y);
|
});
|
||||||
//Conf[ConfSection][STR(BTN_CDOWN + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
|
||||||
//Conf[ConfSection][STR(BTN_CUP + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
|
||||||
Conf[ConfSection][STR(BTN_R)] = std::to_string((SDL_CONTROLLER_AXIS_TRIGGERRIGHT + AXIS_SCANCODE_BIT));
|
|
||||||
Conf[ConfSection][STR(BTN_L)] = std::to_string(SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
|
||||||
Conf[ConfSection][STR(BTN_DRIGHT)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
|
||||||
Conf[ConfSection][STR(BTN_DLEFT)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
|
||||||
Conf[ConfSection][STR(BTN_DDOWN)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
|
||||||
Conf[ConfSection][STR(BTN_DUP)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_UP);
|
|
||||||
Conf[ConfSection][STR(BTN_START)] = std::to_string(SDL_CONTROLLER_BUTTON_START);
|
|
||||||
Conf[ConfSection][STR(BTN_Z)] = std::to_string((SDL_CONTROLLER_AXIS_TRIGGERLEFT + AXIS_SCANCODE_BIT));
|
|
||||||
Conf[ConfSection][STR(BTN_B)] = std::to_string(SDL_CONTROLLER_BUTTON_B);
|
|
||||||
Conf[ConfSection][STR(BTN_A)] = std::to_string(SDL_CONTROLLER_BUTTON_A);
|
|
||||||
Conf[ConfSection][STR(BTN_STICKRIGHT)] = std::to_string((SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT));
|
|
||||||
Conf[ConfSection][STR(BTN_STICKLEFT)] = std::to_string(-(SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT));
|
|
||||||
Conf[ConfSection][STR(BTN_STICKDOWN)] = std::to_string((SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT));
|
|
||||||
Conf[ConfSection][STR(BTN_STICKUP)] = std::to_string(-(SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT));
|
|
||||||
|
|
||||||
Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTX) + "_threshold"] = std::to_string(16.0);
|
if (find == Mappings.end()) return "Unknown";
|
||||||
Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTY) + "_threshold"] = std::to_string(16.0);
|
|
||||||
Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTX) + "_threshold"] = std::to_string(0x4000);
|
|
||||||
Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTY) + "_threshold"] = std::to_string(0x4000);
|
|
||||||
Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERLEFT) + "_threshold"] = std::to_string(0x1E00);
|
|
||||||
Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + "_threshold"] = std::to_string(0x1E00);
|
|
||||||
|
|
||||||
Conf.Save();
|
int btn = abs(find->first);
|
||||||
|
|
||||||
|
if(btn >= AXIS_SCANCODE_BIT) {
|
||||||
|
btn -= AXIS_SCANCODE_BIT;
|
||||||
|
|
||||||
|
snprintf(buffer, sizeof(buffer), "%s%s", AxisNames[btn], find->first > 0 ? "+" : "-");
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLController::CreateDefaultPadConf() {
|
snprintf(buffer, sizeof(buffer), "Button %d", btn);
|
||||||
std::string ConfSection = *GetPadConfSection();
|
return buffer;
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
Conf.Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLController::SetButtonMapping(const std::string& szButtonName, int32_t dwScancode) {
|
const char* SDLController::GetControllerName() {
|
||||||
if (guid.compare(INVALID_SDL_CONTROLLER_GUID)) {
|
return SDL_GameControllerNameForIndex(physicalSlot);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller::SetButtonMapping(szButtonName, dwScancode);
|
void SDLController::CreateDefaultBinding(int32_t slot) {
|
||||||
}
|
DeviceProfile& profile = profiles[slot];
|
||||||
|
profile.Mappings.clear();
|
||||||
|
|
||||||
std::string SDLController::GetControllerType() {
|
profile.UseRumble = true;
|
||||||
return "SDL";
|
profile.RumbleStrength = 1.0f;
|
||||||
}
|
profile.UseGyro = false;
|
||||||
|
profile.Mappings[ SDL_CONTROLLER_AXIS_RIGHTX | AXIS_SCANCODE_BIT] = BTN_CRIGHT;
|
||||||
std::string SDLController::GetConfSection() {
|
profile.Mappings[-(SDL_CONTROLLER_AXIS_RIGHTX | AXIS_SCANCODE_BIT)] = BTN_CLEFT;
|
||||||
return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1);
|
profile.Mappings[ SDL_CONTROLLER_AXIS_RIGHTY | AXIS_SCANCODE_BIT] = BTN_CDOWN;
|
||||||
}
|
profile.Mappings[-(SDL_CONTROLLER_AXIS_RIGHTY | AXIS_SCANCODE_BIT)] = BTN_CUP;
|
||||||
|
profile.Mappings[SDL_CONTROLLER_AXIS_TRIGGERRIGHT + AXIS_SCANCODE_BIT] = BTN_R;
|
||||||
std::string SDLController::GetBindingConfSection() {
|
profile.Mappings[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = BTN_L;
|
||||||
return GetControllerType() + " CONTROLLER BINDING " + guid;
|
profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_RIGHT] = BTN_DRIGHT;
|
||||||
}
|
profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_LEFT] = BTN_DLEFT;
|
||||||
|
profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_DOWN] = BTN_DDOWN;
|
||||||
std::optional<std::string> SDLController::GetPadConfSection() {
|
profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_UP] = BTN_DUP;
|
||||||
return GetControllerType() + " CONTROLLER PAD " + guid;
|
profile.Mappings[SDL_CONTROLLER_BUTTON_START] = BTN_START;
|
||||||
|
profile.Mappings[SDL_CONTROLLER_AXIS_TRIGGERLEFT + AXIS_SCANCODE_BIT] = BTN_Z;
|
||||||
|
profile.Mappings[SDL_CONTROLLER_BUTTON_B] = BTN_B;
|
||||||
|
profile.Mappings[SDL_CONTROLLER_BUTTON_A] = BTN_A;
|
||||||
|
profile.Mappings[(SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT)] = BTN_STICKRIGHT;
|
||||||
|
profile.Mappings[-(SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT)] = BTN_STICKLEFT;
|
||||||
|
profile.Mappings[SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT] = BTN_STICKDOWN;
|
||||||
|
profile.Mappings[-(SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT)] = BTN_STICKUP;
|
||||||
|
profile.Thresholds[LEFT_STICK] = 16.0f;
|
||||||
|
profile.Thresholds[RIGHT_STICK] = 16.0f;
|
||||||
|
profile.Thresholds[LEFT_TRIGGER] = 0x1E00;
|
||||||
|
profile.Thresholds[RIGHT_TRIGGER] = 0x1E00;
|
||||||
|
profile.Thresholds[DRIFT_X] = 0.0f;
|
||||||
|
profile.Thresholds[DRIFT_Y] = 0.0f;
|
||||||
|
profile.Thresholds[SENSITIVITY] = 16.0f;
|
||||||
|
profile.Thresholds[GYRO_SENSITIVITY] = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,46 +6,35 @@
|
|||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define INVALID_SDL_CONTROLLER_GUID (std::string("00000000000000000000000000000000"))
|
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
class SDLController : public Controller {
|
class SDLController : public Controller {
|
||||||
public:
|
public:
|
||||||
SDLController(int32_t dwControllerNumber);
|
SDLController(int slot) : Controller(), Cont(nullptr), physicalSlot(slot) { }
|
||||||
~SDLController();
|
void ReadFromSource(int32_t slot) override;
|
||||||
|
const char* GetControllerName() override;
|
||||||
void ReadFromSource();
|
const char* GetButtonName(int slot, int n64Button) override;
|
||||||
void WriteToSource(ControllerCallback* controller);
|
void WriteToSource(int32_t slot, ControllerCallback* controller) override;
|
||||||
bool Connected() const { return Cont != nullptr; }
|
bool Connected() const override { return Cont != nullptr; }
|
||||||
bool CanRumble() const {
|
bool CanGyro() const override { return supportsGyro; }
|
||||||
|
bool CanRumble() const override {
|
||||||
#if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(2,0,18)
|
#if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(2,0,18)
|
||||||
return SDL_GameControllerHasRumble(Cont);
|
return SDL_GameControllerHasRumble(Cont);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetGuid() { return guid; };
|
bool Open();
|
||||||
|
void ClearRawPress() override {}
|
||||||
bool HasPadConf() const { return true; }
|
int32_t ReadRawPress() override;
|
||||||
std::optional<std::string> GetPadConfSection();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string GetControllerType();
|
void CreateDefaultBinding(int32_t slot) override;
|
||||||
void SetButtonMapping(const std::string& szButtonName, int32_t dwScancode);
|
|
||||||
std::string GetConfSection();
|
|
||||||
std::string GetBindingConfSection();
|
|
||||||
void CreateDefaultBinding();
|
|
||||||
void CreateDefaultPadConf();
|
|
||||||
static bool IsGuidInUse(const std::string& guid);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_GameController* Cont;
|
SDL_GameController* Cont;
|
||||||
std::string guid;
|
int physicalSlot;
|
||||||
std::map<int32_t, int16_t> ThresholdMapping;
|
bool supportsGyro;
|
||||||
|
void NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick, float sensitivity);
|
||||||
void LoadAxisThresholds();
|
|
||||||
void NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold);
|
|
||||||
bool Open();
|
|
||||||
bool Close();
|
bool Close();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,10 @@
|
|||||||
#define BTN_STICKRIGHT 0x20000
|
#define BTN_STICKRIGHT 0x20000
|
||||||
#define BTN_STICKDOWN 0x40000
|
#define BTN_STICKDOWN 0x40000
|
||||||
#define BTN_STICKUP 0x80000
|
#define BTN_STICKUP 0x80000
|
||||||
|
#define BTN_VSTICKUP 0x100000
|
||||||
|
#define BTN_VSTICKDOWN 0x200000
|
||||||
|
#define BTN_VSTICKLEFT 0x400000
|
||||||
|
#define BTN_VSTICKRIGHT 0x800000
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ int32_t ram[15];
|
/* 0x00 */ int32_t ram[15];
|
||||||
@ -120,7 +124,9 @@ typedef struct {
|
|||||||
/* 0x04 */ uint8_t err_no;
|
/* 0x04 */ uint8_t err_no;
|
||||||
/* 0x05 */ float gyro_x;
|
/* 0x05 */ float gyro_x;
|
||||||
/* 0x09 */ float gyro_y;
|
/* 0x09 */ float gyro_y;
|
||||||
} OSContPad; // size = 0x0D
|
/* 0x1C */ float cam_x;
|
||||||
|
/* 0x20 */ float cam_y;
|
||||||
|
} OSContPad; // size = 0x24
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ uint8_t rumble;
|
/* 0x00 */ uint8_t rumble;
|
||||||
|
@ -38,8 +38,7 @@ extern "C" {
|
|||||||
uint8_t __enableGameInput = 1;
|
uint8_t __enableGameInput = 1;
|
||||||
|
|
||||||
int32_t osContInit(OSMesgQueue* mq, uint8_t* controllerBits, OSContStatus* status) {
|
int32_t osContInit(OSMesgQueue* mq, uint8_t* controllerBits, OSContStatus* status) {
|
||||||
std::shared_ptr<Ship::ConfigFile> pConf = Ship::GlobalCtx2::GetInstance()->GetConfig();
|
*controllerBits = 0;
|
||||||
Ship::ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) {
|
if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) {
|
||||||
SPDLOG_ERROR("Failed to initialize SDL game controllers ({})", SDL_GetError());
|
SPDLOG_ERROR("Failed to initialize SDL game controllers ({})", SDL_GetError());
|
||||||
@ -54,43 +53,7 @@ extern "C" {
|
|||||||
SPDLOG_ERROR("Failed add SDL game controller mappings from \"{}\" ({})", controllerDb, SDL_GetError());
|
SPDLOG_ERROR("Failed add SDL game controller mappings from \"{}\" ({})", controllerDb, SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This for loop is debug. Burn it with fire.
|
Ship::Window::ControllerApi->Init(controllerBits);
|
||||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
|
||||||
if (SDL_IsGameController(i)) {
|
|
||||||
// Get the GUID from SDL
|
|
||||||
char buf[33];
|
|
||||||
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), buf, sizeof(buf));
|
|
||||||
auto guid = std::string(buf);
|
|
||||||
auto name = std::string(SDL_GameControllerNameForIndex(i));
|
|
||||||
|
|
||||||
SPDLOG_INFO("Found Controller \"{}\" with ID \"{}\"", name, guid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < __osMaxControllers; i++) {
|
|
||||||
std::string ControllerType = Conf["CONTROLLERS"]["CONTROLLER " + std::to_string(i+1)];
|
|
||||||
mINI::INIStringUtil::toLower(ControllerType);
|
|
||||||
|
|
||||||
if (ControllerType == "auto") {
|
|
||||||
Ship::Window::Controllers[i].push_back(std::make_shared<Ship::KeyboardController>(i));
|
|
||||||
Ship::Window::Controllers[i].push_back(std::make_shared<Ship::SDLController>(i));
|
|
||||||
} else if (ControllerType == "keyboard") {
|
|
||||||
Ship::Window::Controllers[i].push_back(std::make_shared<Ship::KeyboardController>(i));
|
|
||||||
} else if (ControllerType == "usb") {
|
|
||||||
Ship::Window::Controllers[i].push_back(std::make_shared<Ship::SDLController>(i));
|
|
||||||
} else if (ControllerType == "unplugged") {
|
|
||||||
// Do nothing for unplugged controllers
|
|
||||||
} else {
|
|
||||||
SPDLOG_ERROR("Invalid Controller Type: {}", ControllerType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*controllerBits = 0;
|
|
||||||
for (size_t i = 0; i < __osMaxControllers; i++) {
|
|
||||||
if (Ship::Window::Controllers[i].size() > 0) {
|
|
||||||
*controllerBits |= 1 << i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -103,17 +66,14 @@ extern "C" {
|
|||||||
pad->button = 0;
|
pad->button = 0;
|
||||||
pad->stick_x = 0;
|
pad->stick_x = 0;
|
||||||
pad->stick_y = 0;
|
pad->stick_y = 0;
|
||||||
|
pad->cam_x = 0;
|
||||||
|
pad->cam_y = 0;
|
||||||
pad->err_no = 0;
|
pad->err_no = 0;
|
||||||
pad->gyro_x = 0;
|
pad->gyro_x = 0;
|
||||||
pad->gyro_y = 0;
|
pad->gyro_y = 0;
|
||||||
|
|
||||||
if (__enableGameInput)
|
if (__enableGameInput) {
|
||||||
{
|
Ship::Window::ControllerApi->WriteToPad(pad);
|
||||||
for (size_t i = 0; i < __osMaxControllers; i++) {
|
|
||||||
for (size_t j = 0; j < Ship::Window::Controllers[i].size(); j++) {
|
|
||||||
Ship::Window::Controllers[i][j]->Read(&pad[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModInternal::ExecuteHooks<ModInternal::ControllerRead>(pad);
|
ModInternal::ExecuteHooks<ModInternal::ControllerRead>(pad);
|
||||||
@ -129,16 +89,11 @@ extern "C" {
|
|||||||
|
|
||||||
if (hashStr != nullptr) {
|
if (hashStr != nullptr) {
|
||||||
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||||
|
|
||||||
//if (res != nullptr)
|
|
||||||
return (Vtx*)res->vertices.data();
|
return (Vtx*)res->vertices.data();
|
||||||
//else
|
|
||||||
//return (Vtx*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadFile(hashStr)->buffer.get();
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) {
|
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) {
|
||||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||||
@ -146,9 +101,9 @@ extern "C" {
|
|||||||
if (hashStr != nullptr) {
|
if (hashStr != nullptr) {
|
||||||
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||||
return (int32_t*)res->mtx.data();
|
return (int32_t*)res->mtx.data();
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) {
|
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) {
|
||||||
@ -233,7 +188,7 @@ extern GfxWindowManagerAPI gfx_sdl;
|
|||||||
void SetWindowManager(GfxWindowManagerAPI** WmApi, GfxRenderingAPI** RenderingApi, const std::string& gfx_backend);
|
void SetWindowManager(GfxWindowManagerAPI** WmApi, GfxRenderingAPI** RenderingApi, const std::string& gfx_backend);
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
std::map<size_t, std::vector<std::shared_ptr<Controller>>> Window::Controllers;
|
|
||||||
int32_t Window::lastScancode;
|
int32_t Window::lastScancode;
|
||||||
|
|
||||||
Window::Window(std::shared_ptr<GlobalCtx2> Context) : Context(Context), APlayer(nullptr) {
|
Window::Window(std::shared_ptr<GlobalCtx2> Context) : Context(Context), APlayer(nullptr) {
|
||||||
@ -248,26 +203,55 @@ namespace Ship {
|
|||||||
SPDLOG_INFO("destruct window");
|
SPDLOG_INFO("destruct window");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::CreateDefaults() {
|
||||||
|
const std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
|
if (pConf->isNewInstance) {
|
||||||
|
pConf->setInt("Window.Width", 640);
|
||||||
|
pConf->setInt("Window.Height", 480);
|
||||||
|
pConf->setBool("Window.Options", false);
|
||||||
|
pConf->setString("Window.GfxBackend", "");
|
||||||
|
|
||||||
|
pConf->setBool("Window.Fullscreen.Enabled", false);
|
||||||
|
pConf->setInt("Window.Fullscreen.Width", 1920);
|
||||||
|
pConf->setInt("Window.Fullscreen.Height", 1080);
|
||||||
|
|
||||||
|
pConf->setString("Game.SaveName", "");
|
||||||
|
pConf->setString("Game.Main Archive", "");
|
||||||
|
pConf->setString("Game.Patches Archive", "");
|
||||||
|
|
||||||
|
pConf->setInt("Shortcuts.Fullscreen", 0x044);
|
||||||
|
pConf->setInt("Shortcuts.Console", 0x029);
|
||||||
|
pConf->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Window::Init() {
|
void Window::Init() {
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
|
CreateDefaults();
|
||||||
|
|
||||||
SetAudioPlayer();
|
SetAudioPlayer();
|
||||||
bIsFullscreen = Ship::stob(Conf["WINDOW"]["FULLSCREEN"]);
|
bIsFullscreen = pConf->getBool("Window.Fullscreen.Enabled", false);
|
||||||
|
|
||||||
if (bIsFullscreen) {
|
if (bIsFullscreen) {
|
||||||
dwWidth = Ship::stoi(Conf["WINDOW"]["FULLSCREEN WIDTH"], 1920);
|
dwWidth = pConf->getInt("Window.Fullscreen.Width", 1920);
|
||||||
dwHeight = Ship::stoi(Conf["WINDOW"]["FULLSCREEN HEIGHT"], 1080);
|
dwHeight = pConf->getInt("Window.Fullscreen.Height", 1080);
|
||||||
} else {
|
} else {
|
||||||
dwWidth = Ship::stoi(Conf["WINDOW"]["WINDOW WIDTH"], 640);
|
dwWidth = pConf->getInt("Window.Width", 640);
|
||||||
dwHeight = Ship::stoi(Conf["WINDOW"]["WINDOW HEIGHT"], 480);
|
dwHeight = pConf->getInt("Window.Height", 480);
|
||||||
}
|
}
|
||||||
dwMenubar = Ship::stoi(Conf["WINDOW"]["menubar"], 0);
|
|
||||||
const std::string& gfx_backend = Conf["WINDOW"]["GFX BACKEND"];
|
dwMenubar = pConf->getBool("Window.Options", false);
|
||||||
|
const std::string& gfx_backend = pConf->getString("Window.GfxBackend");
|
||||||
SetWindowManager(&WmApi, &RenderingApi, gfx_backend);
|
SetWindowManager(&WmApi, &RenderingApi, gfx_backend);
|
||||||
|
|
||||||
gfx_init(WmApi, RenderingApi, GetContext()->GetName().c_str(), bIsFullscreen, dwWidth, dwHeight);
|
gfx_init(WmApi, RenderingApi, GetContext()->GetName().c_str(), bIsFullscreen, dwWidth, dwHeight);
|
||||||
WmApi->set_fullscreen_changed_callback(Window::OnFullscreenChanged);
|
WmApi->set_fullscreen_changed_callback(OnFullscreenChanged);
|
||||||
WmApi->set_keyboard_callbacks(Window::KeyDown, Window::KeyUp, Window::AllKeysUp);
|
WmApi->set_keyboard_callbacks(KeyDown, KeyUp, AllKeysUp);
|
||||||
|
|
||||||
|
ModInternal::RegisterHook<ModInternal::ExitGame>([]() {
|
||||||
|
ControllerApi->SaveControllerSettings();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::StartFrame() {
|
void Window::StartFrame() {
|
||||||
@ -318,48 +302,41 @@ namespace Ship {
|
|||||||
void Window::MainLoop(void (*MainFunction)(void)) {
|
void Window::MainLoop(void (*MainFunction)(void)) {
|
||||||
WmApi->main_loop(MainFunction);
|
WmApi->main_loop(MainFunction);
|
||||||
}
|
}
|
||||||
bool Window::KeyUp(int32_t dwScancode) {
|
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
if (dwScancode == Ship::stoi(Conf["KEYBOARD SHORTCUTS"]["KEY_FULLSCREEN"])) {
|
bool Window::KeyUp(int32_t dwScancode) {
|
||||||
|
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
|
|
||||||
|
if (dwScancode == pConf->getInt("Shortcuts.Fullscreen", 0x044)) {
|
||||||
GlobalCtx2::GetInstance()->GetWindow()->ToggleFullscreen();
|
GlobalCtx2::GetInstance()->GetWindow()->ToggleFullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// OTRTODO: Rig with Kirito's console?
|
// OTRTODO: Rig with Kirito's console?
|
||||||
//if (dwScancode == Ship::stoi(Conf["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"])) {
|
//if (dwScancode == Ship::stoi(Conf["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"])) {
|
||||||
// ToggleConsole();
|
// ToggleConsole();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
lastScancode = -1;
|
||||||
|
|
||||||
bool bIsProcessed = false;
|
bool bIsProcessed = false;
|
||||||
for (size_t i = 0; i < __osMaxControllers; i++) {
|
const auto pad = dynamic_cast<KeyboardController*>(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get());
|
||||||
for (size_t j = 0; j < Controllers[i].size(); j++) {
|
|
||||||
KeyboardController* pad = dynamic_cast<KeyboardController*>(Ship::Window::Controllers[i][j].get());
|
|
||||||
if (pad != nullptr) {
|
if (pad != nullptr) {
|
||||||
if (pad->ReleaseButton(dwScancode)) {
|
if (pad->ReleaseButton(dwScancode)) {
|
||||||
bIsProcessed = true;
|
bIsProcessed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bIsProcessed;
|
return bIsProcessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Window::KeyDown(int32_t dwScancode) {
|
bool Window::KeyDown(int32_t dwScancode) {
|
||||||
bool bIsProcessed = false;
|
bool bIsProcessed = false;
|
||||||
for (size_t i = 0; i < __osMaxControllers; i++) {
|
|
||||||
for (size_t j = 0; j < Controllers[i].size(); j++) {
|
const auto pad = dynamic_cast<KeyboardController*>(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get());
|
||||||
KeyboardController* pad = dynamic_cast<KeyboardController*>(Ship::Window::Controllers[i][j].get());
|
|
||||||
if (pad != nullptr) {
|
if (pad != nullptr) {
|
||||||
if (pad->PressButton(dwScancode)) {
|
if (pad->PressButton(dwScancode)) {
|
||||||
bIsProcessed = true;
|
bIsProcessed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastScancode = dwScancode;
|
lastScancode = dwScancode;
|
||||||
|
|
||||||
@ -368,21 +345,17 @@ namespace Ship {
|
|||||||
|
|
||||||
|
|
||||||
void Window::AllKeysUp(void) {
|
void Window::AllKeysUp(void) {
|
||||||
for (size_t i = 0; i < __osMaxControllers; i++) {
|
const auto pad = dynamic_cast<KeyboardController*>(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get());
|
||||||
for (size_t j = 0; j < Controllers[i].size(); j++) {
|
|
||||||
KeyboardController* pad = dynamic_cast<KeyboardController*>(Ship::Window::Controllers[i][j].get());
|
|
||||||
if (pad != nullptr) {
|
if (pad != nullptr) {
|
||||||
pad->ReleaseAllButtons();
|
pad->ReleaseAllButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::OnFullscreenChanged(bool bIsFullscreen) {
|
void Window::OnFullscreenChanged(bool bIsFullscreen) {
|
||||||
std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
||||||
ConfigFile& Conf = *pConf.get();
|
|
||||||
GlobalCtx2::GetInstance()->GetWindow()->bIsFullscreen = bIsFullscreen;
|
GlobalCtx2::GetInstance()->GetWindow()->bIsFullscreen = bIsFullscreen;
|
||||||
Conf["WINDOW"]["FULLSCREEN"] = std::to_string(bIsFullscreen);
|
pConf->setBool("Window.Fullscreen.Enabled", bIsFullscreen);
|
||||||
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(!bIsFullscreen);
|
GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(!bIsFullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,17 +5,22 @@
|
|||||||
#include "UltraController.h"
|
#include "UltraController.h"
|
||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include "GlobalCtx2.h"
|
#include "GlobalCtx2.h"
|
||||||
|
#include "ControlDeck.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Lib/Fast3D/gfx_window_manager_api.h"
|
||||||
|
|
||||||
namespace Ship {
|
namespace Ship {
|
||||||
class AudioPlayer;
|
class AudioPlayer;
|
||||||
|
|
||||||
class Window {
|
class Window {
|
||||||
public:
|
public:
|
||||||
static std::map<size_t, std::vector<std::shared_ptr<Controller>>> Controllers;
|
|
||||||
static int32_t lastScancode;
|
static int32_t lastScancode;
|
||||||
|
inline static ControlDeck* ControllerApi = new ControlDeck;
|
||||||
|
|
||||||
Window(std::shared_ptr<GlobalCtx2> Context);
|
Window(std::shared_ptr<GlobalCtx2> Context);
|
||||||
~Window();
|
~Window();
|
||||||
|
void CreateDefaults();
|
||||||
void MainLoop(void (*MainFunction)(void));
|
void MainLoop(void (*MainFunction)(void));
|
||||||
void Init();
|
void Init();
|
||||||
void StartFrame();
|
void StartFrame();
|
||||||
@ -31,9 +36,11 @@ namespace Ship {
|
|||||||
bool IsFullscreen() { return bIsFullscreen; }
|
bool IsFullscreen() { return bIsFullscreen; }
|
||||||
uint32_t GetCurrentWidth();
|
uint32_t GetCurrentWidth();
|
||||||
uint32_t GetCurrentHeight();
|
uint32_t GetCurrentHeight();
|
||||||
|
ControlDeck* GetControlDeck() { return ControllerApi; };
|
||||||
uint32_t dwMenubar;
|
uint32_t dwMenubar;
|
||||||
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
|
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
|
||||||
std::shared_ptr<AudioPlayer> GetAudioPlayer() { return APlayer; }
|
std::shared_ptr<AudioPlayer> GetAudioPlayer() { return APlayer; }
|
||||||
|
const char* GetKeyName(int scancode) { return WmApi->get_key_name(scancode); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
@ -46,11 +53,10 @@ namespace Ship {
|
|||||||
std::weak_ptr<GlobalCtx2> Context;
|
std::weak_ptr<GlobalCtx2> Context;
|
||||||
std::shared_ptr<AudioPlayer> APlayer;
|
std::shared_ptr<AudioPlayer> APlayer;
|
||||||
|
|
||||||
GfxWindowManagerAPI* WmApi;
|
|
||||||
GfxRenderingAPI* RenderingApi;
|
GfxRenderingAPI* RenderingApi;
|
||||||
|
GfxWindowManagerAPI* WmApi;
|
||||||
bool bIsFullscreen;
|
bool bIsFullscreen;
|
||||||
uint32_t dwWidth;
|
uint32_t dwWidth;
|
||||||
uint32_t dwHeight;
|
uint32_t dwHeight;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,13 +256,16 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Audio.cpp" />
|
<ClCompile Include="Audio.cpp" />
|
||||||
<ClCompile Include="Blob.cpp" />
|
<ClCompile Include="Blob.cpp" />
|
||||||
|
<ClCompile Include="ControlDeck.cpp" />
|
||||||
<ClCompile Include="Cvar.cpp" />
|
<ClCompile Include="Cvar.cpp" />
|
||||||
<ClCompile Include="Environment.cpp" />
|
<ClCompile Include="Environment.cpp" />
|
||||||
<ClCompile Include="Factories\AudioFactory.cpp" />
|
<ClCompile Include="Factories\AudioFactory.cpp" />
|
||||||
|
<ClCompile Include="InputEditor.cpp" />
|
||||||
<ClCompile Include="GameOverlay.cpp" />
|
<ClCompile Include="GameOverlay.cpp" />
|
||||||
<ClCompile Include="GameSettings.cpp" />
|
<ClCompile Include="GameSettings.cpp" />
|
||||||
<ClCompile Include="Lib\ImGui\backends\imgui_impl_dx11.cpp" />
|
<ClCompile Include="Lib\ImGui\backends\imgui_impl_dx11.cpp" />
|
||||||
<ClCompile Include="Lib\ImGui\backends\imgui_impl_win32.cpp" />
|
<ClCompile Include="Lib\ImGui\backends\imgui_impl_win32.cpp" />
|
||||||
|
<ClCompile Include="Lib\Mercury\Mercury.cpp" />
|
||||||
<ClCompile Include="luslog.cpp" />
|
<ClCompile Include="luslog.cpp" />
|
||||||
<ClCompile Include="mixer.c" />
|
<ClCompile Include="mixer.c" />
|
||||||
<ClCompile Include="ModManager.cpp" />
|
<ClCompile Include="ModManager.cpp" />
|
||||||
@ -279,7 +282,6 @@
|
|||||||
<ClCompile Include="Factories\TextureFactory.cpp" />
|
<ClCompile Include="Factories\TextureFactory.cpp" />
|
||||||
<ClCompile Include="Factories\VtxFactory.cpp" />
|
<ClCompile Include="Factories\VtxFactory.cpp" />
|
||||||
<ClCompile Include="Array.cpp" />
|
<ClCompile Include="Array.cpp" />
|
||||||
<ClCompile Include="ConfigFile.cpp" />
|
|
||||||
<ClCompile Include="Controller.cpp" />
|
<ClCompile Include="Controller.cpp" />
|
||||||
<ClCompile Include="Hooks.cpp" />
|
<ClCompile Include="Hooks.cpp" />
|
||||||
<ClCompile Include="ImGuiImpl.cpp" />
|
<ClCompile Include="ImGuiImpl.cpp" />
|
||||||
@ -342,13 +344,18 @@
|
|||||||
<ClCompile Include="SDLController.cpp" />
|
<ClCompile Include="SDLController.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Lib\Mercury\Mercury.h" />
|
||||||
|
<ClInclude Include="Lib\nlohmann\json.hpp" />
|
||||||
<ClInclude Include="abi.h" />
|
<ClInclude Include="abi.h" />
|
||||||
<ClInclude Include="Audio.h" />
|
<ClInclude Include="Audio.h" />
|
||||||
<ClInclude Include="AudioPlayer.h" />
|
<ClInclude Include="AudioPlayer.h" />
|
||||||
<ClInclude Include="Blob.h" />
|
<ClInclude Include="Blob.h" />
|
||||||
|
<ClInclude Include="ControlDeck.h" />
|
||||||
<ClInclude Include="Cvar.h" />
|
<ClInclude Include="Cvar.h" />
|
||||||
|
<ClInclude Include="DisconnectedController.h" />
|
||||||
<ClInclude Include="Environment.h" />
|
<ClInclude Include="Environment.h" />
|
||||||
<ClInclude Include="Factories\AudioFactory.h" />
|
<ClInclude Include="Factories\AudioFactory.h" />
|
||||||
|
<ClInclude Include="InputEditor.h" />
|
||||||
<ClInclude Include="GameOverlay.h" />
|
<ClInclude Include="GameOverlay.h" />
|
||||||
<ClInclude Include="GameSettings.h" />
|
<ClInclude Include="GameSettings.h" />
|
||||||
<ClInclude Include="GameVersions.h" />
|
<ClInclude Include="GameVersions.h" />
|
||||||
@ -404,7 +411,6 @@
|
|||||||
<ClInclude Include="Vertex.h" />
|
<ClInclude Include="Vertex.h" />
|
||||||
<ClInclude Include="stox.h" />
|
<ClInclude Include="stox.h" />
|
||||||
<ClInclude Include="Lib\mINI\src\mini\ini.h" />
|
<ClInclude Include="Lib\mINI\src\mini\ini.h" />
|
||||||
<ClInclude Include="ConfigFile.h" />
|
|
||||||
<ClInclude Include="Controller.h" />
|
<ClInclude Include="Controller.h" />
|
||||||
<ClInclude Include="KeyboardController.h" />
|
<ClInclude Include="KeyboardController.h" />
|
||||||
<ClInclude Include="Factories\CollisionHeaderFactory.h" />
|
<ClInclude Include="Factories\CollisionHeaderFactory.h" />
|
||||||
|
@ -31,9 +31,6 @@
|
|||||||
<Filter Include="Source Files\Globals">
|
<Filter Include="Source Files\Globals">
|
||||||
<UniqueIdentifier>{c0f07350-c627-444e-9f66-23e19407ad9a}</UniqueIdentifier>
|
<UniqueIdentifier>{c0f07350-c627-444e-9f66-23e19407ad9a}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Source Files\Config">
|
|
||||||
<UniqueIdentifier>{9cf4833f-e90c-4a9d-8747-d47cde657beb}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Source Files\Resources\Files">
|
<Filter Include="Source Files\Resources\Files">
|
||||||
<UniqueIdentifier>{2aa34c3b-6148-480f-a4fc-19c4e0f8c822}</UniqueIdentifier>
|
<UniqueIdentifier>{2aa34c3b-6148-480f-a4fc-19c4e0f8c822}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
@ -94,6 +91,15 @@
|
|||||||
<Filter Include="Source Files\Lib\dr_libs">
|
<Filter Include="Source Files\Lib\dr_libs">
|
||||||
<UniqueIdentifier>{db6e02cc-fc4c-4138-8219-1d281ad93ec2}</UniqueIdentifier>
|
<UniqueIdentifier>{db6e02cc-fc4c-4138-8219-1d281ad93ec2}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Source Files\Lib\nlohmann">
|
||||||
|
<UniqueIdentifier>{2be7c90f-ba21-455d-8a11-6f99452be15c}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Source Files\Lib\Mercury">
|
||||||
|
<UniqueIdentifier>{7e415dd2-403b-4d4d-b4f2-3e311f91db19}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Source Files\Controller\InputEditor">
|
||||||
|
<UniqueIdentifier>{010dc29b-d1f6-4793-a4e7-4156aa4fcdd6}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Factories\MaterialFactory.cpp">
|
<ClCompile Include="Factories\MaterialFactory.cpp">
|
||||||
@ -165,9 +171,6 @@
|
|||||||
<ClCompile Include="MemoryPack.cpp">
|
<ClCompile Include="MemoryPack.cpp">
|
||||||
<Filter>Source Files\Controller\Attachment</Filter>
|
<Filter>Source Files\Controller\Attachment</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ConfigFile.cpp">
|
|
||||||
<Filter>Source Files\Config</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CollisionHeader.cpp">
|
<ClCompile Include="CollisionHeader.cpp">
|
||||||
<Filter>Source Files\Resources\Files</Filter>
|
<Filter>Source Files\Resources\Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -354,6 +357,15 @@
|
|||||||
<ClCompile Include="Factories\AudioFactory.cpp">
|
<ClCompile Include="Factories\AudioFactory.cpp">
|
||||||
<Filter>Source Files\Resources\Factories</Filter>
|
<Filter>Source Files\Resources\Factories</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="InputEditor.cpp">
|
||||||
|
<Filter>Source Files\Controller\InputEditor</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ControlDeck.cpp">
|
||||||
|
<Filter>Source Files\Controller</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Lib\Mercury\Mercury.cpp">
|
||||||
|
<Filter>Source Files\Lib\Mercury</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Lib\tinyxml2\tinyxml2.h">
|
<ClInclude Include="Lib\tinyxml2\tinyxml2.h">
|
||||||
@ -386,9 +398,6 @@
|
|||||||
<ClInclude Include="MemoryPack.h">
|
<ClInclude Include="MemoryPack.h">
|
||||||
<Filter>Source Files\Controller\Attachment</Filter>
|
<Filter>Source Files\Controller\Attachment</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="ConfigFile.h">
|
|
||||||
<Filter>Source Files\Config</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ResourceMgr.h">
|
<ClInclude Include="ResourceMgr.h">
|
||||||
<Filter>Source Files\Resources</Filter>
|
<Filter>Source Files\Resources</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -659,5 +668,20 @@
|
|||||||
<ClInclude Include="Lib\dr_libs\wav.h">
|
<ClInclude Include="Lib\dr_libs\wav.h">
|
||||||
<Filter>Source Files\Lib\dr_libs</Filter>
|
<Filter>Source Files\Lib\dr_libs</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="InputEditor.h">
|
||||||
|
<Filter>Source Files\Controller\InputEditor</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ControlDeck.h">
|
||||||
|
<Filter>Source Files\Controller</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DisconnectedController.h">
|
||||||
|
<Filter>Source Files\Controller</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Lib\nlohmann\json.hpp">
|
||||||
|
<Filter>Source Files\Lib\nlohmann</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Lib\Mercury\Mercury.h">
|
||||||
|
<Filter>Source Files\Lib\Mercury</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/HarbourMasters/soh.git
|
remote = https://github.com/HarbourMasters/soh.git
|
||||||
branch = master
|
branch = master
|
||||||
commit = ba904bbd0d724784f8f37ff4bea378f6fe26151b
|
commit = 75ccbade8ba26485266a8c8aa7d81e495d0ca4dd
|
||||||
parent = 0bb0e7b53bd80bdc7f78e08c441691737e039b2b
|
parent = 8417db65c73cb3d117f2a0f9040105022a45480c
|
||||||
method = rebase
|
method = rebase
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
@ -120,6 +120,7 @@ ifeq ($(UNAME), Darwin) #APPLE
|
|||||||
LDLIBS += \
|
LDLIBS += \
|
||||||
$(addprefix -framework , \
|
$(addprefix -framework , \
|
||||||
OpenGL \
|
OpenGL \
|
||||||
|
Foundation \
|
||||||
) \
|
) \
|
||||||
$(shell sdl2-config --libs) $(shell pkg-config --libs glew)
|
$(shell sdl2-config --libs) $(shell pkg-config --libs glew)
|
||||||
endif
|
endif
|
||||||
@ -224,9 +225,6 @@ appbundle: macosx/$(APPNAME).icns
|
|||||||
cp macosx/PkgInfo $(APPBUNDLECONTENTS)/
|
cp macosx/PkgInfo $(APPBUNDLECONTENTS)/
|
||||||
cp macosx/$(APPNAME).icns $(APPBUNDLEICON)/
|
cp macosx/$(APPNAME).icns $(APPBUNDLEICON)/
|
||||||
cp $(TARGET) $(APPBUNDLEEXE)/soh
|
cp $(TARGET) $(APPBUNDLEEXE)/soh
|
||||||
cp macosx/launcher.sh $(APPBUNDLEEXE)/launcher.sh
|
|
||||||
clang -ObjC macosx/appsupport.m -arch arm64 -arch x86_64 -framework Foundation -o macosx/appsupport
|
|
||||||
cp macosx/appsupport $(APPBUNDLEEXE)/appsupport
|
|
||||||
otool -l $(TARGET) | grep -A 2 LC_RPATH | tail -n 1 | awk '{print $2}' | dylibbundler -od -b -x $(APPBUNDLEEXE)/soh -d $(APPBUNDLECONTENTS)/libs
|
otool -l $(TARGET) | grep -A 2 LC_RPATH | tail -n 1 | awk '{print $2}' | dylibbundler -od -b -x $(APPBUNDLEEXE)/soh -d $(APPBUNDLECONTENTS)/libs
|
||||||
|
|
||||||
macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png
|
macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png
|
||||||
@ -244,7 +242,3 @@ macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png
|
|||||||
cp macosx/$(APPNAME)Icon.png macosx/$(APPNAME).iconset/icon_512x512@2x.png
|
cp macosx/$(APPNAME)Icon.png macosx/$(APPNAME).iconset/icon_512x512@2x.png
|
||||||
iconutil -c icns -o macosx/$(APPNAME).icns macosx/$(APPNAME).iconset
|
iconutil -c icns -o macosx/$(APPNAME).icns macosx/$(APPNAME).iconset
|
||||||
rm -r macosx/$(APPNAME).iconset
|
rm -r macosx/$(APPNAME).iconset
|
||||||
|
|
||||||
filledappbundle: appbundle
|
|
||||||
cp ./oot.otr $(APPBUNDLEEXE)/oot.otr
|
|
||||||
|
|
||||||
|
@ -559,6 +559,7 @@ void ActorOverlayTable_Cleanup(void);
|
|||||||
u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList*);
|
u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList*);
|
||||||
void func_80038A28(CollisionPoly* poly, f32 tx, f32 ty, f32 tz, MtxF* dest);
|
void func_80038A28(CollisionPoly* poly, f32 tx, f32 ty, f32 tz, MtxF* dest);
|
||||||
f32 CollisionPoly_GetPointDistanceFromPlane(CollisionPoly* poly, Vec3f* point);
|
f32 CollisionPoly_GetPointDistanceFromPlane(CollisionPoly* poly, Vec3f* point);
|
||||||
|
CollisionHeader* BgCheck_GetCollisionHeader(CollisionContext* colCtx, s32 bgId);
|
||||||
void CollisionPoly_GetVerticesByBgId(CollisionPoly* poly, s32 bgId, CollisionContext* colCtx, Vec3f* dest);
|
void CollisionPoly_GetVerticesByBgId(CollisionPoly* poly, s32 bgId, CollisionContext* colCtx, Vec3f* dest);
|
||||||
s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionContext* colCtx, f32* outY, Vec3f* pos,
|
s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionContext* colCtx, f32* outY, Vec3f* pos,
|
||||||
f32 checkHeight, CollisionPoly** outPoly);
|
f32 checkHeight, CollisionPoly** outPoly);
|
||||||
|
@ -1203,6 +1203,9 @@ typedef struct GlobalContext {
|
|||||||
/* 0x00790 */ Camera* cameraPtrs[NUM_CAMS];
|
/* 0x00790 */ Camera* cameraPtrs[NUM_CAMS];
|
||||||
/* 0x007A0 */ s16 activeCamera;
|
/* 0x007A0 */ s16 activeCamera;
|
||||||
/* 0x007A2 */ s16 nextCamera;
|
/* 0x007A2 */ s16 nextCamera;
|
||||||
|
/* 0x007A2 */ bool manualCamera;
|
||||||
|
/* 0x007A2 */ f32 camX;
|
||||||
|
/* 0x007A2 */ f32 camY;
|
||||||
/* 0x007A4 */ SequenceContext sequenceCtx;
|
/* 0x007A4 */ SequenceContext sequenceCtx;
|
||||||
/* 0x007A8 */ LightContext lightCtx;
|
/* 0x007A8 */ LightContext lightCtx;
|
||||||
/* 0x007B8 */ FrameAdvanceContext frameAdvCtx;
|
/* 0x007B8 */ FrameAdvanceContext frameAdvCtx;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "ultra64.h"
|
#include "ultra64.h"
|
||||||
#include "z64math.h"
|
#include "z64math.h"
|
||||||
#include <randomizerTypes.h>
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ u8 buttonItems[8];
|
/* 0x00 */ u8 buttonItems[8];
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>Ship of Harkinian</string>
|
<string>Ship of Harkinian</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>launcher.sh</string>
|
<string>soh</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>2.0.0</string>
|
<string>3.0.0</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>soh.icns</string>
|
<string>soh.icns</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@ -22,14 +22,14 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.0.0</string>
|
<string>3.0.0</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>ZOoT</string>
|
<string>ZOoT</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2.0.0</string>
|
<string>3.0.0</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>Copyright 2022 HarbourMasters.</string>
|
<string>Copyright 2022 HarbourMasters.</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>10.3</string>
|
<string>10.15</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
#import <Foundation/Foundation.h>
|
|
||||||
int main(void) {
|
|
||||||
NSString *appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject];
|
|
||||||
//If there isn't an App Support Directory yet ...
|
|
||||||
if (![[NSFileManager defaultManager] fileExistsAtPath:appSupportDir isDirectory:NULL]) {
|
|
||||||
NSError *error = nil;
|
|
||||||
//Create one
|
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:appSupportDir withIntermediateDirectories:YES attributes:nil error:&error]) {
|
|
||||||
NSLog(@"%@", error.localizedDescription);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// *** OPTIONAL *** Mark the directory as excluded from iCloud backups
|
|
||||||
NSURL *url = [NSURL fileURLWithPath:appSupportDir];
|
|
||||||
if (![url setResourceValue:@YES
|
|
||||||
forKey:NSURLIsExcludedFromBackupKey
|
|
||||||
error:&error])
|
|
||||||
{
|
|
||||||
NSLog(@"Error excluding %@ from backup %@", url.lastPathComponent, error.localizedDescription);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSLog(@"Yay");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("%s\n", [appSupportDir UTF8String]);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
APPPATH="${0%/*}"
|
|
||||||
cd "${APPPATH}"
|
|
||||||
APPPATH=$(pwd)
|
|
||||||
APPSUPPORT=$(./appsupport)
|
|
||||||
mkdir -p "${APPSUPPORT}/com.shipofharkinian.soh"
|
|
||||||
cd "${APPSUPPORT}/com.shipofharkinian.soh"
|
|
||||||
cp "${APPPATH}/oot.otr" .
|
|
||||||
${APPPATH}/soh
|
|
@ -1,19 +0,0 @@
|
|||||||
#include <Lib/spdlog/include/spdlog/spdlog.h>
|
|
||||||
|
|
||||||
void GenerateRandomizer() {
|
|
||||||
int ret = Playthrough::Playthrough_Init(std::hash<std::string>{}(Settings::seed));
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
if (ret == -1) { // Failed to generate after 5 tries
|
|
||||||
SPDLOG_ERROR(
|
|
||||||
"\n\nFailed to generate after 5 tries.\nPress B to go back to the menu.\nA different seed might be "
|
|
||||||
"successful.");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
SPDLOG_ERROR("\n\nError %d with fill.\nPress Select to exit or B to go back to the menu.\n", ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& randomizerHash = GetRandomizerHash();
|
|
||||||
}
|
|
@ -143,7 +143,7 @@
|
|||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||||
<SDLCheck>false</SDLCheck>
|
<SDLCheck>false</SDLCheck>
|
||||||
<PreprocessorDefinitions>INCLUDE_GAME_PRINTF;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;ENABLE_DX11;%(PreprocessorDefinitions)GLEW_STATIC </PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;ENABLE_DX11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
@ -941,6 +941,7 @@
|
|||||||
<ClCompile Include="src\overlays\misc\ovl_kaleido_scope\z_lmap_mark.c" />
|
<ClCompile Include="src\overlays\misc\ovl_kaleido_scope\z_lmap_mark.c" />
|
||||||
<ClCompile Include="src\overlays\misc\ovl_kaleido_scope\z_lmap_mark_data.c" />
|
<ClCompile Include="src\overlays\misc\ovl_kaleido_scope\z_lmap_mark_data.c" />
|
||||||
<ClCompile Include="src\overlays\misc\ovl_map_mark_data\z_map_mark_data.c" />
|
<ClCompile Include="src\overlays\misc\ovl_map_mark_data\z_map_mark_data.c" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="soh\Enhancements\cosmetics\CosmeticsEditor.h" />
|
<ClInclude Include="soh\Enhancements\cosmetics\CosmeticsEditor.h" />
|
||||||
@ -982,7 +983,7 @@
|
|||||||
<ClInclude Include="soh\Enhancements\randomizer\3drando\tinyxml2.h" />
|
<ClInclude Include="soh\Enhancements\randomizer\3drando\tinyxml2.h" />
|
||||||
<ClInclude Include="soh\Enhancements\randomizer\3drando\trial.hpp" />
|
<ClInclude Include="soh\Enhancements\randomizer\3drando\trial.hpp" />
|
||||||
<ClInclude Include="soh\Enhancements\randomizer\3drando\utils.hpp" />
|
<ClInclude Include="soh\Enhancements\randomizer\3drando\utils.hpp" />
|
||||||
<ClInclude Include="randomizerTypes.h" />
|
<ClInclude Include="soh\Enhancements\randomizer\randomizerTypes.h" />
|
||||||
<ClInclude Include="soh\Enhancements\randomizer\randomizer_item_tracker.h" />
|
<ClInclude Include="soh\Enhancements\randomizer\randomizer_item_tracker.h" />
|
||||||
<ClInclude Include="soh\frame_interpolation.h" />
|
<ClInclude Include="soh\frame_interpolation.h" />
|
||||||
<ClInclude Include="include\alloca.h" />
|
<ClInclude Include="include\alloca.h" />
|
||||||
@ -1038,7 +1039,6 @@
|
|||||||
<ClInclude Include="soh\Enhancements\debugger\debugSaveEditor.h" />
|
<ClInclude Include="soh\Enhancements\debugger\debugSaveEditor.h" />
|
||||||
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h" />
|
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h" />
|
||||||
<ClInclude Include="soh\gameconsole.h" />
|
<ClInclude Include="soh\gameconsole.h" />
|
||||||
<ClInclude Include="soh\Lib\nlohmann\json.hpp" />
|
|
||||||
<ClInclude Include="soh\OTRAudio.h" />
|
<ClInclude Include="soh\OTRAudio.h" />
|
||||||
<ClInclude Include="soh\OTRGlobals.h" />
|
<ClInclude Include="soh\OTRGlobals.h" />
|
||||||
<ClInclude Include="soh\SaveManager.h" />
|
<ClInclude Include="soh\SaveManager.h" />
|
||||||
|
@ -82,12 +82,6 @@
|
|||||||
<Filter Include="Source Files\soh\Enhancements\debugger">
|
<Filter Include="Source Files\soh\Enhancements\debugger">
|
||||||
<UniqueIdentifier>{04fc1c52-49ff-48e2-ae23-2c00867374f8}</UniqueIdentifier>
|
<UniqueIdentifier>{04fc1c52-49ff-48e2-ae23-2c00867374f8}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Source Files\soh\Lib">
|
|
||||||
<UniqueIdentifier>{dbcf07c4-80b1-4c88-ac54-2bbdd8f53ee4}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Source Files\soh\Lib\nlohmann">
|
|
||||||
<UniqueIdentifier>{9c880c8e-492b-48f6-b230-1fd269ea74b1}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\boot\assert.c">
|
<ClCompile Include="src\boot\assert.c">
|
||||||
@ -3947,9 +3941,6 @@
|
|||||||
<ClInclude Include="soh\OTRAudio.h">
|
<ClInclude Include="soh\OTRAudio.h">
|
||||||
<Filter>Source Files\soh</Filter>
|
<Filter>Source Files\soh</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="soh\Lib\nlohmann\json.hpp">
|
|
||||||
<Filter>Source Files\soh\Lib\nlohmann</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="soh\SaveManager.h">
|
<ClInclude Include="soh\SaveManager.h">
|
||||||
<Filter>Source Files\soh</Filter>
|
<Filter>Source Files\soh</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -4061,7 +4052,7 @@
|
|||||||
<ClInclude Include="soh\Enhancements\randomizer\3drando\utils.hpp">
|
<ClInclude Include="soh\Enhancements\randomizer\3drando\utils.hpp">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="randomizerTypes.h">
|
<ClInclude Include="soh\Enhancements\randomizer\randomizerTypes.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="soh\Enhancements\gfx.h">
|
<ClInclude Include="soh\Enhancements\gfx.h">
|
||||||
|
@ -30,7 +30,6 @@ void BootCommands_Init()
|
|||||||
CVar_RegisterS32("gHoverFishing", 0);
|
CVar_RegisterS32("gHoverFishing", 0);
|
||||||
CVar_RegisterS32("gN64WeirdFrames", 0);
|
CVar_RegisterS32("gN64WeirdFrames", 0);
|
||||||
CVar_RegisterS32("gBombchusOOB", 0);
|
CVar_RegisterS32("gBombchusOOB", 0);
|
||||||
CVar_RegisterS32("gRumbleEnabled", 0);
|
|
||||||
CVar_RegisterS32("gUniformLR", 0);
|
CVar_RegisterS32("gUniformLR", 0);
|
||||||
CVar_RegisterS32("gTwoHandedIdle", 0);
|
CVar_RegisterS32("gTwoHandedIdle", 0);
|
||||||
CVar_RegisterS32("gDekuNutUpgradeFix", 0);
|
CVar_RegisterS32("gDekuNutUpgradeFix", 0);
|
||||||
|
@ -178,28 +178,28 @@ void Draw_Npcs(){
|
|||||||
ImGui::TableSetupColumn("Outer colors##Navi", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort, TablesCellsWidth/2);
|
ImGui::TableSetupColumn("Outer colors##Navi", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort, TablesCellsWidth/2);
|
||||||
Table_InitHeader();
|
Table_InitHeader();
|
||||||
Draw_HelpIcon("Inner color for Navi (idle flying around)");
|
Draw_HelpIcon("Inner color for Navi (idle flying around)");
|
||||||
SohImGui::EnhancementColor("Navi Idle", "gNavi_Idle_Inner_", navi_idle_i_col, ImVec4(255, 255, 255, 255), false);
|
SohImGui::EnhancementColor("Navi Idle (Primary)", "gNavi_Idle_Inner_", navi_idle_i_col, ImVec4(255, 255, 255, 255), false);
|
||||||
Table_NextCol();
|
Table_NextCol();
|
||||||
Draw_HelpIcon("Outer color for Navi (idle flying around)");
|
Draw_HelpIcon("Outer color for Navi (idle flying around)");
|
||||||
SohImGui::EnhancementColor("Navi Idle", "gNavi_Idle_Outer_", navi_idle_o_col, ImVec4(0, 0, 255, 255), false);
|
SohImGui::EnhancementColor("Navi Idle (Secondary)", "gNavi_Idle_Outer_", navi_idle_o_col, ImVec4(0, 0, 255, 255), false);
|
||||||
Table_NextLine();
|
Table_NextLine();
|
||||||
Draw_HelpIcon("Inner color for Navi (when Navi fly around NPCs)");
|
Draw_HelpIcon("Inner color for Navi (when Navi fly around NPCs)");
|
||||||
SohImGui::EnhancementColor("Navi NPC", "gNavi_NPC_Inner_", navi_npc_i_col, ImVec4(150, 150, 255, 255), false);
|
SohImGui::EnhancementColor("Navi NPC (Primary)", "gNavi_NPC_Inner_", navi_npc_i_col, ImVec4(150, 150, 255, 255), false);
|
||||||
Table_NextCol();
|
Table_NextCol();
|
||||||
Draw_HelpIcon("Outer color for Navi (when Navi fly around NPCs)");
|
Draw_HelpIcon("Outer color for Navi (when Navi fly around NPCs)");
|
||||||
SohImGui::EnhancementColor("Navi NPC", "gNavi_NPC_Outer_", navi_npc_o_col, ImVec4(150, 150, 255, 255), false);
|
SohImGui::EnhancementColor("Navi NPC (Secondary)", "gNavi_NPC_Outer_", navi_npc_o_col, ImVec4(150, 150, 255, 255), false);
|
||||||
Table_NextLine();
|
Table_NextLine();
|
||||||
Draw_HelpIcon("Inner color for Navi (when Navi fly around Enemies or Bosses)");
|
Draw_HelpIcon("Inner color for Navi (when Navi fly around Enemies or Bosses)");
|
||||||
SohImGui::EnhancementColor("Navi Enemy", "gNavi_Enemy_Inner_", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false);
|
SohImGui::EnhancementColor("Navi Enemy (Primary)", "gNavi_Enemy_Inner_", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false);
|
||||||
Table_NextCol();
|
Table_NextCol();
|
||||||
Draw_HelpIcon("Outer color for Navi (when Navi fly around Enemies or Bosses)");
|
Draw_HelpIcon("Outer color for Navi (when Navi fly around Enemies or Bosses)");
|
||||||
SohImGui::EnhancementColor("Navi Enemy", "gNavi_Enemy_Outer_", navi_enemy_o_col, ImVec4(220, 155, 0, 255), false);
|
SohImGui::EnhancementColor("Navi Enemy (Secondary)", "gNavi_Enemy_Outer_", navi_enemy_o_col, ImVec4(220, 155, 0, 255), false);
|
||||||
Table_NextLine();
|
Table_NextLine();
|
||||||
Draw_HelpIcon("Inner color for Navi (when Navi fly around props (signs etc))");
|
Draw_HelpIcon("Inner color for Navi (when Navi fly around props (signs etc))");
|
||||||
SohImGui::EnhancementColor("Navi Prop", "gNavi_Prop_Inner_", navi_prop_i_col, ImVec4(0, 255, 0, 255), false);
|
SohImGui::EnhancementColor("Navi Prop (Primary)", "gNavi_Prop_Inner_", navi_prop_i_col, ImVec4(0, 255, 0, 255), false);
|
||||||
Table_NextCol();
|
Table_NextCol();
|
||||||
Draw_HelpIcon("Outer color for Navi (when Navi fly around props (signs etc))");
|
Draw_HelpIcon("Outer color for Navi (when Navi fly around props (signs etc))");
|
||||||
SohImGui::EnhancementColor("Navi Prop", "gNavi_Prop_Outer_", navi_prop_o_col, ImVec4(0, 255, 0, 255), false);
|
SohImGui::EnhancementColor("Navi Prop (Secondary)", "gNavi_Prop_Outer_", navi_prop_o_col, ImVec4(0, 255, 0, 255), false);
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
SohImGui::EnhancementCheckbox("Custom colors for Keese", "gUseKeeseCol");
|
SohImGui::EnhancementCheckbox("Custom colors for Keese", "gUseKeeseCol");
|
||||||
@ -212,10 +212,10 @@ void Draw_Npcs(){
|
|||||||
SohImGui::EnhancementColor("Fire Primary color", "gKeese1_Ef_Prim", Keese1_primcol, ImVec4(255, 255, 100, 255));
|
SohImGui::EnhancementColor("Fire Primary color", "gKeese1_Ef_Prim", Keese1_primcol, ImVec4(255, 255, 100, 255));
|
||||||
Table_NextCol();
|
Table_NextCol();
|
||||||
Draw_HelpIcon("Affects the primary color of the Ice itself of the Keese");
|
Draw_HelpIcon("Affects the primary color of the Ice itself of the Keese");
|
||||||
SohImGui::EnhancementColor("Fire Primary color", "gKeese2_Ef_Prim", Keese2_primcol, ImVec4(100, 200, 255, 255));
|
SohImGui::EnhancementColor("Ice Primary color", "gKeese2_Ef_Prim", Keese2_primcol, ImVec4(100, 200, 255, 255));
|
||||||
Table_NextLine();
|
Table_NextLine();
|
||||||
Draw_HelpIcon("Affects the secondary color of the Fire itself of the Keese");
|
Draw_HelpIcon("Affects the secondary color of the Fire itself of the Keese");
|
||||||
SohImGui::EnhancementColor("Ice Secondary color", "gKeese1_Ef_Env", Keese1_envcol, ImVec4(255, 50, 0, 255));
|
SohImGui::EnhancementColor("Fire Secondary color", "gKeese1_Ef_Env", Keese1_envcol, ImVec4(255, 50, 0, 255));
|
||||||
Table_NextCol();
|
Table_NextCol();
|
||||||
Draw_HelpIcon("Affects the secondary color of the Ice itself of the Keese");
|
Draw_HelpIcon("Affects the secondary color of the Ice itself of the Keese");
|
||||||
SohImGui::EnhancementColor("Ice Secondary color", "gKeese2_Ef_Env", Keese2_envcol, ImVec4(0, 0, 255, 255));
|
SohImGui::EnhancementColor("Ice Secondary color", "gKeese2_Ef_Env", Keese2_envcol, ImVec4(0, 0, 255, 255));
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <Utils/StringHelper.h>
|
#include <Utils/StringHelper.h>
|
||||||
#include <Utils/File.h>
|
#include <Utils/File.h>
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
#include "Lib/ImGui/imgui_internal.h"
|
#include "Lib/ImGui/imgui_internal.h"
|
||||||
#undef PATH_HACK
|
#undef PATH_HACK
|
||||||
#undef Path
|
#undef Path
|
||||||
@ -498,10 +499,10 @@ template <typename Numeric> bool is_number(const std::string& s) {
|
|||||||
return ((std::istringstream(s) >> n >> std::ws).eof());
|
return ((std::istringstream(s) >> n >> std::ws).eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugConsole_LoadCVars()
|
void DebugConsole_LoadLegacyCVars() {
|
||||||
{
|
auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg");
|
||||||
if (File::Exists("cvars.cfg")) {
|
if (File::Exists(cvarsConfig)) {
|
||||||
const auto lines = File::ReadAllLines("cvars.cfg");
|
const auto lines = File::ReadAllLines(cvarsConfig);
|
||||||
|
|
||||||
for (const std::string& line : lines) {
|
for (const std::string& line : lines) {
|
||||||
std::vector<std::string> cfg = StringHelper::Split(line, " = ");
|
std::vector<std::string> cfg = StringHelper::Split(line, " = ");
|
||||||
@ -519,21 +520,58 @@ void DebugConsole_LoadCVars()
|
|||||||
CVar_SetS32(cfg[0].c_str(), std::stoi(cfg[1]));
|
CVar_SetS32(cfg[0].c_str(), std::stoi(cfg[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs::remove(cvarsConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugConsole_LoadCVars() {
|
||||||
|
|
||||||
|
std::shared_ptr<Mercury> pConf = Ship::GlobalCtx2::GetInstance()->GetConfig();
|
||||||
|
pConf->reload();
|
||||||
|
|
||||||
|
for (const auto& item : pConf->rjson["CVars"].items()) {
|
||||||
|
auto value = item.value();
|
||||||
|
switch (value.type()) {
|
||||||
|
case nlohmann::detail::value_t::array:
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::string:
|
||||||
|
CVar_SetString(item.key().c_str(), value.get<std::string>().c_str());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::boolean:
|
||||||
|
CVar_SetS32(item.key().c_str(), value.get<bool>());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::number_unsigned:
|
||||||
|
case nlohmann::detail::value_t::number_integer:
|
||||||
|
CVar_SetS32(item.key().c_str(), value.get<int>());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::number_float:
|
||||||
|
CVar_SetFloat(item.key().c_str(), value.get<float>());
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
if (item.key() == "gOpenMenuBar") {
|
||||||
|
int bp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugConsole_LoadLegacyCVars();
|
||||||
|
}
|
||||||
|
|
||||||
void DebugConsole_SaveCVars()
|
void DebugConsole_SaveCVars()
|
||||||
{
|
{
|
||||||
std::string output;
|
std::shared_ptr<Mercury> pConf = Ship::GlobalCtx2::GetInstance()->GetConfig();
|
||||||
|
|
||||||
for (const auto &cvar : cvars) {
|
for (const auto &cvar : cvars) {
|
||||||
if (cvar.second->type == CVAR_TYPE_STRING)
|
const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str());
|
||||||
output += StringHelper::Sprintf("%s = \"%s\"\n", cvar.first.c_str(), cvar.second->value.valueStr);
|
|
||||||
|
if (cvar.second->type == CVAR_TYPE_STRING && cvar.second->value.valueStr != nullptr)
|
||||||
|
pConf->setString(key, std::string(cvar.second->value.valueStr));
|
||||||
else if (cvar.second->type == CVAR_TYPE_S32)
|
else if (cvar.second->type == CVAR_TYPE_S32)
|
||||||
output += StringHelper::Sprintf("%s = %i\n", cvar.first.c_str(), cvar.second->value.valueS32);
|
pConf->setInt(key, cvar.second->value.valueS32);
|
||||||
else if (cvar.second->type == CVAR_TYPE_FLOAT)
|
else if (cvar.second->type == CVAR_TYPE_FLOAT)
|
||||||
output += StringHelper::Sprintf("%s = %f\n", cvar.first.c_str(), cvar.second->value.valueFloat);
|
pConf->setFloat(key, cvar.second->value.valueFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
File::WriteAllText("cvars.cfg", output);
|
pConf->save();
|
||||||
}
|
}
|
||||||
|
@ -529,7 +529,7 @@ void DrawColCheckList(std::vector<Gfx>& dl, Collider** objects, int32_t count) {
|
|||||||
|
|
||||||
Mtx m;
|
Mtx m;
|
||||||
MtxF mt;
|
MtxF mt;
|
||||||
SkinMatrix_SetTranslate(&mt, cyl->dim.pos.x, cyl->dim.pos.y, cyl->dim.pos.z);
|
SkinMatrix_SetTranslate(&mt, cyl->dim.pos.x, cyl->dim.pos.y + cyl->dim.yShift, cyl->dim.pos.z);
|
||||||
MtxF ms;
|
MtxF ms;
|
||||||
int32_t radius = cyl->dim.radius == 0 ? 1 : cyl->dim.radius;
|
int32_t radius = cyl->dim.radius == 0 ? 1 : cyl->dim.radius;
|
||||||
SkinMatrix_SetScale(&ms, radius / 128.0f, cyl->dim.height / 128.0f, radius / 128.0f);
|
SkinMatrix_SetScale(&ms, radius / 128.0f, cyl->dim.height / 128.0f, radius / 128.0f);
|
||||||
|
@ -1561,6 +1561,18 @@ void DrawPlayerTab() {
|
|||||||
ImGui::InputScalar("C Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[2], &one, NULL);
|
ImGui::InputScalar("C Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[2], &one, NULL);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL);
|
ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL);
|
||||||
|
|
||||||
|
if (CVar_GetS32("gDpadEquips", 0)) {
|
||||||
|
ImGui::NewLine();
|
||||||
|
ImGui::Text("Current D-pad Equips");
|
||||||
|
ImGui::InputScalar("D-pad Up ", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[4], &one, NULL); // Two spaces at the end for aligning, not elegant but it's working
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::InputScalar("D-pad Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[5], &one, NULL);
|
||||||
|
// Intentionnal to not put everything on the same line, else it's taking too much for lower resolution.
|
||||||
|
ImGui::InputScalar("D-pad Left", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[6], &one, NULL);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::InputScalar("D-pad Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[7], &one, NULL);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "location_access.hpp"
|
#include "location_access.hpp"
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include <Lib/spdlog/include/spdlog/spdlog.h>
|
#include <Lib/spdlog/include/spdlog/spdlog.h>
|
||||||
#include "randomizerTypes.h"
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool seedChanged;
|
bool seedChanged;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "randomizerTypes.h"
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
|
|
||||||
#define MAIN_MENU 0
|
#define MAIN_MENU 0
|
||||||
#define OPTION_SUB_MENU 1
|
#define OPTION_SUB_MENU 1
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "logic.hpp"
|
#include "logic.hpp"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
#include "spoiler_log.hpp"
|
#include "spoiler_log.hpp"
|
||||||
#include "randomizerTypes.h"
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
|
|
||||||
namespace Playthrough {
|
namespace Playthrough {
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
// #include <soh/Enhancements/randomizer.h>
|
// #include <soh/Enhancements/randomizer.h>
|
||||||
#include <Cvar.h>
|
#include <Cvar.h>
|
||||||
#include <GameSettings.h>
|
#include <GameSettings.h>
|
||||||
|
#define NOGDI
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <GlobalCtx2.h>
|
||||||
|
|
||||||
#define TICKS_PER_SEC 268123480.0
|
#define TICKS_PER_SEC 268123480.0
|
||||||
|
|
||||||
@ -18,7 +21,7 @@ void RandoMain::GenerateRando(std::unordered_map<RandomizerSettingKey, u8> cvarS
|
|||||||
// std::string settingsFileName = "./randomizer/latest_settings.json";
|
// std::string settingsFileName = "./randomizer/latest_settings.json";
|
||||||
// CVar_SetString("gLoadedPreset", settingsFileName.c_str());
|
// CVar_SetString("gLoadedPreset", settingsFileName.c_str());
|
||||||
|
|
||||||
std::string fileName = GenerateRandomizer(cvarSettings);
|
std::string fileName = Ship::GlobalCtx2::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings).c_str());
|
||||||
CVar_SetString("gSpoilerLog", fileName.c_str());
|
CVar_SetString("gSpoilerLog", fileName.c_str());
|
||||||
|
|
||||||
Game::SaveSettings();
|
Game::SaveSettings();
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "shops.hpp"
|
#include "shops.hpp"
|
||||||
#include "hints.hpp"
|
#include "hints.hpp"
|
||||||
#include "soh/Lib/nlohmann/json.hpp"
|
#include "Lib/nlohmann/json.hpp"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -26,6 +26,10 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <variables.h>
|
#include <variables.h>
|
||||||
|
|
||||||
|
#define NOGDI
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include "GlobalCtx2.h"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
json jsonData;
|
json jsonData;
|
||||||
@ -721,12 +725,13 @@ const char* SpoilerLog_Write(int language) {
|
|||||||
//WriteShuffledEntrances(spoilerLog);
|
//WriteShuffledEntrances(spoilerLog);
|
||||||
WriteAllLocations(language);
|
WriteAllLocations(language);
|
||||||
|
|
||||||
if (!std::filesystem::exists("./Randomizer")) {
|
if (!std::filesystem::exists(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Randomizer"))) {
|
||||||
std::filesystem::create_directory("./Randomizer");
|
std::filesystem::create_directory(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Randomizer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string jsonString = jsonData.dump(4);
|
std::string jsonString = jsonData.dump(4);
|
||||||
std::ofstream jsonFile("./Randomizer/" + Settings::seed + ".json");
|
std::ofstream jsonFile(Ship::GlobalCtx2::GetPathRelativeToAppDirectory(
|
||||||
|
(std::string("Randomizer/") + std::string(Settings::seed) + std::string(".json")).c_str()));
|
||||||
jsonFile << std::setw(4) << jsonString << std::endl;
|
jsonFile << std::setw(4) << jsonString << std::endl;
|
||||||
jsonFile.close();
|
jsonFile.close();
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#ifndef RANDOMIZER_H
|
#pragma once
|
||||||
#define RANDOMIZER_H
|
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../../../include/ultra64.h"
|
#include "../../../include/ultra64.h"
|
||||||
#include "../../../include/z64item.h"
|
#include "../../../include/z64item.h"
|
||||||
#include <randomizerTypes.h>
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
|
|
||||||
class Randomizer {
|
class Randomizer {
|
||||||
private:
|
private:
|
||||||
@ -54,5 +53,3 @@ void Rando_Init(void);
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -57,7 +57,6 @@ OTRGlobals* OTRGlobals::Instance;
|
|||||||
SaveManager* SaveManager::Instance;
|
SaveManager* SaveManager::Instance;
|
||||||
|
|
||||||
OTRGlobals::OTRGlobals() {
|
OTRGlobals::OTRGlobals() {
|
||||||
|
|
||||||
context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian");
|
context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian");
|
||||||
gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
||||||
gRandomizer = std::make_shared<Randomizer>();
|
gRandomizer = std::make_shared<Randomizer>();
|
||||||
@ -1154,34 +1153,27 @@ extern "C" s32* ResourceMgr_LoadCSByName(const char* path)
|
|||||||
return (s32*)res->commands.data();
|
return (s32*)res->commands.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path GetSaveFile(Ship::ConfigFile& Conf) {
|
std::filesystem::path GetSaveFile(std::shared_ptr<Mercury> Conf) {
|
||||||
std::string fileName = Conf.get("SAVE").get("Save Filename");
|
const std::string fileName = Conf->getString("Game.SaveName", Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav"));
|
||||||
|
|
||||||
if (fileName.empty()) {
|
|
||||||
Conf["SAVE"]["Save Filename"] = "oot_save.sav";
|
|
||||||
Conf.Save();
|
|
||||||
}
|
|
||||||
std::filesystem::path saveFile = std::filesystem::absolute(fileName);
|
std::filesystem::path saveFile = std::filesystem::absolute(fileName);
|
||||||
|
|
||||||
if (!std::filesystem::exists(saveFile.parent_path())) {
|
if (!exists(saveFile.parent_path())) {
|
||||||
std::filesystem::create_directories(saveFile.parent_path());
|
create_directories(saveFile.parent_path());
|
||||||
}
|
}
|
||||||
|
|
||||||
return saveFile;
|
return saveFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path GetSaveFile() {
|
std::filesystem::path GetSaveFile() {
|
||||||
std::shared_ptr<Ship::ConfigFile> pConf = OTRGlobals::Instance->context->GetConfig();
|
const std::shared_ptr<Mercury> pConf = OTRGlobals::Instance->context->GetConfig();
|
||||||
Ship::ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
return GetSaveFile(Conf);
|
return GetSaveFile(pConf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OTRGlobals::CheckSaveFile(size_t sramSize) {
|
void OTRGlobals::CheckSaveFile(size_t sramSize) const {
|
||||||
std::shared_ptr<Ship::ConfigFile> pConf = context->GetConfig();
|
const std::shared_ptr<Mercury> pConf = Instance->context->GetConfig();
|
||||||
Ship::ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
std::filesystem::path savePath = GetSaveFile(Conf);
|
std::filesystem::path savePath = GetSaveFile(pConf);
|
||||||
std::fstream saveFile(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
|
std::fstream saveFile(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
|
||||||
if (saveFile.fail()) {
|
if (saveFile.fail()) {
|
||||||
saveFile.open(savePath, std::fstream::in | std::fstream::out | std::fstream::binary | std::fstream::app);
|
saveFile.open(savePath, std::fstream::in | std::fstream::out | std::fstream::binary | std::fstream::app);
|
||||||
@ -1200,25 +1192,6 @@ extern "C" void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size) {
|
|||||||
OTRGlobals::Instance->context->WriteSaveFile(GetSaveFile(), addr, dramAddr, size);
|
OTRGlobals::Instance->context->WriteSaveFile(GetSaveFile(), addr, dramAddr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember to free after use of value */
|
|
||||||
extern "C" char* Config_getValue(char* category, char* key) {
|
|
||||||
std::shared_ptr<Ship::ConfigFile> pConf = OTRGlobals::Instance->context->GetConfig();
|
|
||||||
Ship::ConfigFile& Conf = *pConf.get();
|
|
||||||
|
|
||||||
std::string data = Conf.get(std::string(category)).get(std::string(key));
|
|
||||||
char* retval = (char*)malloc(data.length()+1);
|
|
||||||
strcpy(retval, data.c_str());
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" bool Config_setValue(char* category, char* key, char* value) {
|
|
||||||
std::shared_ptr<Ship::ConfigFile> pConf = OTRGlobals::Instance->context->GetConfig();
|
|
||||||
Ship::ConfigFile& Conf = *pConf.get();
|
|
||||||
Conf[std::string(category)][std::string(key)] = std::string(value);
|
|
||||||
return Conf.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring StringToU16(const std::string& s) {
|
std::wstring StringToU16(const std::string& s) {
|
||||||
std::vector<unsigned long> result;
|
std::vector<unsigned long> result;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -1320,11 +1293,10 @@ extern "C" uint32_t OTRGetCurrentHeight() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void OTRControllerCallback(ControllerCallback* controller) {
|
extern "C" void OTRControllerCallback(ControllerCallback* controller) {
|
||||||
auto controllers = OTRGlobals::Instance->context->GetWindow()->Controllers;
|
const auto controllers = Ship::Window::ControllerApi->virtualDevices;
|
||||||
for (size_t i = 0; i < controllers.size(); i++) {
|
|
||||||
for (int j = 0; j < controllers[i].size(); j++) {
|
for (int i = 0; i < controllers.size(); ++i) {
|
||||||
OTRGlobals::Instance->context->GetWindow()->Controllers[i][j]->WriteToSource(controller);
|
Ship::Window::ControllerApi->physicalDevices[controllers[i]]->WriteToSource(i, controller);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1378,11 +1350,11 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int Controller_ShouldRumble(size_t i) {
|
extern "C" int Controller_ShouldRumble(size_t i) {
|
||||||
for (const auto& controller : Ship::Window::Controllers.at(i))
|
|
||||||
{
|
|
||||||
float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", i).c_str(), 1.0f);
|
|
||||||
|
|
||||||
if (controller->CanRumble() && rumble_strength > 0.001f) {
|
const auto controllers = Ship::Window::ControllerApi->virtualDevices;
|
||||||
|
|
||||||
|
for (const auto virtual_entry : controllers) {
|
||||||
|
if (Ship::Window::ControllerApi->physicalDevices[virtual_entry]->CanRumble()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1395,23 +1367,23 @@ extern "C" void* getN64WeirdFrame(s32 i) {
|
|||||||
return &weirdFrameBytes[i + sizeof(n64WeirdFrames)];
|
return &weirdFrameBytes[i + sizeof(n64WeirdFrames)];
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" s16 GetItemModelFromId(s16 itemId) {
|
extern "C" s16 Randomizer_GetItemModelFromId(s16 itemId) {
|
||||||
return OTRGlobals::Instance->gRandomizer->GetItemModelFromId(itemId);
|
return OTRGlobals::Instance->gRandomizer->GetItemModelFromId(itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" s32 GetItemIDFromGetItemID(s32 getItemId) {
|
extern "C" s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId) {
|
||||||
return OTRGlobals::Instance->gRandomizer->GetItemIDFromGetItemID(getItemId);
|
return OTRGlobals::Instance->gRandomizer->GetItemIDFromGetItemID(getItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LoadRandomizerSettings(const char* spoilerFileName) {
|
extern "C" void Randomizer_LoadSettings(const char* spoilerFileName) {
|
||||||
OTRGlobals::Instance->gRandomizer->LoadRandomizerSettings(spoilerFileName);
|
OTRGlobals::Instance->gRandomizer->LoadRandomizerSettings(spoilerFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LoadHintLocations(const char* spoilerFileName) {
|
extern "C" void Randomizer_LoadHintLocations(const char* spoilerFileName) {
|
||||||
OTRGlobals::Instance->gRandomizer->LoadHintLocations(spoilerFileName);
|
OTRGlobals::Instance->gRandomizer->LoadHintLocations(spoilerFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LoadItemLocations(const char* spoilerFileName, bool silent) {
|
extern "C" void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent) {
|
||||||
OTRGlobals::Instance->gRandomizer->LoadItemLocations(spoilerFileName, silent);
|
OTRGlobals::Instance->gRandomizer->LoadItemLocations(spoilerFileName, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1419,11 +1391,11 @@ extern "C" bool SpoilerFileExists(const char* spoilerFileName) {
|
|||||||
return OTRGlobals::Instance->gRandomizer->SpoilerFileExists(spoilerFileName);
|
return OTRGlobals::Instance->gRandomizer->SpoilerFileExists(spoilerFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey) {
|
extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey) {
|
||||||
return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(randoSettingKey);
|
return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(randoSettingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" RandomizerCheck GetCheckFromActor(s16 sceneNum, s16 actorId, s16 actorParams) {
|
extern "C" RandomizerCheck Randomizer_GetCheckFromActor(s16 sceneNum, s16 actorId, s16 actorParams) {
|
||||||
return OTRGlobals::Instance->gRandomizer->GetCheckFromActor(sceneNum, actorId, actorParams);
|
return OTRGlobals::Instance->gRandomizer->GetCheckFromActor(sceneNum, actorId, actorParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1499,33 +1471,33 @@ extern "C" int CopyScrubMessage(u16 scrubTextId, char* buffer, const int maxBuff
|
|||||||
return CopyStringToCharBuffer(scrubText, buffer, maxBufferSize);
|
return CopyStringToCharBuffer(scrubText, buffer, maxBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int CopyAltarMessage(char* buffer, const int maxBufferSize) {
|
extern "C" int Randomizer_CopyAltarMessage(char* buffer, const int maxBufferSize) {
|
||||||
const std::string& altarText = (LINK_IS_ADULT) ? OTRGlobals::Instance->gRandomizer->GetAdultAltarText()
|
const std::string& altarText = (LINK_IS_ADULT) ? OTRGlobals::Instance->gRandomizer->GetAdultAltarText()
|
||||||
: OTRGlobals::Instance->gRandomizer->GetChildAltarText();
|
: OTRGlobals::Instance->gRandomizer->GetChildAltarText();
|
||||||
return CopyStringToCharBuffer(altarText, buffer, maxBufferSize);
|
return CopyStringToCharBuffer(altarText, buffer, maxBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int CopyGanonText(char* buffer, const int maxBufferSize) {
|
extern "C" int Randomizer_CopyGanonText(char* buffer, const int maxBufferSize) {
|
||||||
const std::string& ganonText = OTRGlobals::Instance->gRandomizer->GetGanonText();
|
const std::string& ganonText = OTRGlobals::Instance->gRandomizer->GetGanonText();
|
||||||
return CopyStringToCharBuffer(ganonText, buffer, maxBufferSize);
|
return CopyStringToCharBuffer(ganonText, buffer, maxBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int CopyGanonHintText(char* buffer, const int maxBufferSize) {
|
extern "C" int Randomizer_CopyGanonHintText(char* buffer, const int maxBufferSize) {
|
||||||
const std::string& ganonText = OTRGlobals::Instance->gRandomizer->GetGanonHintText();
|
const std::string& ganonText = OTRGlobals::Instance->gRandomizer->GetGanonHintText();
|
||||||
return CopyStringToCharBuffer(ganonText, buffer, maxBufferSize);
|
return CopyStringToCharBuffer(ganonText, buffer, maxBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize) {
|
extern "C" int Randomizer_CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize) {
|
||||||
// we don't want to make a copy of the std::string returned from GetHintFromCheck
|
// we don't want to make a copy of the std::string returned from GetHintFromCheck
|
||||||
// so we're just going to let RVO take care of it
|
// so we're just going to let RVO take care of it
|
||||||
const std::string& hintText = OTRGlobals::Instance->gRandomizer->GetHintFromCheck(check);
|
const std::string& hintText = OTRGlobals::Instance->gRandomizer->GetHintFromCheck(check);
|
||||||
return CopyStringToCharBuffer(hintText, buffer, maxBufferSize);
|
return CopyStringToCharBuffer(hintText, buffer, maxBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" s32 GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) {
|
extern "C" s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) {
|
||||||
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemId(ogId, actorId, actorParams, sceneNum);
|
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemId(ogId, actorId, actorParams, sceneNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" s32 GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) {
|
extern "C" s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) {
|
||||||
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId);
|
return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
~OTRGlobals();
|
~OTRGlobals();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CheckSaveFile(size_t sramSize);
|
void CheckSaveFile(size_t sramSize) const;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -61,8 +61,6 @@ SoundFontSample* ResourceMgr_LoadAudioSample(const char* path);
|
|||||||
CollisionHeader* ResourceMgr_LoadColByName(const char* path);
|
CollisionHeader* ResourceMgr_LoadColByName(const char* path);
|
||||||
void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
||||||
void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
||||||
char* Config_getValue(char* category, char* key);
|
|
||||||
bool Config_setValue(char* category, char* key, char* value);
|
|
||||||
|
|
||||||
uint64_t GetPerfCounter();
|
uint64_t GetPerfCounter();
|
||||||
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path);
|
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path);
|
||||||
@ -86,19 +84,19 @@ void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
|
|||||||
int Controller_ShouldRumble(size_t i);
|
int Controller_ShouldRumble(size_t i);
|
||||||
void* getN64WeirdFrame(s32 i);
|
void* getN64WeirdFrame(s32 i);
|
||||||
Sprite* GetSeedTexture(uint8_t index);
|
Sprite* GetSeedTexture(uint8_t index);
|
||||||
void LoadRandomizerSettings(const char* spoilerFileName);
|
void Randomizer_LoadSettings(const char* spoilerFileName);
|
||||||
u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey);
|
u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
|
||||||
RandomizerCheck GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum);
|
RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum);
|
||||||
int CopyAltarMessage(char* buffer, const int maxBufferSize);
|
int Randomizer_CopyAltarMessage(char* buffer, const int maxBufferSize);
|
||||||
int CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize);
|
int Randomizer_CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize);
|
||||||
int CopyGanonText(char* buffer, const int maxBufferSize);
|
int Randomizer_CopyGanonText(char* buffer, const int maxBufferSize);
|
||||||
int CopyGanonHintText(char* buffer, const int maxBufferSize);
|
int Randomizer_CopyGanonHintText(char* buffer, const int maxBufferSize);
|
||||||
void LoadHintLocations(const char* spoilerFileName);
|
void Randomizer_LoadHintLocations(const char* spoilerFileName);
|
||||||
void LoadItemLocations(const char* spoilerFileName, bool silent);
|
void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent);
|
||||||
s16 GetItemModelFromId(s16 itemId);
|
s16 Randomizer_GetItemModelFromId(s16 itemId);
|
||||||
s32 GetItemIDFromGetItemID(s32 getItemId);
|
s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId);
|
||||||
s32 GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
|
s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum);
|
||||||
s32 GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
|
s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "SaveManager.h"
|
#include "SaveManager.h"
|
||||||
|
#include "OTRGlobals.h"
|
||||||
|
|
||||||
#include "z64.h"
|
#include "z64.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
@ -14,11 +15,9 @@
|
|||||||
|
|
||||||
extern "C" SaveContext gSaveContext;
|
extern "C" SaveContext gSaveContext;
|
||||||
|
|
||||||
static const std::filesystem::path sSavePath("Save"); // TODO maybe let this be user-configurable?
|
|
||||||
static const std::filesystem::path sGlobalPath = sSavePath / "global.sav";
|
|
||||||
|
|
||||||
std::filesystem::path SaveManager::GetFileName(int fileNum) {
|
std::filesystem::path SaveManager::GetFileName(int fileNum) {
|
||||||
return sSavePath / (std::string("file") + std::to_string(fileNum + 1) + ".sav");
|
const std::filesystem::path sSavePath(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Save"));
|
||||||
|
return sSavePath / ("file" + std::to_string(fileNum + 1) + ".sav");
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveManager::SaveManager() {
|
SaveManager::SaveManager() {
|
||||||
@ -128,15 +127,20 @@ void SaveManager::SaveRandomizer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SaveManager::Init() {
|
void SaveManager::Init() {
|
||||||
|
const std::filesystem::path sSavePath(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Save"));
|
||||||
|
const std::filesystem::path sGlobalPath = sSavePath / std::string("global.sav");
|
||||||
|
auto sOldSavePath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav");
|
||||||
|
auto sOldBackupSavePath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.bak");
|
||||||
|
|
||||||
// If the save directory does not exist, create it
|
// If the save directory does not exist, create it
|
||||||
if (!std::filesystem::exists(sSavePath)) {
|
if (!std::filesystem::exists(sSavePath)) {
|
||||||
std::filesystem::create_directory(sSavePath);
|
std::filesystem::create_directory(sSavePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a lingering unversioned save, convert it
|
// If there is a lingering unversioned save, convert it
|
||||||
if (std::filesystem::exists("oot_save.sav")) {
|
if (std::filesystem::exists(sOldSavePath)) {
|
||||||
ConvertFromUnversioned();
|
ConvertFromUnversioned();
|
||||||
std::filesystem::rename("oot_save.sav", "oot_save.bak");
|
std::filesystem::rename(sOldSavePath, sOldBackupSavePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the global save file exist, load it. Otherwise, create it.
|
// If the global save file exist, load it. Otherwise, create it.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const char gBuildVersion[] = "ROY ALFA (2.0.0)";
|
const char gBuildVersion[] = "RACHAEL ALFA (3.0.0)";
|
||||||
const char gBuildTeam[] = "github.com/harbourmasters";
|
const char gBuildTeam[] = "github.com/harbourmasters";
|
||||||
const char gBuildDate[] = __DATE__ " " __TIME__;
|
const char gBuildDate[] = __DATE__ " " __TIME__;
|
||||||
const char gBuildMakeOption[] = "";
|
const char gBuildMakeOption[] = "";
|
||||||
|
@ -1176,9 +1176,13 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||||||
if (seqPlayer->defaultFont != 0xFF)
|
if (seqPlayer->defaultFont != 0xFF)
|
||||||
{
|
{
|
||||||
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
||||||
int8_t idx = (sDat.numFonts - result - 1);
|
|
||||||
|
|
||||||
command = sDat.fonts[abs(idx)];
|
// The game apparantely would sometimes do negative array lookups, the result of which would get rejected by AudioHeap_SearchCaches, never
|
||||||
|
// changing the actual fontid.
|
||||||
|
if (result > sDat.numFonts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
command = sDat.fonts[(sDat.numFonts - result - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command))
|
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command))
|
||||||
|
@ -409,7 +409,9 @@ void GameState_Update(GameState* gameState) {
|
|||||||
// Unrestricted Items
|
// Unrestricted Items
|
||||||
if (CVar_GetS32("gNoRestrictItems", 0) != 0) {
|
if (CVar_GetS32("gNoRestrictItems", 0) != 0) {
|
||||||
if (gGlobalCtx) {
|
if (gGlobalCtx) {
|
||||||
|
u8 sunsBackup = gGlobalCtx->interfaceCtx.restrictions.sunsSong;
|
||||||
memset(&gGlobalCtx->interfaceCtx.restrictions, 0, sizeof(gGlobalCtx->interfaceCtx.restrictions));
|
memset(&gGlobalCtx->interfaceCtx.restrictions, 0, sizeof(gGlobalCtx->interfaceCtx.restrictions));
|
||||||
|
gGlobalCtx->interfaceCtx.restrictions.sunsSong = sunsBackup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ void PadMgr_ProcessInputs(PadMgr* padMgr) {
|
|||||||
input->press.stick_y += (s8)(input->cur.stick_y - input->prev.stick_y);
|
input->press.stick_y += (s8)(input->cur.stick_y - input->prev.stick_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
controllerCallback.rumble = CVar_GetS32("gRumbleEnabled", 0) && (padMgr->rumbleEnable[0] > 0);
|
controllerCallback.rumble = (padMgr->rumbleEnable[0] > 0);
|
||||||
|
|
||||||
if (HealthMeter_IsCritical()) {
|
if (HealthMeter_IsCritical()) {
|
||||||
controllerCallback.ledColor = 0;
|
controllerCallback.ledColor = 0;
|
||||||
|
@ -5983,7 +5983,7 @@ s32 func_80038290(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* ar
|
|||||||
}
|
}
|
||||||
|
|
||||||
s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) {
|
s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) {
|
||||||
if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
||||||
// RANDOTODO update this logic when we implement keysanity
|
// RANDOTODO update this logic when we implement keysanity
|
||||||
// because 3drando replaces the keys not the rupees
|
// because 3drando replaces the keys not the rupees
|
||||||
if (ogDrawId == GID_RUPEE_GREEN ||
|
if (ogDrawId == GID_RUPEE_GREEN ||
|
||||||
@ -5993,27 +5993,27 @@ s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx)
|
|||||||
switch(room) {
|
switch(room) {
|
||||||
case 1:
|
case 1:
|
||||||
if(!Flags_GetCollectible(globalCtx, 0x1B)) {
|
if(!Flags_GetCollectible(globalCtx, 0x1B)) {
|
||||||
return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN);
|
return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if(!Flags_GetCollectible(globalCtx, 0x1C)) {
|
if(!Flags_GetCollectible(globalCtx, 0x1C)) {
|
||||||
return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN);
|
return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if(!Flags_GetCollectible(globalCtx, 0x1D)) {
|
if(!Flags_GetCollectible(globalCtx, 0x1D)) {
|
||||||
return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE);
|
return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if(!Flags_GetCollectible(globalCtx, 0x1E)) {
|
if(!Flags_GetCollectible(globalCtx, 0x1E)) {
|
||||||
return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE);
|
return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if(!Flags_GetCollectible(globalCtx, 0x1F)) {
|
if(!Flags_GetCollectible(globalCtx, 0x1F)) {
|
||||||
return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED);
|
return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6021,7 +6021,7 @@ s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ogDrawId == GID_HEART_PIECE) {
|
if(ogDrawId == GID_HEART_PIECE) {
|
||||||
return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE);
|
return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GI_NONE;
|
return GI_NONE;
|
||||||
@ -6031,7 +6031,7 @@ s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) {
|
|||||||
s32 randoGetItemId = GetChestGameRandoGetItemId(room, ogDrawId, globalCtx);
|
s32 randoGetItemId = GetChestGameRandoGetItemId(room, ogDrawId, globalCtx);
|
||||||
|
|
||||||
if(randoGetItemId != GI_NONE) {
|
if(randoGetItemId != GI_NONE) {
|
||||||
return GetItemModelFromId(randoGetItemId);
|
return Randomizer_GetItemModelFromId(randoGetItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ogDrawId;
|
return ogDrawId;
|
||||||
|
@ -1409,7 +1409,115 @@ s32 Camera_Noop(Camera* camera) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 SetCameraManual(Camera* camera) {
|
||||||
|
f32 newCamX = -D_8015BD7C->state.input[0].cur.cam_x;
|
||||||
|
f32 newCamY = D_8015BD7C->state.input[0].cur.cam_y;
|
||||||
|
|
||||||
|
if ((fabsf(newCamX) >= 15.0f || fabsf(newCamY) >= 15.0f) && camera->globalCtx->manualCamera == false) {
|
||||||
|
camera->globalCtx->manualCamera = true;
|
||||||
|
|
||||||
|
VecSph eyeAdjustment;
|
||||||
|
OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment, &camera->at, &camera->eye);
|
||||||
|
|
||||||
|
camera->globalCtx->camX = eyeAdjustment.yaw;
|
||||||
|
camera->globalCtx->camY = eyeAdjustment.pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera->globalCtx->manualCamera) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 Camera_Free(Camera* camera) {
|
||||||
|
Vec3f* eye = &camera->eye;
|
||||||
|
Vec3f* at = &camera->at;
|
||||||
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
|
VecSph spA8;
|
||||||
|
CamColChk sp6C;
|
||||||
|
Parallel1* para1 = (Parallel1*)camera->paramData;
|
||||||
|
f32 playerHeight;
|
||||||
|
|
||||||
|
at->x = Camera_LERPCeilF(camera->player->actor.world.pos.x, camera->at.x, 0.5f, 1.0f);
|
||||||
|
at->y = Camera_LERPCeilF(camera->player->actor.world.pos.y + (camera->player->rideActor != NULL
|
||||||
|
? Player_GetHeight(camera->player) / 2
|
||||||
|
: Player_GetHeight(camera->player)) /
|
||||||
|
1.2f,
|
||||||
|
camera->at.y, 0.5f, 1.0f);
|
||||||
|
at->z = Camera_LERPCeilF(camera->player->actor.world.pos.z, camera->at.z, 0.5f, 1.0f);
|
||||||
|
|
||||||
|
playerHeight = Player_GetHeight(camera->player);
|
||||||
|
|
||||||
|
if (RELOAD_PARAMS) {
|
||||||
|
OLib_Vec3fDiffToVecSphGeo(&spA8, &camera->at, &camera->eye);
|
||||||
|
|
||||||
|
camera->globalCtx->camX = spA8.yaw;
|
||||||
|
camera->globalCtx->camY = spA8.pitch;
|
||||||
|
|
||||||
|
CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values;
|
||||||
|
f32 yNormal = (1.0f + PCT(OREG(46))) - (PCT(OREG(46)) * (68.0f / playerHeight));
|
||||||
|
|
||||||
|
para1->yOffset = NEXTPCT * playerHeight * yNormal;
|
||||||
|
para1->distTarget = NEXTPCT * playerHeight * yNormal;
|
||||||
|
para1->pitchTarget = DEGF_TO_BINANG(NEXTSETTING);
|
||||||
|
para1->yawTarget = DEGF_TO_BINANG(NEXTSETTING);
|
||||||
|
para1->unk_08 = NEXTSETTING;
|
||||||
|
para1->unk_0C = NEXTSETTING;
|
||||||
|
para1->fovTarget = NEXTSETTING;
|
||||||
|
para1->unk_14 = NEXTPCT;
|
||||||
|
para1->interfaceFlags = NEXTSETTING;
|
||||||
|
para1->unk_18 = NEXTPCT * playerHeight * yNormal;
|
||||||
|
para1->unk_1C = NEXTPCT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_RELOAD_CAM_PARAMS) {
|
||||||
|
Camera_CopyPREGToModeValues(camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
sCameraInterfaceFlags = 1;
|
||||||
|
|
||||||
|
camera->animState = 1;
|
||||||
|
|
||||||
|
f32 newCamX = -D_8015BD7C->state.input[0].cur.cam_x;
|
||||||
|
f32 newCamY = D_8015BD7C->state.input[0].cur.cam_y;
|
||||||
|
|
||||||
|
camera->globalCtx->camX += newCamX;
|
||||||
|
camera->globalCtx->camY += newCamY;
|
||||||
|
|
||||||
|
if (camera->globalCtx->camY > 0x32A4) {
|
||||||
|
camera->globalCtx->camY = 0x32A4;
|
||||||
|
}
|
||||||
|
if (camera->globalCtx->camY < -0x228C) {
|
||||||
|
camera->globalCtx->camY = -0x228C;
|
||||||
|
}
|
||||||
|
|
||||||
|
camera->dist = Camera_LERPCeilF(para1->distTarget, camera->dist, 1.0f / camera->rUpdateRateInv, 0.0f);
|
||||||
|
OLib_Vec3fDiffToVecSphGeo(&spA8, at, eyeNext);
|
||||||
|
|
||||||
|
spA8.r = camera->dist;
|
||||||
|
spA8.yaw = camera->globalCtx->camX;
|
||||||
|
spA8.pitch = camera->globalCtx->camY;
|
||||||
|
|
||||||
|
Camera_Vec3fVecSphGeoAdd(eyeNext, at, &spA8);
|
||||||
|
if (camera->status == CAM_STAT_ACTIVE) {
|
||||||
|
sp6C.pos = *eyeNext;
|
||||||
|
Camera_BGCheckInfo(camera, at, &sp6C);
|
||||||
|
*eye = sp6C.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
camera->fov = Camera_LERPCeilF(65.0f, camera->fov, camera->fovUpdateRate, 1.0f);
|
||||||
|
camera->roll = Camera_LERPCeilS(0, camera->roll, 0.5, 0xA);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 Camera_Normal1(Camera* camera) {
|
s32 Camera_Normal1(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
@ -1637,6 +1745,11 @@ s32 Camera_Normal1(Camera* camera) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s32 Camera_Normal2(Camera* camera) {
|
s32 Camera_Normal2(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
@ -1803,6 +1916,11 @@ s32 Camera_Normal2(Camera* camera) {
|
|||||||
|
|
||||||
// riding epona
|
// riding epona
|
||||||
s32 Camera_Normal3(Camera* camera) {
|
s32 Camera_Normal3(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
@ -1997,6 +2115,8 @@ s32 Camera_Parallel1(Camera* camera) {
|
|||||||
OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye);
|
OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye);
|
||||||
OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext);
|
OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext);
|
||||||
|
|
||||||
|
camera->globalCtx->manualCamera = false;
|
||||||
|
|
||||||
switch (camera->animState) {
|
switch (camera->animState) {
|
||||||
case 0:
|
case 0:
|
||||||
case 0xA:
|
case 0xA:
|
||||||
@ -2162,6 +2282,11 @@ s32 Camera_Parallel0(Camera* camera) {
|
|||||||
* Generic jump, jumping off ledges
|
* Generic jump, jumping off ledges
|
||||||
*/
|
*/
|
||||||
s32 Camera_Jump1(Camera* camera) {
|
s32 Camera_Jump1(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
@ -2307,6 +2432,11 @@ s32 Camera_Jump1(Camera* camera) {
|
|||||||
|
|
||||||
// Climbing ladders/vines
|
// Climbing ladders/vines
|
||||||
s32 Camera_Jump2(Camera* camera) {
|
s32 Camera_Jump2(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
@ -2489,6 +2619,11 @@ s32 Camera_Jump2(Camera* camera) {
|
|||||||
|
|
||||||
// swimming
|
// swimming
|
||||||
s32 Camera_Jump3(Camera* camera) {
|
s32 Camera_Jump3(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
@ -2946,6 +3081,11 @@ s32 Camera_Battle3(Camera* camera) {
|
|||||||
* setting value.
|
* setting value.
|
||||||
*/
|
*/
|
||||||
s32 Camera_Battle4(Camera* camera) {
|
s32 Camera_Battle4(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
@ -4476,6 +4616,11 @@ s32 Camera_Data4(Camera* camera) {
|
|||||||
* Hanging off of a ledge
|
* Hanging off of a ledge
|
||||||
*/
|
*/
|
||||||
s32 Camera_Unique1(Camera* camera) {
|
s32 Camera_Unique1(Camera* camera) {
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
|
||||||
|
Camera_Free(camera);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3f* eye = &camera->eye;
|
Vec3f* eye = &camera->eye;
|
||||||
Vec3f* at = &camera->at;
|
Vec3f* at = &camera->at;
|
||||||
Vec3f* eyeNext = &camera->eyeNext;
|
Vec3f* eyeNext = &camera->eyeNext;
|
||||||
|
@ -2124,7 +2124,7 @@ void Cutscene_HandleConditionalTriggers(GlobalContext* globalCtx) {
|
|||||||
|
|
||||||
// If we are rando and tower escape skip is on, then set the flag to say we saw the towers fall
|
// If we are rando and tower escape skip is on, then set the flag to say we saw the towers fall
|
||||||
// and exit.
|
// and exit.
|
||||||
if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_SKIP_TOWER_ESCAPE)) {
|
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gSaveContext.cutsceneIndex = 0xFFF0;
|
gSaveContext.cutsceneIndex = 0xFFF0;
|
||||||
|
@ -509,7 +509,7 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((gSaveContext.n64ddFlag || getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) {
|
if ((gSaveContext.n64ddFlag || getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) {
|
||||||
getItemId = GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
getItemId = Randomizer_GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
||||||
func_8002F554(&this->actor, globalCtx, getItemId);
|
func_8002F554(&this->actor, globalCtx, getItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ void func_8001DFC8(EnItem00* this, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->actor.params == ITEM00_HEART_PIECE) {
|
if (this->actor.params == ITEM00_HEART_PIECE) {
|
||||||
if ((CVar_GetS32("gNewDrops", 0) !=0) && !gSaveContext.n64ddFlag) {
|
if (CVar_GetS32("gNewDrops", 0) && !gSaveContext.n64ddFlag) {
|
||||||
this->actor.shape.yOffset = Math_SinS(this->actor.shape.rot.y) * 20.0f + 50.0f;
|
this->actor.shape.yOffset = Math_SinS(this->actor.shape.rot.y) * 20.0f + 50.0f;
|
||||||
} else {
|
} else {
|
||||||
this->actor.shape.yOffset = Math_SinS(this->actor.shape.rot.y) * 150.0f + 850.0f;
|
this->actor.shape.yOffset = Math_SinS(this->actor.shape.rot.y) * 150.0f + 850.0f;
|
||||||
@ -881,7 +881,7 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
|
|
||||||
if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) {
|
if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) {
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
getItemId = GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
getItemId = Randomizer_GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
||||||
}
|
}
|
||||||
func_8002F554(&this->actor, globalCtx, getItemId);
|
func_8002F554(&this->actor, globalCtx, getItemId);
|
||||||
}
|
}
|
||||||
@ -1297,14 +1297,14 @@ void EnItem00_DrawRupee(EnItem00* this, GlobalContext* globalCtx) {
|
|||||||
* Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...).
|
* Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...).
|
||||||
*/
|
*/
|
||||||
void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) {
|
void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) {
|
||||||
if ((gSaveContext.n64ddFlag && this->getItemId != GI_NONE) || this->actor.params == ITEM00_SMALL_KEY) {
|
if (gSaveContext.n64ddFlag && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) {
|
||||||
f32 mtxScale = 16.0f;
|
f32 mtxScale = 16.0f;
|
||||||
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
|
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
|
||||||
s32 randoGetItemId = GetRandomizedItemId(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
s32 randoGetItemId = Randomizer_GetRandomizedItemId(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
||||||
if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) {
|
if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) {
|
||||||
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId);
|
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId);
|
||||||
}
|
}
|
||||||
GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId));
|
GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId));
|
||||||
} else {
|
} else {
|
||||||
s32 texIndex = this->actor.params - 3;
|
s32 texIndex = this->actor.params - 3;
|
||||||
|
|
||||||
@ -1360,11 +1360,11 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) {
|
|||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
f32 mtxScale = 16.0f;
|
f32 mtxScale = 16.0f;
|
||||||
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
|
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
|
||||||
s32 randoGetItemId = GetRandomizedItemId(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
s32 randoGetItemId = Randomizer_GetRandomizedItemId(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum);
|
||||||
if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) {
|
if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) {
|
||||||
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId);
|
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId);
|
||||||
}
|
}
|
||||||
GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId));
|
GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId));
|
||||||
} else {
|
} else {
|
||||||
s32 pad;
|
s32 pad;
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ void TransitionWipe_Draw(void* thisx, Gfx** gfxP) {
|
|||||||
TransitionWipe* this = (TransitionWipe*)thisx;
|
TransitionWipe* this = (TransitionWipe*)thisx;
|
||||||
s32 pad[4];
|
s32 pad[4];
|
||||||
Gfx* tex;
|
Gfx* tex;
|
||||||
|
Gfx* wipeDl = sWipeDList;
|
||||||
|
|
||||||
modelView = this->modelView[this->frame];
|
modelView = this->modelView[this->frame];
|
||||||
|
|
||||||
|
@ -1676,11 +1676,11 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) {
|
|||||||
// if we're rando'd and talking to a gossip stone
|
// if we're rando'd and talking to a gossip stone
|
||||||
if (gSaveContext.n64ddFlag &&
|
if (gSaveContext.n64ddFlag &&
|
||||||
textId == 0x2053 &&
|
textId == 0x2053 &&
|
||||||
GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) != 0 &&
|
Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) != 0 &&
|
||||||
(GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) == 1 ||
|
(Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 1 ||
|
||||||
(GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) == 2 &&
|
(Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 2 &&
|
||||||
Player_GetMask(globalCtx) == PLAYER_MASK_TRUTH) ||
|
Player_GetMask(globalCtx) == PLAYER_MASK_TRUTH) ||
|
||||||
(GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) == 3 &&
|
(Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 3 &&
|
||||||
CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) {
|
CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) {
|
||||||
|
|
||||||
s16 actorParams = msgCtx->talkActor->params;
|
s16 actorParams = msgCtx->talkActor->params;
|
||||||
@ -1700,14 +1700,14 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomizerCheck hintCheck = GetCheckFromActor(globalCtx->sceneNum, msgCtx->talkActor->id, actorParams);
|
RandomizerCheck hintCheck = Randomizer_GetCheckFromActor(globalCtx->sceneNum, msgCtx->talkActor->id, actorParams);
|
||||||
|
|
||||||
// Pass the sizeof the message buffer so we don't hardcode any sizes and can rely on globals.
|
// Pass the sizeof the message buffer so we don't hardcode any sizes and can rely on globals.
|
||||||
// If no hint can be found, this just returns 0 size and doesn't modify the buffer, so no worries.
|
// If no hint can be found, this just returns 0 size and doesn't modify the buffer, so no worries.
|
||||||
msgCtx->msgLength = font->msgLength = CopyHintFromCheck(hintCheck, font->msgBuf, sizeof(font->msgBuf));
|
msgCtx->msgLength = font->msgLength = Randomizer_CopyHintFromCheck(hintCheck, font->msgBuf, sizeof(font->msgBuf));
|
||||||
} else if (gSaveContext.n64ddFlag && (textId == 0x7040 || textId == 0x7088)) {
|
} else if (gSaveContext.n64ddFlag && (textId == 0x7040 || textId == 0x7088)) {
|
||||||
// rando hints at altar
|
// rando hints at altar
|
||||||
msgCtx->msgLength = font->msgLength = CopyAltarMessage(font->msgBuf, sizeof(font->msgBuf));
|
msgCtx->msgLength = font->msgLength = Randomizer_CopyAltarMessage(font->msgBuf, sizeof(font->msgBuf));
|
||||||
} else if (textId == 0x00b4 && CVar_GetS32("gInjectSkulltulaCount", 0) != 0) {
|
} else if (textId == 0x00b4 && CVar_GetS32("gInjectSkulltulaCount", 0) != 0) {
|
||||||
switch (gSaveContext.language) {
|
switch (gSaveContext.language) {
|
||||||
case LANGUAGE_FRA:
|
case LANGUAGE_FRA:
|
||||||
@ -1731,9 +1731,9 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) {
|
|||||||
msgCtx->msgLength = font->msgLength = CopyScrubMessage(textId, font->msgBuf, sizeof(font->msgBuf));
|
msgCtx->msgLength = font->msgLength = CopyScrubMessage(textId, font->msgBuf, sizeof(font->msgBuf));
|
||||||
} else if (gSaveContext.n64ddFlag && textId == 0x70CC) {
|
} else if (gSaveContext.n64ddFlag && textId == 0x70CC) {
|
||||||
if (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) {
|
if (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) {
|
||||||
msgCtx->msgLength = font->msgLength = CopyGanonText(font->msgBuf, sizeof(font->msgBuf));
|
msgCtx->msgLength = font->msgLength = Randomizer_CopyGanonText(font->msgBuf, sizeof(font->msgBuf));
|
||||||
} else {
|
} else {
|
||||||
msgCtx->msgLength = font->msgLength = CopyGanonHintText(font->msgBuf, sizeof(font->msgBuf));
|
msgCtx->msgLength = font->msgLength = Randomizer_CopyGanonHintText(font->msgBuf, sizeof(font->msgBuf));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgCtx->msgLength = font->msgLength;
|
msgCtx->msgLength = font->msgLength;
|
||||||
@ -2237,14 +2237,14 @@ void Message_DrawMain(GlobalContext* globalCtx, Gfx** p) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
osSyncPrintf("Na_StartOcarinaSinglePlayCheck2( message->ocarina_no );\n");
|
osSyncPrintf("Na_StartOcarinaSinglePlayCheck2( message->ocarina_no );\n");
|
||||||
func_800ECC04((1 << msgCtx->ocarinaAction) + 0x8000);
|
func_800ECC04((1 << (msgCtx->ocarinaAction % 32)) + 0x8000);
|
||||||
}
|
}
|
||||||
msgCtx->msgMode = MSGMODE_OCARINA_PLAYING;
|
msgCtx->msgMode = MSGMODE_OCARINA_PLAYING;
|
||||||
} else if (msgCtx->msgMode == MSGMODE_SONG_DEMONSTRATION_STARTING) {
|
} else if (msgCtx->msgMode == MSGMODE_SONG_DEMONSTRATION_STARTING) {
|
||||||
msgCtx->stateTimer = 20;
|
msgCtx->stateTimer = 20;
|
||||||
msgCtx->msgMode = MSGMODE_SONG_DEMONSTRATION_SELECT_INSTRUMENT;
|
msgCtx->msgMode = MSGMODE_SONG_DEMONSTRATION_SELECT_INSTRUMENT;
|
||||||
} else {
|
} else {
|
||||||
func_800ECC04((1 << (msgCtx->ocarinaAction + 0x11)) + 0x8000);
|
func_800ECC04((1 << ((msgCtx->ocarinaAction + 0x11) % 32)) + 0x8000);
|
||||||
// "Performance Check"
|
// "Performance Check"
|
||||||
osSyncPrintf("演奏チェック=%d\n", msgCtx->ocarinaAction - OCARINA_ACTION_PLAYBACK_MINUET);
|
osSyncPrintf("演奏チェック=%d\n", msgCtx->ocarinaAction - OCARINA_ACTION_PLAYBACK_MINUET);
|
||||||
msgCtx->msgMode = MSGMODE_SONG_PLAYBACK;
|
msgCtx->msgMode = MSGMODE_SONG_PLAYBACK;
|
||||||
@ -3228,6 +3228,8 @@ void Message_DrawMain(GlobalContext* globalCtx, Gfx** p) {
|
|||||||
* the last value being saved in a static variable.
|
* the last value being saved in a static variable.
|
||||||
*/
|
*/
|
||||||
void Message_DrawDebugVariableChanged(s16* var, GraphicsContext* gfxCtx) {
|
void Message_DrawDebugVariableChanged(s16* var, GraphicsContext* gfxCtx) {
|
||||||
|
if (!CVar_GetS32("gDebugEnabled", 0)) { return; }
|
||||||
|
|
||||||
static s16 sVarLastValue = 0;
|
static s16 sVarLastValue = 0;
|
||||||
static s16 sFillTimer = 0;
|
static s16 sFillTimer = 0;
|
||||||
s32 pad;
|
s32 pad;
|
||||||
|
@ -1710,6 +1710,8 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
|
|||||||
} else {
|
} else {
|
||||||
gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS];
|
gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS];
|
||||||
}
|
}
|
||||||
return ITEM_NONE;
|
return ITEM_NONE;
|
||||||
} else if (item == ITEM_KEY_SMALL) {
|
} else if (item == ITEM_KEY_SMALL) {
|
||||||
@ -1808,13 +1810,13 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
|
|||||||
return ITEM_NONE;
|
return ITEM_NONE;
|
||||||
} else if (item == ITEM_WALLET_ADULT) {
|
} else if (item == ITEM_WALLET_ADULT) {
|
||||||
Inventory_ChangeUpgrade(UPG_WALLET, 1);
|
Inventory_ChangeUpgrade(UPG_WALLET, 1);
|
||||||
if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_FULL_WALLETS)) {
|
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) {
|
||||||
Rupees_ChangeBy(200);
|
Rupees_ChangeBy(200);
|
||||||
}
|
}
|
||||||
return ITEM_NONE;
|
return ITEM_NONE;
|
||||||
} else if (item == ITEM_WALLET_GIANT) {
|
} else if (item == ITEM_WALLET_GIANT) {
|
||||||
Inventory_ChangeUpgrade(UPG_WALLET, 2);
|
Inventory_ChangeUpgrade(UPG_WALLET, 2);
|
||||||
if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_FULL_WALLETS)) {
|
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) {
|
||||||
Rupees_ChangeBy(500);
|
Rupees_ChangeBy(500);
|
||||||
}
|
}
|
||||||
return ITEM_NONE;
|
return ITEM_NONE;
|
||||||
|
@ -198,7 +198,7 @@ void GivePlayerRandoRewardSongOfTime(GlobalContext* globalCtx, RandomizerCheck c
|
|||||||
|
|
||||||
if (gSaveContext.entranceIndex == 0x050F && player != NULL && !Player_InBlockingCsMode(globalCtx, player) &&
|
if (gSaveContext.entranceIndex == 0x050F && player != NULL && !Player_InBlockingCsMode(globalCtx, player) &&
|
||||||
!Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF) {
|
!Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF) {
|
||||||
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_SONG_OF_TIME);
|
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME);
|
||||||
GiveItemWithoutActor(globalCtx, getItemId);
|
GiveItemWithoutActor(globalCtx, getItemId);
|
||||||
Flags_SetTreasure(globalCtx, 0x1F);
|
Flags_SetTreasure(globalCtx, 0x1F);
|
||||||
}
|
}
|
||||||
@ -212,7 +212,7 @@ void GivePlayerRandoRewardNocturne(GlobalContext* globalCtx, RandomizerCheck che
|
|||||||
gSaveContext.entranceIndex == 0x0195) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) &&
|
gSaveContext.entranceIndex == 0x0195) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) &&
|
||||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL &&
|
CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL &&
|
||||||
!Player_InBlockingCsMode(globalCtx, player) && !Flags_GetEventChkInf(0xAA)) {
|
!Player_InBlockingCsMode(globalCtx, player) && !Flags_GetEventChkInf(0xAA)) {
|
||||||
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_NOCTURNE_OF_SHADOW);
|
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_NOCTURNE_OF_SHADOW);
|
||||||
GiveItemWithoutActor(globalCtx, getItemId);
|
GiveItemWithoutActor(globalCtx, getItemId);
|
||||||
Flags_SetEventChkInf(0xAA);
|
Flags_SetEventChkInf(0xAA);
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ void GivePlayerRandoRewardRequiem(GlobalContext* globalCtx, RandomizerCheck chec
|
|||||||
if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) {
|
if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) {
|
||||||
if ((gSaveContext.entranceIndex == 0x01E1) && !Flags_GetEventChkInf(0xAC) && player != NULL &&
|
if ((gSaveContext.entranceIndex == 0x01E1) && !Flags_GetEventChkInf(0xAC) && player != NULL &&
|
||||||
!Player_InBlockingCsMode(globalCtx, player)) {
|
!Player_InBlockingCsMode(globalCtx, player)) {
|
||||||
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_SONG_OF_TIME);
|
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME);
|
||||||
GiveItemWithoutActor(globalCtx, getItemId);
|
GiveItemWithoutActor(globalCtx, getItemId);
|
||||||
Flags_SetEventChkInf(0xAC);
|
Flags_SetEventChkInf(0xAC);
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi
|
|||||||
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TOKINOMA) &&
|
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TOKINOMA) &&
|
||||||
!Flags_GetTreasure(globalCtx, 0x1E) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) &&
|
!Flags_GetTreasure(globalCtx, 0x1E) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) &&
|
||||||
globalCtx->sceneLoadFlag == 0 && player->getItemId == GI_NONE) {
|
globalCtx->sceneLoadFlag == 0 && player->getItemId == GI_NONE) {
|
||||||
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_ARROW_LIGHT);
|
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ARROW_LIGHT);
|
||||||
GiveItemWithoutActor(globalCtx, getItemId);
|
GiveItemWithoutActor(globalCtx, getItemId);
|
||||||
Flags_SetTreasure(globalCtx, 0x1E);
|
Flags_SetTreasure(globalCtx, 0x1E);
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi
|
|||||||
void GivePlayerRandoRewardSariaGift(GlobalContext* globalCtx, RandomizerCheck check) {
|
void GivePlayerRandoRewardSariaGift(GlobalContext* globalCtx, RandomizerCheck check) {
|
||||||
Player* player = GET_PLAYER(globalCtx);
|
Player* player = GET_PLAYER(globalCtx);
|
||||||
if (gSaveContext.entranceIndex == 0x05E0) {
|
if (gSaveContext.entranceIndex == 0x05E0) {
|
||||||
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY);
|
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY);
|
||||||
|
|
||||||
if ((!Flags_GetEventChkInf(0xC1) || (player->getItemId == getItemId && getItemId != GI_ICE_TRAP)) &&
|
if ((!Flags_GetEventChkInf(0xC1) || (player->getItemId == getItemId && getItemId != GI_ICE_TRAP)) &&
|
||||||
player != NULL && !Player_InBlockingCsMode(globalCtx, player)) {
|
player != NULL && !Player_InBlockingCsMode(globalCtx, player)) {
|
||||||
@ -271,7 +271,7 @@ void Gameplay_Init(GameState* thisx) {
|
|||||||
u8 tempSetupIndex;
|
u8 tempSetupIndex;
|
||||||
s32 pad[2];
|
s32 pad[2];
|
||||||
|
|
||||||
if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_SKIP_CHILD_STEALTH)) {
|
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SKIP_CHILD_STEALTH)) {
|
||||||
if (gSaveContext.entranceIndex == 0x7A) {
|
if (gSaveContext.entranceIndex == 0x7A) {
|
||||||
gSaveContext.entranceIndex = 0x400;
|
gSaveContext.entranceIndex = 0x400;
|
||||||
} else if (gSaveContext.entranceIndex == 0x296) {
|
} else if (gSaveContext.entranceIndex == 0x296) {
|
||||||
@ -530,6 +530,10 @@ void Gameplay_Update(GlobalContext* globalCtx) {
|
|||||||
ActorOverlayTable_LogPrint();
|
ActorOverlayTable_LogPrint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CVar_GetS32("gFreeCamera", 0) && Player_InCsMode(globalCtx)) {
|
||||||
|
globalCtx->manualCamera = false;
|
||||||
|
}
|
||||||
|
|
||||||
gSegments[4] = VIRTUAL_TO_PHYSICAL(globalCtx->objectCtx.status[globalCtx->objectCtx.mainKeepIndex].segment);
|
gSegments[4] = VIRTUAL_TO_PHYSICAL(globalCtx->objectCtx.status[globalCtx->objectCtx.mainKeepIndex].segment);
|
||||||
gSegments[5] = VIRTUAL_TO_PHYSICAL(globalCtx->objectCtx.status[globalCtx->objectCtx.subKeepIndex].segment);
|
gSegments[5] = VIRTUAL_TO_PHYSICAL(globalCtx->objectCtx.status[globalCtx->objectCtx.subKeepIndex].segment);
|
||||||
gSegments[2] = VIRTUAL_TO_PHYSICAL(globalCtx->sceneSegment);
|
gSegments[2] = VIRTUAL_TO_PHYSICAL(globalCtx->sceneSegment);
|
||||||
|
@ -416,7 +416,7 @@ void GiveLinkDungeonReward(GetItemID getItemId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GiveLinksPocketMedallion() {
|
void GiveLinksPocketMedallion() {
|
||||||
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE);
|
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE);
|
||||||
|
|
||||||
GiveLinkDungeonReward(getItemId);
|
GiveLinkDungeonReward(getItemId);
|
||||||
}
|
}
|
||||||
@ -644,7 +644,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
// Give Link's pocket item
|
// Give Link's pocket item
|
||||||
GiveLinksPocketMedallion();
|
GiveLinksPocketMedallion();
|
||||||
|
|
||||||
int openForest = GetRandoSettingValue(RSK_FOREST);
|
int openForest = Randomizer_GetSettingValue(RSK_FOREST);
|
||||||
switch (openForest) {
|
switch (openForest) {
|
||||||
case 0: // closed
|
case 0: // closed
|
||||||
break;
|
break;
|
||||||
@ -657,28 +657,28 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int doorOfTime = GetRandoSettingValue(RSK_DOOR_OF_TIME);
|
int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME);
|
||||||
switch (doorOfTime) {
|
switch (doorOfTime) {
|
||||||
case 0: // open
|
case 0: // open
|
||||||
gSaveContext.eventChkInf[4] |= 0x800;
|
gSaveContext.eventChkInf[4] |= 0x800;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kakGate = GetRandoSettingValue(RSK_KAK_GATE);
|
int kakGate = Randomizer_GetSettingValue(RSK_KAK_GATE);
|
||||||
switch (kakGate) {
|
switch (kakGate) {
|
||||||
case 1: // open
|
case 1: // open
|
||||||
gSaveContext.infTable[7] |= 0x40;
|
gSaveContext.infTable[7] |= 0x40;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetRandoSettingValue(RSK_STARTING_KOKIRI_SWORD)) GiveLinkKokiriSword();
|
if(Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) GiveLinkKokiriSword();
|
||||||
if(GetRandoSettingValue(RSK_STARTING_DEKU_SHIELD)) GiveLinkDekuShield();
|
if(Randomizer_GetSettingValue(RSK_STARTING_DEKU_SHIELD)) GiveLinkDekuShield();
|
||||||
|
|
||||||
if(GetRandoSettingValue(RSK_STARTING_OCARINA)) {
|
if(Randomizer_GetSettingValue(RSK_STARTING_OCARINA)) {
|
||||||
INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY;
|
INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetRandoSettingValue(RSK_STARTING_MAPS_COMPASSES)) {
|
if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES)) {
|
||||||
uint32_t mapBitMask = 1 << 1;
|
uint32_t mapBitMask = 1 << 1;
|
||||||
uint32_t compassBitMask = 1 << 2;
|
uint32_t compassBitMask = 1 << 2;
|
||||||
uint32_t startingDungeonItemsBitMask = mapBitMask | compassBitMask;
|
uint32_t startingDungeonItemsBitMask = mapBitMask | compassBitMask;
|
||||||
@ -687,13 +687,13 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetRandoSettingValue(RSK_STARTING_CONSUMABLES)) {
|
if (Randomizer_GetSettingValue(RSK_STARTING_CONSUMABLES)) {
|
||||||
GiveLinkDekuSticks(10);
|
GiveLinkDekuSticks(10);
|
||||||
GiveLinkDekuNuts(20);
|
GiveLinkDekuNuts(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA)) {
|
if(Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) {
|
||||||
s32 giid = GetRandomizedItemIdFromKnownCheck(RC_SONG_FROM_IMPA, GI_ZELDAS_LULLABY);
|
s32 giid = Randomizer_GetItemIdFromKnownCheck(RC_SONG_FROM_IMPA, GI_ZELDAS_LULLABY);
|
||||||
|
|
||||||
if(giid >= GI_ZELDAS_LULLABY && giid <= GI_PRELUDE_OF_LIGHT) {
|
if(giid >= GI_ZELDAS_LULLABY && giid <= GI_PRELUDE_OF_LIGHT) {
|
||||||
GiveLinkSong(giid);
|
GiveLinkSong(giid);
|
||||||
@ -780,7 +780,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
} else if (giid == GI_DOUBLE_DEFENSE) {
|
} else if (giid == GI_DOUBLE_DEFENSE) {
|
||||||
GiveLinkDoubleDefense();
|
GiveLinkDoubleDefense();
|
||||||
} else {
|
} else {
|
||||||
s32 iid = GetItemIDFromGetItemID(giid);
|
s32 iid = Randomizer_GetItemIDFromGetItemID(giid);
|
||||||
if (iid != -1) INV_CONTENT(iid) = iid;
|
if (iid != -1) INV_CONTENT(iid) = iid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,18 +801,18 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA;
|
INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetRandoSettingValue(RSK_FULL_WALLETS)) {
|
if (Randomizer_GetSettingValue(RSK_FULL_WALLETS)) {
|
||||||
GiveLinkRupees(9001);
|
GiveLinkRupees(9001);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Ganon's boss key "Start With" is 0
|
// For Ganon's boss key "Start With" is 0
|
||||||
if(GetRandoSettingValue(RSK_GANONS_BOSS_KEY) == 0) {
|
if(Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == 0) {
|
||||||
gSaveContext.inventory.dungeonItems[10] |= 1;
|
gSaveContext.inventory.dungeonItems[10] |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * GetRandoSettingValue(RSK_BIG_POE_COUNT));
|
HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT));
|
||||||
|
|
||||||
if(GetRandoSettingValue(RSK_SKIP_EPONA_RACE)) {
|
if(Randomizer_GetSettingValue(RSK_SKIP_EPONA_RACE)) {
|
||||||
gSaveContext.eventChkInf[1] |= (1 << 8);
|
gSaveContext.eventChkInf[1] |= (1 << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,6 +826,11 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
// Go away ruto (water temple first cutscene)
|
// Go away ruto (water temple first cutscene)
|
||||||
gSaveContext.sceneFlags[05].swch |= (1 << 0x10);
|
gSaveContext.sceneFlags[05].swch |= (1 << 0x10);
|
||||||
|
|
||||||
|
// Opens locked Water Temple door to prevent softlocks
|
||||||
|
// West door on the middle level that leads to the water raising thing
|
||||||
|
// Happens in 3DS rando and N64 rando as well
|
||||||
|
gSaveContext.sceneFlags[05].swch |= (1 << 0x15);
|
||||||
|
|
||||||
// Skip intro cutscene when bombing mud wall in Dodongo's cavern
|
// Skip intro cutscene when bombing mud wall in Dodongo's cavern
|
||||||
// this also makes the lower jaw render, and the eyes react to explosives
|
// this also makes the lower jaw render, and the eyes react to explosives
|
||||||
Flags_SetEventChkInf(0xB0);
|
Flags_SetEventChkInf(0xB0);
|
||||||
@ -834,7 +839,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
gSaveContext.infTable[25] |= 0x20;
|
gSaveContext.infTable[25] |= 0x20;
|
||||||
|
|
||||||
// fast gerudo fortress
|
// fast gerudo fortress
|
||||||
if (GetRandoSettingValue(RSK_GERUDO_FORTRESS) == 1 || GetRandoSettingValue(RSK_GERUDO_FORTRESS) == 2) {
|
if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == 1 || Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == 2) {
|
||||||
gSaveContext.eventChkInf[9] |= 2;
|
gSaveContext.eventChkInf[9] |= 2;
|
||||||
gSaveContext.eventChkInf[9] |= 4;
|
gSaveContext.eventChkInf[9] |= 4;
|
||||||
gSaveContext.eventChkInf[9] |= 8;
|
gSaveContext.eventChkInf[9] |= 8;
|
||||||
@ -853,14 +858,14 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open gerudo fortress
|
// open gerudo fortress
|
||||||
if (GetRandoSettingValue(RSK_GERUDO_FORTRESS) == 2) {
|
if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == 2) {
|
||||||
gSaveContext.eventChkInf[9] |= 1;
|
gSaveContext.eventChkInf[9] |= 1;
|
||||||
gSaveContext.sceneFlags[12].swch |= (1 << 0x01);
|
gSaveContext.sceneFlags[12].swch |= (1 << 0x01);
|
||||||
gSaveContext.sceneFlags[12].swch |= (1 << 0x05);
|
gSaveContext.sceneFlags[12].swch |= (1 << 0x05);
|
||||||
gSaveContext.sceneFlags[12].swch |= (1 << 0x11);
|
gSaveContext.sceneFlags[12].swch |= (1 << 0x11);
|
||||||
gSaveContext.sceneFlags[12].collect |= (1 << 0x0C);
|
gSaveContext.sceneFlags[12].collect |= (1 << 0x0C);
|
||||||
|
|
||||||
if (!GetRandoSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
||||||
GiveLinkGerudoCard();
|
GiveLinkGerudoCard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ const ActorInit Bg_Dy_Yoseizo_InitVars = {
|
|||||||
|
|
||||||
void GivePlayerRandoRewardGreatFairy(BgDyYoseizo* this, GlobalContext* globalCtx) {
|
void GivePlayerRandoRewardGreatFairy(BgDyYoseizo* this, GlobalContext* globalCtx) {
|
||||||
Player* player = GET_PLAYER(globalCtx);
|
Player* player = GET_PLAYER(globalCtx);
|
||||||
GetItemID getItemId = GetRandomizedItemId(GI_NONE, this->actor.id, this->fountainType + 1, globalCtx->sceneNum);
|
GetItemID getItemId = Randomizer_GetRandomizedItemId(GI_NONE, this->actor.id, this->fountainType + 1, globalCtx->sceneNum);
|
||||||
|
|
||||||
if (this->actor.parent == GET_PLAYER(globalCtx) && !Flags_GetTreasure(globalCtx, this->fountainType + 1) &&
|
if (this->actor.parent == GET_PLAYER(globalCtx) && !Flags_GetTreasure(globalCtx, this->fountainType + 1) &&
|
||||||
!Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) {
|
!Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) {
|
||||||
|
@ -46,7 +46,7 @@ void BgGateShutter_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
this->somePos.z = thisx->world.pos.z;
|
this->somePos.z = thisx->world.pos.z;
|
||||||
if (((gSaveContext.infTable[7] & 0x40) ||
|
if (((gSaveContext.infTable[7] & 0x40) ||
|
||||||
(!gSaveContext.n64ddFlag && (gSaveContext.eventChkInf[4] & 0x20)) ||
|
(!gSaveContext.n64ddFlag && (gSaveContext.eventChkInf[4] & 0x20)) ||
|
||||||
(gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_KAK_GATE))) &&
|
(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_KAK_GATE))) &&
|
||||||
(globalCtx->sceneNum == SCENE_SPOT01)) {
|
(globalCtx->sceneNum == SCENE_SPOT01)) {
|
||||||
thisx->world.pos.x = -89.0f;
|
thisx->world.pos.x = -89.0f;
|
||||||
thisx->world.pos.z = -1375.0f;
|
thisx->world.pos.z = -1375.0f;
|
||||||
|
@ -50,7 +50,7 @@ void BgGjyoBridge_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
|
|
||||||
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, thisx, colHeader);
|
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, thisx, colHeader);
|
||||||
|
|
||||||
int bridge = GetRandoSettingValue(RSK_RAINBOW_BRIDGE);
|
int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE);
|
||||||
if (gSaveContext.eventChkInf[4] & 0x2000 || (gSaveContext.n64ddFlag && bridge == 0)) {
|
if (gSaveContext.eventChkInf[4] & 0x2000 || (gSaveContext.n64ddFlag && bridge == 0)) {
|
||||||
this->actionFunc = func_808787A4;
|
this->actionFunc = func_808787A4;
|
||||||
} else {
|
} else {
|
||||||
@ -176,12 +176,12 @@ void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, GlobalContext* globalCtx)
|
|||||||
LaunchBridgeCutscene(this, globalCtx);
|
LaunchBridgeCutscene(this, globalCtx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int bridge = GetRandoSettingValue(RSK_RAINBOW_BRIDGE);
|
int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE);
|
||||||
int bridgeStoneCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_STONE_COUNT);
|
int bridgeStoneCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_STONE_COUNT);
|
||||||
int bridgeMedallionCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT);
|
int bridgeMedallionCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT);
|
||||||
int bridgeRewardCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_REWARD_COUNT);
|
int bridgeRewardCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_REWARD_COUNT);
|
||||||
int bridgeDungeonCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT);
|
int bridgeDungeonCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT);
|
||||||
int bridgeTokenCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_TOKEN_COUNT);
|
int bridgeTokenCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_TOKEN_COUNT);
|
||||||
|
|
||||||
if (CheckPlayerPosition(player, globalCtx)) {
|
if (CheckPlayerPosition(player, globalCtx)) {
|
||||||
switch (bridge) {
|
switch (bridge) {
|
||||||
|
@ -1504,7 +1504,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, GlobalContext* globalCtx)
|
|||||||
|
|
||||||
if (this->csTimer == 180) {
|
if (this->csTimer == 180) {
|
||||||
globalCtx->sceneLoadFlag = 0x14;
|
globalCtx->sceneLoadFlag = 0x14;
|
||||||
if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_SKIP_TOWER_ESCAPE)) {
|
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)) {
|
||||||
Flags_SetEventChkInf(0xC7);
|
Flags_SetEventChkInf(0xC7);
|
||||||
globalCtx->nextEntranceIndex = 0x517;
|
globalCtx->nextEntranceIndex = 0x517;
|
||||||
}
|
}
|
||||||
|
@ -899,12 +899,12 @@ void func_80986BF8(DemoIm* this, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GivePlayerRandoRewardImpa(Actor* impa, GlobalContext* globalCtx, RandomizerCheck check) {
|
void GivePlayerRandoRewardImpa(Actor* impa, GlobalContext* globalCtx, RandomizerCheck check) {
|
||||||
GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY);
|
GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY);
|
||||||
|
|
||||||
if (impa->parent != NULL && impa->parent->id == GET_PLAYER(globalCtx)->actor.id &&
|
if (impa->parent != NULL && impa->parent->id == GET_PLAYER(globalCtx)->actor.id &&
|
||||||
!Flags_GetTreasure(globalCtx, 0x1F)) {
|
!Flags_GetTreasure(globalCtx, 0x1F)) {
|
||||||
Flags_SetTreasure(globalCtx, 0x1F);
|
Flags_SetTreasure(globalCtx, 0x1F);
|
||||||
} else if (!Flags_GetTreasure(globalCtx, 0x1F) && !GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA)) {
|
} else if (!Flags_GetTreasure(globalCtx, 0x1F) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) {
|
||||||
func_8002F434(impa, globalCtx, getItemId, 75.0f, 50.0f);
|
func_8002F434(impa, globalCtx, getItemId, 75.0f, 50.0f);
|
||||||
} else if (!Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) {
|
} else if (!Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) {
|
||||||
gSaveContext.eventChkInf[5] |= 0x200;
|
gSaveContext.eventChkInf[5] |= 0x200;
|
||||||
|
@ -788,7 +788,14 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
this->unk_150[i].unk_0.y = (s16)((Rand_ZeroOne() - 0.5f) * 16.0f * temp_f22);
|
this->unk_150[i].unk_0.y = (s16)((Rand_ZeroOne() - 0.5f) * 16.0f * temp_f22);
|
||||||
this->unk_150[i].unk_0.z = (s16)((Rand_ZeroOne() - 0.5f) * 16.0f * temp_f22);
|
this->unk_150[i].unk_0.z = (s16)((Rand_ZeroOne() - 0.5f) * 16.0f * temp_f22);
|
||||||
this->unk_150[i].unk_23 = 0;
|
this->unk_150[i].unk_23 = 0;
|
||||||
|
|
||||||
|
// Skip the first part of warp song cutscenes in rando
|
||||||
|
if (gSaveContext.n64ddFlag && this->actor.params == DEMOKANKYO_WARP_OUT) {
|
||||||
|
this->unk_150[i].unk_22 = 2;
|
||||||
|
} else {
|
||||||
this->unk_150[i].unk_22++;
|
this->unk_150[i].unk_22++;
|
||||||
|
}
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (this->actor.params == DEMOKANKYO_WARP_OUT) {
|
if (this->actor.params == DEMOKANKYO_WARP_OUT) {
|
||||||
if (func_800BB2B4(&camPos, &sWarpRoll, &sWarpFoV, sWarpOutCameraPoints, &this->unk_150[i].unk_20,
|
if (func_800BB2B4(&camPos, &sWarpRoll, &sWarpFoV, sWarpOutCameraPoints, &this->unk_150[i].unk_20,
|
||||||
|
@ -128,7 +128,7 @@ void DemoKekkai_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
this->collider2.dim.yShift = 300;
|
this->collider2.dim.yShift = 300;
|
||||||
|
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
int trialsToComplete = GetRandoSettingValue(RSK_TRIAL_COUNT);
|
int trialsToComplete = Randomizer_GetSettingValue(RSK_TRIAL_COUNT);
|
||||||
if (trialsToComplete <= TrialsDoneCount()) {
|
if (trialsToComplete <= TrialsDoneCount()) {
|
||||||
Actor_Kill(thisx);
|
Actor_Kill(thisx);
|
||||||
return;
|
return;
|
||||||
|
@ -462,7 +462,7 @@ s32 DoorWarp1_PlayerInRange(DoorWarp1* this, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GivePlayerRandoReward(DoorWarp1* this, Player* player, GlobalContext* globalCtx, u8 ruto, u8 adult) {
|
void GivePlayerRandoReward(DoorWarp1* this, Player* player, GlobalContext* globalCtx, u8 ruto, u8 adult) {
|
||||||
GetItemID getItemId = GetRandomizedItemId(GI_NONE, this->actor.id, this->actor.params, globalCtx->sceneNum);
|
GetItemID getItemId = Randomizer_GetRandomizedItemId(GI_NONE, this->actor.id, this->actor.params, globalCtx->sceneNum);
|
||||||
|
|
||||||
if (this->actor.parent != NULL && this->actor.parent->id == GET_PLAYER(globalCtx)->actor.id &&
|
if (this->actor.parent != NULL && this->actor.parent->id == GET_PLAYER(globalCtx)->actor.id &&
|
||||||
!Flags_GetTreasure(globalCtx, 0x1F)) {
|
!Flags_GetTreasure(globalCtx, 0x1F)) {
|
||||||
|
@ -127,7 +127,7 @@ void func_809B0558(EnAni* this, GlobalContext* globalCtx) {
|
|||||||
gSaveContext.itemGetInf[1] |= 0x20;
|
gSaveContext.itemGetInf[1] |= 0x20;
|
||||||
} else {
|
} else {
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
s32 getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE);
|
s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE);
|
||||||
func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f);
|
func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f);
|
||||||
} else {
|
} else {
|
||||||
func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f);
|
func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f);
|
||||||
@ -141,7 +141,7 @@ void func_809B05F0(EnAni* this, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
s32 getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE);
|
s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE);
|
||||||
func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f);
|
func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f);
|
||||||
} else {
|
} else {
|
||||||
func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f);
|
func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f);
|
||||||
|
@ -186,14 +186,14 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, GlobalContext* globalCtx) {
|
|||||||
switch (this->prizeIndex) {
|
switch (this->prizeIndex) {
|
||||||
case EXITEM_BOMB_BAG_BOWLING:
|
case EXITEM_BOMB_BAG_BOWLING:
|
||||||
this->getItemId =
|
this->getItemId =
|
||||||
GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20);
|
Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20);
|
||||||
break;
|
break;
|
||||||
case EXITEM_HEART_PIECE_BOWLING:
|
case EXITEM_HEART_PIECE_BOWLING:
|
||||||
this->getItemId =
|
this->getItemId =
|
||||||
GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE);
|
Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE);
|
||||||
break;
|
break;
|
||||||
case EXITEM_BOMBCHUS_BOWLING:
|
case EXITEM_BOMBCHUS_BOWLING:
|
||||||
this->getItemId = GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10);
|
this->getItemId = Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ void EnBox_WaitOpen(EnBox* this, GlobalContext* globalCtx) {
|
|||||||
Flags_SetTreasure(globalCtx, this->dyna.actor.params & 0x1F);
|
Flags_SetTreasure(globalCtx, this->dyna.actor.params & 0x1F);
|
||||||
|
|
||||||
// treasure chest game rando
|
// treasure chest game rando
|
||||||
if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
||||||
if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) {
|
if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) {
|
||||||
if((this->dyna.actor.params & 0xF) < 2) {
|
if((this->dyna.actor.params & 0xF) < 2) {
|
||||||
Flags_SetCollectible(globalCtx, 0x1B);
|
Flags_SetCollectible(globalCtx, 0x1B);
|
||||||
@ -445,10 +445,10 @@ void EnBox_WaitOpen(EnBox* this, GlobalContext* globalCtx) {
|
|||||||
func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos);
|
func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos);
|
||||||
if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f &&
|
if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f &&
|
||||||
Player_IsFacingActor(&this->dyna.actor, 0x3000, globalCtx)) {
|
Player_IsFacingActor(&this->dyna.actor, 0x3000, globalCtx)) {
|
||||||
int32_t item = GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum);
|
int32_t item = Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum);
|
||||||
|
|
||||||
// RANDOTODO treasure chest game rando
|
// RANDOTODO treasure chest game rando
|
||||||
if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
||||||
if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) {
|
if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) {
|
||||||
if((this->dyna.actor.params & 0xF) < 2) {
|
if((this->dyna.actor.params & 0xF) < 2) {
|
||||||
if(Flags_GetCollectible(globalCtx, 0x1B)) {
|
if(Flags_GetCollectible(globalCtx, 0x1B)) {
|
||||||
@ -590,7 +590,7 @@ void EnBox_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (((!gSaveContext.n64ddFlag && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) ||
|
if (((!gSaveContext.n64ddFlag && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) ||
|
||||||
(gSaveContext.n64ddFlag && GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F,
|
(gSaveContext.n64ddFlag && Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F,
|
||||||
this->dyna.actor.id, this->dyna.actor.params,
|
this->dyna.actor.id, this->dyna.actor.params,
|
||||||
globalCtx->sceneNum) == GI_ICE_TRAP)) &&
|
globalCtx->sceneNum) == GI_ICE_TRAP)) &&
|
||||||
this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 &&
|
this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 &&
|
||||||
|
@ -453,7 +453,7 @@ void func_809EEA00(EnDivingGame* this, GlobalContext* globalCtx) {
|
|||||||
if ((this->unk_292 == Message_GetState(&globalCtx->msgCtx) && Message_ShouldAdvance(globalCtx))) {
|
if ((this->unk_292 == Message_GetState(&globalCtx->msgCtx) && Message_ShouldAdvance(globalCtx))) {
|
||||||
Message_CloseTextbox(globalCtx);
|
Message_CloseTextbox(globalCtx);
|
||||||
this->actor.parent = NULL;
|
this->actor.parent = NULL;
|
||||||
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f);
|
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f);
|
||||||
this->actionFunc = func_809EEA90;
|
this->actionFunc = func_809EEA90;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,7 +463,7 @@ void func_809EEA90(EnDivingGame* this, GlobalContext* globalCtx) {
|
|||||||
if (Actor_HasParent(&this->actor, globalCtx)) {
|
if (Actor_HasParent(&this->actor, globalCtx)) {
|
||||||
this->actionFunc = func_809EEAF8;
|
this->actionFunc = func_809EEAF8;
|
||||||
} else {
|
} else {
|
||||||
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f);
|
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ void EnDns_Talk(EnDns* this, GlobalContext* globalCtx) {
|
|||||||
void func_809EFDD0(EnDns* this, GlobalContext* globalCtx) {
|
void func_809EFDD0(EnDns* this, GlobalContext* globalCtx) {
|
||||||
if (this->actor.params == 0x9) {
|
if (this->actor.params == 0x9) {
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
func_8002F434(&this->actor, globalCtx, GetRandomizedItemId(GI_STICK_UPGRADE_30, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f);
|
func_8002F434(&this->actor, globalCtx, Randomizer_GetRandomizedItemId(GI_STICK_UPGRADE_30, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f);
|
||||||
} else if (CUR_UPG_VALUE(UPG_STICKS) < 2) {
|
} else if (CUR_UPG_VALUE(UPG_STICKS) < 2) {
|
||||||
func_8002F434(&this->actor, globalCtx, GI_STICK_UPGRADE_20, 130.0f, 100.0f);
|
func_8002F434(&this->actor, globalCtx, GI_STICK_UPGRADE_20, 130.0f, 100.0f);
|
||||||
} else {
|
} else {
|
||||||
@ -379,14 +379,14 @@ void func_809EFDD0(EnDns* this, GlobalContext* globalCtx) {
|
|||||||
}
|
}
|
||||||
} else if (this->actor.params == 0xA) {
|
} else if (this->actor.params == 0xA) {
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
func_8002F434(&this->actor, globalCtx, GetRandomizedItemId(GI_NUT_UPGRADE_40, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f);
|
func_8002F434(&this->actor, globalCtx, Randomizer_GetRandomizedItemId(GI_NUT_UPGRADE_40, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f);
|
||||||
} else if (CUR_UPG_VALUE(UPG_NUTS) < 2) {
|
} else if (CUR_UPG_VALUE(UPG_NUTS) < 2) {
|
||||||
func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_30, 130.0f, 100.0f);
|
func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_30, 130.0f, 100.0f);
|
||||||
} else {
|
} else {
|
||||||
func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_40, 130.0f, 100.0f);
|
func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_40, 130.0f, 100.0f);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemId(this->dnsItemEntry->getItemId, this->actor.id, this->actor.params, globalCtx->sceneNum) : this->dnsItemEntry->getItemId, 130.0f, 100.0f);
|
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetRandomizedItemId(this->dnsItemEntry->getItemId, this->actor.id, this->actor.params, globalCtx->sceneNum) : this->dnsItemEntry->getItemId, 130.0f, 100.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,13 +139,13 @@ void EnDntDemo_Judge(EnDntDemo* this, GlobalContext* globalCtx) {
|
|||||||
switch (Player_GetMask(globalCtx)) {
|
switch (Player_GetMask(globalCtx)) {
|
||||||
case PLAYER_MASK_SKULL:
|
case PLAYER_MASK_SKULL:
|
||||||
if (!Flags_GetTreasure(globalCtx, 0x1F)) {
|
if (!Flags_GetTreasure(globalCtx, 0x1F)) {
|
||||||
GiveItemWithoutActor(globalCtx, GetRandomizedItemIdFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30));
|
GiveItemWithoutActor(globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30));
|
||||||
Flags_SetTreasure(globalCtx, 0x1F);
|
Flags_SetTreasure(globalCtx, 0x1F);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PLAYER_MASK_TRUTH:
|
case PLAYER_MASK_TRUTH:
|
||||||
if (!Flags_GetTreasure(globalCtx, 0x1E)) {
|
if (!Flags_GetTreasure(globalCtx, 0x1E)) {
|
||||||
GiveItemWithoutActor(globalCtx, GetRandomizedItemIdFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40));
|
GiveItemWithoutActor(globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40));
|
||||||
Flags_SetTreasure(globalCtx, 0x1E);
|
Flags_SetTreasure(globalCtx, 0x1E);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -548,7 +548,7 @@ void func_809FEC70(EnDu* this, GlobalContext* globalCtx) {
|
|||||||
EnDu_SetupAction(this, func_809FECE4);
|
EnDu_SetupAction(this, func_809FECE4);
|
||||||
} else {
|
} else {
|
||||||
f32 xzRange = this->actor.xzDistToPlayer + 1.0f;
|
f32 xzRange = this->actor.xzDistToPlayer + 1.0f;
|
||||||
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET) : GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f);
|
func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET) : GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,8 +138,8 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) {
|
|||||||
case EXITEM_BOMB_BAG_BOWLING:
|
case EXITEM_BOMB_BAG_BOWLING:
|
||||||
this->unk_17C = func_8002EBCC;
|
this->unk_17C = func_8002EBCC;
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
this->giDrawId = GetItemModelFromId(
|
this->giDrawId = Randomizer_GetItemModelFromId(
|
||||||
GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20));
|
Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20));
|
||||||
} else {
|
} else {
|
||||||
this->giDrawId = GID_BOMB_BAG_30;
|
this->giDrawId = GID_BOMB_BAG_30;
|
||||||
}
|
}
|
||||||
@ -173,8 +173,8 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) {
|
|||||||
case EXITEM_BOMBCHUS_BOWLING:
|
case EXITEM_BOMBCHUS_BOWLING:
|
||||||
this->unk_17C = func_8002EBCC;
|
this->unk_17C = func_8002EBCC;
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
this->giDrawId = GetItemModelFromId(
|
this->giDrawId = Randomizer_GetItemModelFromId(
|
||||||
GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10));
|
Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10));
|
||||||
} else {
|
} else {
|
||||||
this->giDrawId = GID_BOMBCHU;
|
this->giDrawId = GID_BOMBCHU;
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) {
|
|||||||
this->scale = 0.5f;
|
this->scale = 0.5f;
|
||||||
this->unkFloat = 0.5f;
|
this->unkFloat = 0.5f;
|
||||||
this->actor.velocity.y = 10.0f;
|
this->actor.velocity.y = 10.0f;
|
||||||
if (!gSaveContext.n64ddFlag || !GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
if (!gSaveContext.n64ddFlag || !Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) {
|
||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case EXITEM_GREEN_RUPEE_CHEST:
|
case EXITEM_GREEN_RUPEE_CHEST:
|
||||||
this->giDrawId = GID_RUPEE_GREEN;
|
this->giDrawId = GID_RUPEE_GREEN;
|
||||||
@ -404,7 +404,7 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, GlobalContext* globalCtx) {
|
|||||||
this->actor.parent = NULL;
|
this->actor.parent = NULL;
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
GET_PLAYER(globalCtx)->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11);
|
GET_PLAYER(globalCtx)->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11);
|
||||||
getItemId = GetRandomizedItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50);
|
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50);
|
||||||
} else {
|
} else {
|
||||||
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
|
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
|
||||||
getItemId = GI_BULLET_BAG_40;
|
getItemId = GI_BULLET_BAG_40;
|
||||||
@ -424,7 +424,7 @@ void EnExItem_TargetPrizeGive(EnExItem* this, GlobalContext* globalCtx) {
|
|||||||
this->actionFunc = EnExItem_TargetPrizeFinish;
|
this->actionFunc = EnExItem_TargetPrizeFinish;
|
||||||
} else {
|
} else {
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
getItemId = GetRandomizedItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50);
|
getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50);
|
||||||
} else {
|
} else {
|
||||||
getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
|
getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
|
||||||
}
|
}
|
||||||
@ -510,12 +510,12 @@ void EnExItem_DrawItems(EnExItem* this, GlobalContext* globalCtx) {
|
|||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case EXITEM_BOMB_BAG_BOWLING:
|
case EXITEM_BOMB_BAG_BOWLING:
|
||||||
case EXITEM_BOMB_BAG_COUNTER:
|
case EXITEM_BOMB_BAG_COUNTER:
|
||||||
randoGetItemId = GetRandomizedItemIdFromKnownCheck(
|
randoGetItemId = Randomizer_GetItemIdFromKnownCheck(
|
||||||
RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20);
|
RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20);
|
||||||
break;
|
break;
|
||||||
case EXITEM_BOMBCHUS_BOWLING:
|
case EXITEM_BOMBCHUS_BOWLING:
|
||||||
case EXITEM_BOMBCHUS_COUNTER:
|
case EXITEM_BOMBCHUS_COUNTER:
|
||||||
randoGetItemId = GetRandomizedItemIdFromKnownCheck(
|
randoGetItemId = Randomizer_GetItemIdFromKnownCheck(
|
||||||
RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10);
|
RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -532,12 +532,12 @@ void EnExItem_DrawHeartPiece(EnExItem* this, GlobalContext* globalCtx) {
|
|||||||
func_8002ED80(&this->actor, globalCtx, 0);
|
func_8002ED80(&this->actor, globalCtx, 0);
|
||||||
|
|
||||||
if (gSaveContext.n64ddFlag) {
|
if (gSaveContext.n64ddFlag) {
|
||||||
s32 randoGetItemId = GetRandomizedItemIdFromKnownCheck(
|
s32 randoGetItemId = Randomizer_GetItemIdFromKnownCheck(
|
||||||
RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE);
|
RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE);
|
||||||
if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) {
|
if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) {
|
||||||
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId);
|
EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId);
|
||||||
}
|
}
|
||||||
GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId));
|
GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId));
|
||||||
} else {
|
} else {
|
||||||
GetItem_Draw(globalCtx, GID_HEART_PIECE);
|
GetItem_Draw(globalCtx, GID_HEART_PIECE);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user