mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-10 11:35:19 -05:00
Merge pull request #1007 from briaguya-ai/zhora-to-rnext-merge
zhora -> rando-next
This commit is contained in:
commit
8aa20e1732
7
.gitignore
vendored
7
.gitignore
vendored
@ -407,6 +407,13 @@ oot.otr
|
||||
shipofharkinian.ini
|
||||
shipofharkinian.json
|
||||
|
||||
# Switch Stuff
|
||||
|
||||
*.nro
|
||||
*.nacp
|
||||
ZAPDTR/ZAPDUtils/lib/*
|
||||
!/soh/icon.jpg
|
||||
|
||||
# Xcode
|
||||
xcuserdata/
|
||||
*.xcconfig
|
||||
|
@ -32,13 +32,6 @@ sudo docker run --rm -it -v $(pwd):/soh soh /bin/bash
|
||||
```
|
||||
Inside the Docker container:
|
||||
```bash
|
||||
# Clone and build StormLib
|
||||
git clone https://github.com/ladislav-zezula/StormLib external/StormLib
|
||||
cmake -B external/StormLib/build -S external/StormLib
|
||||
cmake --build external/StormLib/build
|
||||
cp external/StormLib/build/libstorm.a external
|
||||
cp /usr/local/lib/libGLEW.a external
|
||||
|
||||
cd soh
|
||||
# Extract the assets/Compile the exporter/Run the exporter
|
||||
make setup -j$(nproc) OPTFLAGS=-O2 DEBUG=0
|
||||
|
39
Dockerfile
39
Dockerfile
@ -3,31 +3,29 @@ FROM ubuntu:20.04 as build
|
||||
ENV LANG C.UTF-8
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV GCCVER=10
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get install -y \
|
||||
binutils \
|
||||
gcc-10 \
|
||||
g++-10 \
|
||||
patchelf \
|
||||
gcc-${GCCVER} \
|
||||
g++-${GCCVER} \
|
||||
p7zip-full \
|
||||
python3.9 \
|
||||
python3 \
|
||||
make \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
lld \
|
||||
wget \
|
||||
libglew-dev \
|
||||
libsdl2-dev \
|
||||
zlib1g-dev \
|
||||
libbz2-dev \
|
||||
libpng-dev \
|
||||
libgles2-mesa-dev && \
|
||||
ln -s /usr/bin/g++-10 /usr/bin/g++ && \
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10 && \
|
||||
gcc --version && \
|
||||
g++ --version
|
||||
|
||||
RUN apt-get clean autoclean && apt-get autoremove --yes && rm -rf /var/lib/apt /var/lib/cache /var/lib/log
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCCVER} 10 && \
|
||||
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCCVER} 10
|
||||
|
||||
RUN git clone https://github.com/Perlmint/glew-cmake.git && \
|
||||
cmake glew-cmake && \
|
||||
@ -38,10 +36,23 @@ ENV SDL2VER=2.0.22
|
||||
RUN curl -sLO https://libsdl.org/release/SDL2-${SDL2VER}.tar.gz && \
|
||||
tar -xzf SDL2-${SDL2VER}.tar.gz && \
|
||||
cd SDL2-${SDL2VER} && \
|
||||
./configure --prefix=/usr && \
|
||||
make && make install && \
|
||||
rm ../SDL2-${SDL2VER}.tar.gz && \
|
||||
cp -av /lib/libSDL* /lib/x86_64-linux-gnu/
|
||||
./configure --build=x86_64-linux-gnu && \
|
||||
make -j$(nproc) && make install && \
|
||||
rm ../SDL2-${SDL2VER}.tar.gz
|
||||
|
||||
RUN \
|
||||
ln -sf /proc/self/mounts /etc/mtab && \
|
||||
mkdir -p /usr/local/share/keyring/ && \
|
||||
wget -O /usr/local/share/keyring/devkitpro-pub.gpg https://apt.devkitpro.org/devkitpro-pub.gpg && \
|
||||
echo "deb [signed-by=/usr/local/share/keyring/devkitpro-pub.gpg] https://apt.devkitpro.org stable main" > /etc/apt/sources.list.d/devkitpro.list && \
|
||||
apt-get update -y && \
|
||||
apt-get install -y devkitpro-pacman && \
|
||||
yes | dkp-pacman -Syu switch-dev switch-portlibs --noconfirm
|
||||
|
||||
ENV DEVKITPRO=/opt/devkitpro
|
||||
ENV DEVKITARM=/opt/devkitpro/devkitARM
|
||||
ENV DEVKITPPC=/opt/devkitpro/devkitPPC
|
||||
ENV PATH=$PATH:/opt/devkitpro/portlibs/switch/bin/
|
||||
|
||||
RUN mkdir /soh
|
||||
WORKDIR /soh
|
||||
|
51
Jenkinsfile
vendored
51
Jenkinsfile
vendored
@ -97,8 +97,7 @@ pipeline {
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
docker build . -t soh
|
||||
docker run --name sohcont -dit --rm -v $(pwd):/soh soh /bin/bash
|
||||
cp ../../buildsoh.bash soh
|
||||
docker exec sohcont soh/buildsoh.bash
|
||||
docker exec sohcont scripts/linux/build.sh
|
||||
|
||||
mkdir build
|
||||
mv soh/soh.elf build/
|
||||
@ -107,7 +106,7 @@ pipeline {
|
||||
mv ZAPDTR/ZAPD.out build/assets/extractor/
|
||||
mv README.md readme.txt
|
||||
|
||||
docker exec sohcont appimage/appimage.sh
|
||||
docker exec sohcont scripts/linux/build-appimage.sh
|
||||
|
||||
7z a soh-linux.7z SOH-Linux.AppImage readme.txt
|
||||
|
||||
@ -143,9 +142,9 @@ pipeline {
|
||||
sh '''
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
cd soh
|
||||
make setup -j4 OPTFLAGS=-O2 DEBUG=0 LD="ld"
|
||||
make -j4 DEBUG=0 OPTFLAGS=-O2 LD="ld"
|
||||
make -j4 appbundle
|
||||
make setup -j$(sysctl -n hw.physicalcpu) OPTFLAGS=-O2 DEBUG=0 LD="ld"
|
||||
make -j$(sysctl -n hw.physicalcpu) DEBUG=0 OPTFLAGS=-O2 LD="ld"
|
||||
make appbundle
|
||||
mv ../README.md readme.txt
|
||||
7z a soh-mac.7z soh.app readme.txt
|
||||
'''
|
||||
@ -158,7 +157,47 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Build Switch') {
|
||||
options {
|
||||
timeout(time: 20)
|
||||
}
|
||||
agent {
|
||||
label "SoH-Linux-Builders"
|
||||
}
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
sh '''
|
||||
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
docker build . -t sohswitch
|
||||
docker run --name sohcont -dit --rm -v $(pwd):/soh sohswitch /bin/bash
|
||||
docker exec sohcont scripts/switch/build.sh
|
||||
|
||||
mv soh/soh.nro .
|
||||
mv README.md readme.txt
|
||||
|
||||
7z a soh-switch.7z soh.nro readme.txt
|
||||
|
||||
'''
|
||||
}
|
||||
sh 'sudo docker container stop sohcont'
|
||||
archiveArtifacts artifacts: 'soh-switch.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
36
Makefile.switch
Normal file
36
Makefile.switch
Normal file
@ -0,0 +1,36 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
export SOH_TOP_DIR := $(CURDIR)
|
||||
|
||||
.PHONY: all clean ZAPDUtils libultraship soh StormLib
|
||||
|
||||
all: soh
|
||||
@echo "Done!"
|
||||
|
||||
ZAPDUtils:
|
||||
@echo "Building $@..."
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ZAPDTR/ZAPDUtils -f $(CURDIR)/ZAPDTR/ZAPDUtils/Makefile.switch
|
||||
|
||||
StormLib:
|
||||
@echo "Building $@..."
|
||||
LDFLAGS="" ${DEVKITPRO}/portlibs/switch/bin/aarch64-none-elf-cmake -DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/Switch.cmake -DCMAKE_BUILD_TYPE=Release -B $(CURDIR)/StormLib/nxbuild -S $(CURDIR)/StormLib
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/StormLib/nxbuild -f $(CURDIR)/StormLib/nxbuild/Makefile
|
||||
|
||||
libultraship: StormLib ZAPDUtils
|
||||
@echo "Building $@..."
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/libultraship -f $(CURDIR)/libultraship/Makefile.switch
|
||||
|
||||
soh: libultraship
|
||||
@echo "Building $@..."
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/soh -f $(CURDIR)/soh/Makefile.switch
|
||||
|
||||
otr:
|
||||
@echo "Building $@..."
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/soh -f $(CURDIR)/soh/Makefile setup
|
||||
|
||||
clean:
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ZAPDTR/ZAPDUtils -f $(CURDIR)/ZAPDTR/ZAPDUtils/Makefile.switch clean
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/libultraship -f $(CURDIR)/libultraship/Makefile.switch clean
|
||||
@$(MAKE) --no-print-directory -C $(CURDIR)/soh -f $(CURDIR)/soh/Makefile.switch clean
|
@ -3,7 +3,7 @@
|
||||
|
||||
void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType, Ship::Version resVersion)
|
||||
{
|
||||
writer->Write((uint8_t)Endianess::Little); // 0x00
|
||||
writer->Write((uint8_t)Endianness::Little); // 0x00
|
||||
writer->Write((uint8_t)0); // 0x01
|
||||
writer->Write((uint8_t)0); // 0x02
|
||||
writer->Write((uint8_t)0); // 0x03
|
||||
|
@ -65,12 +65,6 @@
|
||||
<ClCompile Include="VersionInfo.cpp" />
|
||||
<ClCompile Include="VtxExporter.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OTRGui\build\ZERO_CHECK.vcxproj">
|
||||
<Project>{02d10590-9542-3f55-aaf8-6055677e2a2a}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
|
@ -83,7 +83,7 @@ Refer to the [building instructions](BUILDING.md) to compile SoH.
|
||||
- Confirm that `zapd.exe` exists in the `/assets/extractor` folder
|
||||
|
||||
## Nightly Builds
|
||||
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/job/SoH_Multibranch/job/develop)
|
||||
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/)
|
||||
|
||||
|
||||
## The Harbour Masters Are...
|
||||
|
1
StormLib/.gitignore
vendored
1
StormLib/.gitignore
vendored
@ -140,6 +140,7 @@ Desktop.ini
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
nxbuild
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
|
@ -323,6 +323,11 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DO_LARGEFILE=0 -Dstat64=stat -Dlstat64=lstat -Dlseek64=lseek -Doff64_t=off_t -Dfstat64=fstat -Dftruncate64=ftruncate")
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
||||
# Enable POSIX extensions such as `readlink` and `ftruncate`.
|
||||
add_definitions(-D_POSIX_C_SOURCE=200809L)
|
||||
endif()
|
||||
|
||||
add_library(${LIBRARY_NAME} ${LIB_TYPE} ${SRC_FILES} ${SRC_ADDITIONAL_FILES} ${STORM_DEF_FILES})
|
||||
if(WIN32)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES OUTPUT_NAME "StormLib")
|
||||
|
@ -48,11 +48,15 @@ endif
|
||||
LDFLAGS := -Llib/libgfxd -L../libultraship -L../StormLib/build \
|
||||
-pthread -lgfxd -lultraship ZAPDUtils/ZAPDUtils.a -lstorm -lbz2 -lm -ldl
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation
|
||||
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs)
|
||||
INC += $(shell pkg-config --cflags libpng)
|
||||
else
|
||||
LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
LDFLAGS += -framework OpenGL -framework Foundation
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Linux)
|
||||
LDFLAGS += $(shell pkg-config --libs x11 libpulse)
|
||||
endif
|
||||
|
||||
# Use LLD if available. Set LLD=0 to not use it
|
||||
@ -65,10 +69,12 @@ ifneq ($(LLD),0)
|
||||
endif
|
||||
|
||||
UNAMEM := $(shell uname -m)
|
||||
ifneq ($(UNAME), Darwin)
|
||||
ifeq ($(UNAME), Linux)
|
||||
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
|
||||
EXPORTERS := -Wl,--whole-archive ../OTRExporter/OTRExporter/OTRExporter.a -Wl,--no-whole-archive
|
||||
else
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
EXPORTERS := -Wl,-force_load ../OTRExporter/OTRExporter/OTRExporter.a
|
||||
endif
|
||||
|
||||
|
@ -359,12 +359,6 @@
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OTRGui\build\ZERO_CHECK.vcxproj">
|
||||
<Project>{02d10590-9542-3f55-aaf8-6055677e2a2a}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
|
||||
|
171
ZAPDTR/ZAPDUtils/Makefile.switch
Normal file
171
ZAPDTR/ZAPDUtils/Makefile.switch
Normal file
@ -0,0 +1,171 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
||||
#
|
||||
# NO_ICON: if set to anything, do not use icon.
|
||||
# NO_NACP: if set to anything, no .nacp file is generated.
|
||||
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
|
||||
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
|
||||
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
|
||||
# ICON is the filename of the icon (.jpg), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.jpg
|
||||
# - icon.jpg
|
||||
# - <libnx folder>/default_icon.jpg
|
||||
#
|
||||
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.json
|
||||
# - config.json
|
||||
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
|
||||
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
|
||||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := ZAPDUtils
|
||||
BUILD := build
|
||||
SOURCES := Utils
|
||||
DATA :=
|
||||
INCLUDES :=
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# source files
|
||||
#-------------------------------------------------------------------------------
|
||||
SOURCEFILES_C :=
|
||||
|
||||
SOURCEFILES_CPP :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fexceptions -std=gnu++20
|
||||
CFLAGS += -std=gnu11
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/lib/lib$(TARGET).a
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||
$(foreach sf,$(SOURCEFILES_C),$(CURDIR)/$(dir $(sf))) \
|
||||
$(foreach sf,$(SOURCEFILES_CPP),$(CURDIR)/$(dir $(sf)))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) \
|
||||
$(foreach f,$(SOURCEFILES_C),$(notdir $(f)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) \
|
||||
$(foreach f,$(SOURCEFILES_CPP),$(notdir $(f)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
lib:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
$(BUILD) : lib
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.switch
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -rf build lib
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
$(OUTPUT) : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES)
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
@ -18,6 +18,16 @@ void BinaryReader::Close()
|
||||
stream->Close();
|
||||
}
|
||||
|
||||
void BinaryReader::SetEndianness(Endianness endianness)
|
||||
{
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
Endianness BinaryReader::GetEndianness() const
|
||||
{
|
||||
return endianness;
|
||||
}
|
||||
|
||||
void BinaryReader::Seek(uint32_t offset, SeekOffsetType seekType)
|
||||
{
|
||||
stream->Seek(offset, seekType);
|
||||
@ -28,11 +38,16 @@ uint32_t BinaryReader::GetBaseAddress()
|
||||
return stream->GetBaseAddress();
|
||||
}
|
||||
|
||||
void BinaryReader::Read([[maybe_unused]] char* buffer, int32_t length)
|
||||
void BinaryReader::Read(int32_t length)
|
||||
{
|
||||
stream->Read(length);
|
||||
}
|
||||
|
||||
void BinaryReader::Read(char* buffer, int32_t length)
|
||||
{
|
||||
stream->Read(buffer, length);
|
||||
}
|
||||
|
||||
char BinaryReader::ReadChar()
|
||||
{
|
||||
return (char)stream->ReadByte();
|
||||
@ -53,6 +68,10 @@ int16_t BinaryReader::ReadInt16()
|
||||
int16_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(int16_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP16(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -61,6 +80,10 @@ int32_t BinaryReader::ReadInt32()
|
||||
int32_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(int32_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP32(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -69,6 +92,10 @@ uint16_t BinaryReader::ReadUInt16()
|
||||
uint16_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint16_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP16(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -77,6 +104,10 @@ uint32_t BinaryReader::ReadUInt32()
|
||||
uint32_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint32_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP32(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -85,6 +116,10 @@ uint64_t BinaryReader::ReadUInt64()
|
||||
uint64_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint64_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP64(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -94,6 +129,9 @@ float BinaryReader::ReadSingle()
|
||||
|
||||
stream->Read((char*)&result, sizeof(float));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BitConverter::ToFloatBE((uint8_t*)&result, 0);
|
||||
|
||||
if (std::isnan(result))
|
||||
throw std::runtime_error("BinaryReader::ReadSingle(): Error reading stream");
|
||||
|
||||
@ -105,6 +143,10 @@ double BinaryReader::ReadDouble()
|
||||
double result = NAN;
|
||||
|
||||
stream->Read((char*)&result, sizeof(double));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BitConverter::ToDoubleBE((uint8_t*)&result, 0);
|
||||
|
||||
if (std::isnan(result))
|
||||
throw std::runtime_error("BinaryReader::ReadDouble(): Error reading stream");
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "../Vec2f.h"
|
||||
#include "../Vec3f.h"
|
||||
#include "../Vec3s.h"
|
||||
#include "BitConverter.h"
|
||||
#include "Stream.h"
|
||||
|
||||
class BinaryReader
|
||||
@ -18,9 +19,13 @@ public:
|
||||
|
||||
void Close();
|
||||
|
||||
void SetEndianness(Endianness endianness);
|
||||
Endianness GetEndianness() const;
|
||||
|
||||
void Seek(uint32_t offset, SeekOffsetType seekType);
|
||||
uint32_t GetBaseAddress();
|
||||
|
||||
void Read(int32_t length);
|
||||
void Read(char* buffer, int32_t length);
|
||||
char ReadChar();
|
||||
int8_t ReadByte();
|
||||
@ -41,4 +46,5 @@ public:
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Stream> stream;
|
||||
Endianness endianness = Endianness::Native;
|
||||
};
|
@ -10,6 +10,11 @@ BinaryWriter::BinaryWriter(std::shared_ptr<Stream> nStream)
|
||||
stream = nStream;
|
||||
}
|
||||
|
||||
void BinaryWriter::SetEndianness(Endianness endianness)
|
||||
{
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
void BinaryWriter::Close()
|
||||
{
|
||||
stream->Close();
|
||||
@ -47,16 +52,25 @@ void BinaryWriter::Write(uint8_t value)
|
||||
|
||||
void BinaryWriter::Write(int16_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP16(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint16_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP16(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int32_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP32(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int32_t));
|
||||
}
|
||||
|
||||
@ -68,33 +82,48 @@ void BinaryWriter::Write(int32_t valueA, int32_t valueB)
|
||||
|
||||
void BinaryWriter::Write(uint32_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP32(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int64_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP64(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int64_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint64_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP64(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(float value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BitConverter::ToFloatBE((uint8_t*)&value, 0);
|
||||
|
||||
stream->Write((char*)&value, sizeof(float));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(double value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BitConverter::ToDoubleBE((uint8_t*)&value, 0);
|
||||
|
||||
stream->Write((char*)&value, sizeof(double));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(const std::string& str)
|
||||
{
|
||||
int strLen = str.size();
|
||||
stream->Write((char*)&strLen, sizeof(int));
|
||||
Write(strLen);
|
||||
|
||||
for (char c : str)
|
||||
stream->WriteByte(c);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "BitConverter.h"
|
||||
#include "Stream.h"
|
||||
|
||||
class BinaryWriter
|
||||
@ -12,6 +13,8 @@ public:
|
||||
BinaryWriter(Stream* nStream);
|
||||
BinaryWriter(std::shared_ptr<Stream> nStream);
|
||||
|
||||
void SetEndianness(Endianness endianness);
|
||||
|
||||
std::shared_ptr<Stream> GetStream();
|
||||
uint64_t GetBaseAddress();
|
||||
uint64_t GetLength();
|
||||
@ -34,4 +37,5 @@ public:
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Stream> stream;
|
||||
Endianness endianness = Endianness::Native;
|
||||
};
|
@ -5,6 +5,28 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define BSWAP16 _byteswap_ushort
|
||||
#define BSWAP32 _byteswap_ulong
|
||||
#define BSWAP64 _byteswap_uint64
|
||||
#else
|
||||
#define BSWAP16 __builtin_bswap16
|
||||
#define BSWAP32 __builtin_bswap32
|
||||
#define BSWAP64 __builtin_bswap64
|
||||
#endif
|
||||
|
||||
enum class Endianness
|
||||
{
|
||||
Little = 0,
|
||||
Big = 1,
|
||||
|
||||
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
|
||||
Native = Big,
|
||||
#else
|
||||
Native = Little,
|
||||
#endif
|
||||
};
|
||||
|
||||
class BitConverter
|
||||
{
|
||||
public:
|
||||
|
@ -10,13 +10,6 @@ enum class SeekOffsetType
|
||||
End
|
||||
};
|
||||
|
||||
// TODO: Eventually account for endianess in binaryreader and binarywriter
|
||||
enum class Endianess
|
||||
{
|
||||
Little = 0,
|
||||
Big = 1,
|
||||
};
|
||||
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
|
@ -9,22 +9,18 @@
|
||||
|
||||
std::vector<std::string> StringHelper::Split(std::string s, const std::string& delimiter)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
size_t pos = 0;
|
||||
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
|
||||
std::string token;
|
||||
std::vector<std::string> res;
|
||||
|
||||
while ((pos = s.find(delimiter)) != std::string::npos)
|
||||
{
|
||||
token = s.substr(0, pos);
|
||||
result.push_back(token);
|
||||
s.erase(0, pos + delimiter.length());
|
||||
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
|
||||
token = s.substr(pos_start, pos_end - pos_start);
|
||||
pos_start = pos_end + delim_len;
|
||||
res.push_back(token);
|
||||
}
|
||||
|
||||
if (s.length() != 0)
|
||||
result.push_back(s);
|
||||
|
||||
return result;
|
||||
res.push_back(s.substr(pos_start));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string StringHelper::Strip(std::string s, const std::string& delimiter)
|
||||
|
@ -186,12 +186,6 @@
|
||||
<ClCompile Include="Utils\MemoryStream.cpp" />
|
||||
<ClCompile Include="Utils\StringHelper.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OTRGui\build\ZERO_CHECK.vcxproj">
|
||||
<Project>{02d10590-9542-3f55-aaf8-6055677e2a2a}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -9,6 +9,7 @@ UNAME := $(shell uname)
|
||||
ASAN ?= 0
|
||||
DEBUG ?= 1
|
||||
OPTFLAGS ?= -O0
|
||||
X11 ?= 0
|
||||
LTO ?= 0
|
||||
|
||||
# flag to save whether the compiler being used is clang or gcc by checking CXX --version
|
||||
@ -28,7 +29,6 @@ WARN := -Wall -Wextra -Werror \
|
||||
-Wno-narrowing \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wno-error=multichar \
|
||||
-Wno-unused-command-line-argument \
|
||||
-Wno-delete-non-abstract-non-virtual-dtor \
|
||||
-Wno-unused-private-field \
|
||||
-Wno-deprecated-copy-with-user-provided-copy \
|
||||
@ -45,10 +45,15 @@ endif
|
||||
|
||||
CXXFLAGS := $(WARN) $(CXXWARN) -std=c++20 -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 $(shell pkg-config --cflags sdl2 glew)
|
||||
|
||||
MMFLAGS := -Wno-deprecated-declarations -ObjC++ -fobjc-weak -fobjc-arc
|
||||
|
||||
ifeq ($(X11), 1)
|
||||
CXXFLAGS += -DX11_SUPPORTED
|
||||
CFLAGS += -DX11_SUPPORTED
|
||||
endif
|
||||
|
||||
# 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)
|
||||
@ -56,10 +61,6 @@ ifneq ($(CXX_IS_CLANG),1)
|
||||
MMFLAGS += -stdlib++-isystem ${STD_ISYSTEM} -cxx-isystem ${CXX_ISYSTEM}
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin) #APPLE
|
||||
CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL -framework Foundation
|
||||
endif
|
||||
|
||||
ifneq ($(DEBUG),0)
|
||||
CXXFLAGS += -g -D_DEBUG
|
||||
CFLAGS += -g -D_DEBUG
|
||||
|
192
libultraship/Makefile.switch
Normal file
192
libultraship/Makefile.switch
Normal file
@ -0,0 +1,192 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
||||
#
|
||||
# NO_ICON: if set to anything, do not use icon.
|
||||
# NO_NACP: if set to anything, no .nacp file is generated.
|
||||
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
|
||||
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
|
||||
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
|
||||
# ICON is the filename of the icon (.jpg), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.jpg
|
||||
# - icon.jpg
|
||||
# - <libnx folder>/default_icon.jpg
|
||||
#
|
||||
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.json
|
||||
# - config.json
|
||||
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
|
||||
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
|
||||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := ultraship
|
||||
BUILD := build
|
||||
SOURCES := \
|
||||
libultraship/Factories \
|
||||
libultraship/Lib/Fast3D \
|
||||
libultraship/Lib/ImGui \
|
||||
libultraship/Lib/Mercury \
|
||||
libultraship
|
||||
DATA :=
|
||||
INCLUDES := \
|
||||
../ZAPDTR/ZAPDUtils \
|
||||
../StormLib/src \
|
||||
libultraship/Lib/Fast3D/U64 \
|
||||
libultraship/Lib/ImGui \
|
||||
libultraship/Lib/spdlog \
|
||||
libultraship/Lib/spdlog/include \
|
||||
libultraship
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# source files
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
SOURCEFILES_C := \
|
||||
libultraship/mixer.c \
|
||||
libultraship/Lib/stb/stb_impl.c \
|
||||
|
||||
SOURCEFILES_CPP := \
|
||||
libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \
|
||||
libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \
|
||||
libultraship/Lib/StrHash64.cpp \
|
||||
libultraship/Lib/tinyxml2/tinyxml2.cpp
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE -ffast-math -O3
|
||||
|
||||
CFLAGS := -Wall -ffunction-sections \
|
||||
$(ARCH) $(DEFINES) \
|
||||
-DSPDLOG_NO_THREAD_ID \
|
||||
-DSTBI_NO_THREAD_LOCALS
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DENABLE_OPENGL
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++20
|
||||
CFLAGS += -std=gnu11
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/lib/lib$(TARGET).a
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||
$(foreach sf,$(SOURCEFILES_C),$(CURDIR)/$(dir $(sf))) \
|
||||
$(foreach sf,$(SOURCEFILES_CPP),$(CURDIR)/$(dir $(sf)))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) \
|
||||
$(foreach f,$(SOURCEFILES_C),$(notdir $(f)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) \
|
||||
$(foreach f,$(SOURCEFILES_CPP),$(notdir $(f)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
lib:
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
$(BUILD) : lib
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.switch
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -rf build lib
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
$(OUTPUT) : $(OFILES)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES)
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
@ -6,6 +6,10 @@
|
||||
#include "Lib/StrHash64.h"
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include "SwitchImpl.h"
|
||||
#endif
|
||||
|
||||
namespace Ship {
|
||||
Archive::Archive(const std::string& MainPath, bool enableWriting) : Archive(MainPath, "", enableWriting)
|
||||
{
|
||||
@ -68,7 +72,7 @@ namespace Ship {
|
||||
//}
|
||||
|
||||
if (!attempt) {
|
||||
printf("({%i}) Failed to open file {%s} from mpq archive {%s}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||
SPDLOG_ERROR("({}) Failed to open file {} from mpq archive {}.", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||
FileToLoad->bHasLoadError = true;
|
||||
return FileToLoad;
|
||||
@ -327,13 +331,21 @@ namespace Ship {
|
||||
#ifdef _WIN32
|
||||
std::wstring wfullPath = std::filesystem::absolute(MainPath).wstring();
|
||||
#endif
|
||||
#if defined(__SWITCH__)
|
||||
std::string fullPath = MainPath;
|
||||
#else
|
||||
std::string fullPath = std::filesystem::absolute(MainPath).string();
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!SFileOpenArchive(wfullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
|
||||
#else
|
||||
if (!SFileOpenArchive(fullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
Switch::ThrowMissingOTR(fullPath);
|
||||
#endif
|
||||
SPDLOG_ERROR("({}) Failed to open main mpq file {}.", GetLastError(), fullPath.c_str());
|
||||
return false;
|
||||
}
|
||||
@ -362,7 +374,11 @@ namespace Ship {
|
||||
|
||||
bool Archive::LoadPatchMPQ(const std::string& path) {
|
||||
HANDLE patchHandle = NULL;
|
||||
#if defined(__SWITCH__)
|
||||
std::string fullPath = path;
|
||||
#else
|
||||
std::string fullPath = std::filesystem::absolute(path).string();
|
||||
#endif
|
||||
if (mpqHandles.contains(fullPath)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -98,20 +98,14 @@ void Console::Update() {
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" uint8_t __enableGameInput;
|
||||
|
||||
void Console::Draw() {
|
||||
bool input_focus = false;
|
||||
__enableGameInput = true;
|
||||
if (!this->opened) return;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
const ImVec2 pos = ImGui::GetWindowPos();
|
||||
const ImVec2 size = ImGui::GetWindowSize();
|
||||
|
||||
__enableGameInput = !ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows);
|
||||
|
||||
// SohImGui::ShowCursor(ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows | ImGuiHoveredFlags_RectOnly), SohImGui::Dialogues::dConsole);
|
||||
|
||||
// Renders autocomplete window
|
||||
@ -230,8 +224,8 @@ void Console::Draw() {
|
||||
// Renders input textfield
|
||||
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
|
||||
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
|
||||
ImGui::PushItemWidth(-1);
|
||||
if(ImGui::InputTextWithHint("CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
|
||||
ImGui::PushItemWidth(-53);
|
||||
if(ImGui::InputTextWithHint("##CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
|
||||
input_focus = true;
|
||||
if(this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ')
|
||||
this->Dispatch(std::string(this->InputBuffer));
|
||||
@ -250,6 +244,13 @@ void Console::Draw() {
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 50);
|
||||
if(ImGui::Button("Submit") && !input_focus && this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' '){
|
||||
this->Dispatch(std::string(this->InputBuffer));
|
||||
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
ImGui::SetItemDefaultFocus();
|
||||
if (input_focus) ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::PopItemWidth();
|
||||
|
@ -1,5 +1,103 @@
|
||||
#include "Cutscene.h"
|
||||
|
||||
enum class CutsceneCommands
|
||||
{
|
||||
Cmd00 = 0x0000,
|
||||
SetCameraPos = 0x0001,
|
||||
SetCameraFocus = 0x0002,
|
||||
SpecialAction = 0x0003,
|
||||
SetLighting = 0x0004,
|
||||
SetCameraPosLink = 0x0005,
|
||||
SetCameraFocusLink = 0x0006,
|
||||
Cmd07 = 0x0007,
|
||||
Cmd08 = 0x0008,
|
||||
Cmd09 = 0x0009,
|
||||
Unknown = 0x001A,
|
||||
Textbox = 0x0013,
|
||||
SetActorAction0 = 0x000A,
|
||||
SetActorAction1 = 0x000F,
|
||||
SetActorAction2 = 0x000E,
|
||||
SetActorAction3 = 0x0019,
|
||||
SetActorAction4 = 0x001D,
|
||||
SetActorAction5 = 0x001E,
|
||||
SetActorAction6 = 0x002C,
|
||||
SetActorAction7 = 0x001F,
|
||||
SetActorAction8 = 0x0031,
|
||||
SetActorAction9 = 0x003E,
|
||||
SetActorAction10 = 0x008F,
|
||||
SetSceneTransFX = 0x002D,
|
||||
Nop = 0x000B,
|
||||
PlayBGM = 0x0056,
|
||||
StopBGM = 0x0057,
|
||||
FadeBGM = 0x007C,
|
||||
SetTime = 0x008C,
|
||||
Terminator = 0x03E8,
|
||||
End = 0xFFFF,
|
||||
Error = 0xFEAF,
|
||||
};
|
||||
|
||||
static inline uint32_t read_CMD_BBBB(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_BBH(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half word to match endianness
|
||||
if (reader->GetEndianness() != Endianness::Native)
|
||||
{
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[2];
|
||||
b[2] = b[3];
|
||||
b[3] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_HBB(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half word to match endianness
|
||||
if (reader->GetEndianness() != Endianness::Native)
|
||||
{
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_HH(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half words to match endianness
|
||||
if (reader->GetEndianness() != Endianness::Native)
|
||||
{
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = tmp;
|
||||
tmp = b[2];
|
||||
b[2] = b[3];
|
||||
b[3] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res)
|
||||
{
|
||||
Cutscene* cs = (Cutscene*)res;
|
||||
@ -9,11 +107,415 @@ void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res)
|
||||
uint32_t numEntries = reader->ReadUInt32();
|
||||
cs->commands.reserve(numEntries);
|
||||
|
||||
for (uint32_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
uint32_t data = reader->ReadUInt32();
|
||||
uint16_t opcode = data >> 16;
|
||||
uint32_t numCommands = reader->ReadUInt32();
|
||||
cs->commands.push_back(numCommands);
|
||||
|
||||
cs->commands.push_back(data);
|
||||
// endFrame
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t commandId = reader->ReadUInt32();
|
||||
cs->commands.push_back(commandId);
|
||||
|
||||
switch (commandId)
|
||||
{
|
||||
case (uint32_t)CutsceneCommands::SetCameraPos:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (uint32_t)CutsceneCommands::SetCameraFocus:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SpecialAction:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetLighting:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetCameraPosLink:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetCameraFocusLink:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::Cmd09:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HBB(reader));
|
||||
cs->commands.push_back(read_CMD_BBH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x15:
|
||||
case (uint32_t)CutsceneCommands::Unknown:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (uint32_t)CutsceneCommands::Textbox:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetActorAction0:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction1:
|
||||
case 17:
|
||||
case 18:
|
||||
case 23:
|
||||
case 34:
|
||||
case 39:
|
||||
case 46:
|
||||
case 76:
|
||||
case 85:
|
||||
case 93:
|
||||
case 105:
|
||||
case 107:
|
||||
case 110:
|
||||
case 119:
|
||||
case 123:
|
||||
case 138:
|
||||
case 139:
|
||||
case 144:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction2:
|
||||
case 16:
|
||||
case 24:
|
||||
case 35:
|
||||
case 40:
|
||||
case 48:
|
||||
case 64:
|
||||
case 68:
|
||||
case 70:
|
||||
case 78:
|
||||
case 80:
|
||||
case 94:
|
||||
case 116:
|
||||
case 118:
|
||||
case 120:
|
||||
case 125:
|
||||
case 131:
|
||||
case 141:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction3:
|
||||
case 36:
|
||||
case 41:
|
||||
case 50:
|
||||
case 67:
|
||||
case 69:
|
||||
case 72:
|
||||
case 74:
|
||||
case 81:
|
||||
case 106:
|
||||
case 117:
|
||||
case 121:
|
||||
case 126:
|
||||
case 132:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction4:
|
||||
case 37:
|
||||
case 42:
|
||||
case 51:
|
||||
case 53:
|
||||
case 63:
|
||||
case 65:
|
||||
case 66:
|
||||
case 75:
|
||||
case 82:
|
||||
case 108:
|
||||
case 127:
|
||||
case 133:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction5:
|
||||
case 38:
|
||||
case 43:
|
||||
case 47:
|
||||
case 54:
|
||||
case 79:
|
||||
case 83:
|
||||
case 128:
|
||||
case 135:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction6:
|
||||
case 55:
|
||||
case 77:
|
||||
case 84:
|
||||
case 90:
|
||||
case 129:
|
||||
case 136:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction7:
|
||||
case 52:
|
||||
case 57:
|
||||
case 58:
|
||||
case 88:
|
||||
case 115:
|
||||
case 130:
|
||||
case 137:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction8:
|
||||
case 60:
|
||||
case 89:
|
||||
case 111:
|
||||
case 114:
|
||||
case 134:
|
||||
case 142:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction9:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction10:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetSceneTransFX:
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::PlayBGM:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::StopBGM:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::FadeBGM:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetTime:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HBB(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::Terminator:
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
break;
|
||||
}
|
||||
case 0xFFFFFFFF: // CS_END
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
return;
|
||||
}
|
||||
default:
|
||||
#ifdef _DEBUG
|
||||
printf("CutsceneV0: Unknown command %x\n", commandId);
|
||||
#endif
|
||||
// error?
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,16 @@
|
||||
|
||||
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||
|
||||
extern "C" CVar* CVar_Get(const char* name) {
|
||||
CVar* CVar_Get(const char* name) {
|
||||
auto it = cvars.find(name);
|
||||
return (it != cvars.end()) ? it->second.get() : nullptr;
|
||||
}
|
||||
|
||||
extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue) {
|
||||
extern "C" int32_t CVar_GetS32(const char* name, int32_t defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_S32)
|
||||
if (cvar->type == CVarType::S32)
|
||||
return cvar->value.valueS32;
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_FLOAT)
|
||||
if (cvar->type == CVarType::Float)
|
||||
return cvar->value.valueFloat;
|
||||
}
|
||||
|
||||
@ -40,19 +40,59 @@ extern "C" const char* CVar_GetString(const char* name, const char* defaultValue
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_STRING)
|
||||
if (cvar->type == CVarType::String)
|
||||
return cvar->value.valueStr;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
extern "C" void CVar_SetS32(const char* name, s32 value) {
|
||||
extern "C" Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue)
|
||||
{
|
||||
Color_RGBA8 defaultValueRGBA;
|
||||
defaultValueRGBA.r = defaultValue.r;
|
||||
defaultValueRGBA.g = defaultValue.g;
|
||||
defaultValueRGBA.b = defaultValue.b;
|
||||
defaultValueRGBA.a = 255;
|
||||
|
||||
Color_RGBA8 cvarGet = CVar_GetRGBA(name, defaultValueRGBA);
|
||||
Color_RGB8 result;
|
||||
|
||||
result.r = cvarGet.r;
|
||||
result.g = cvarGet.g;
|
||||
result.b = cvarGet.b;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar != nullptr) {
|
||||
if (cvar->type == CVarType::RGBA)
|
||||
return cvar->value.valueRGBA;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
extern "C" void CVar_SetRGBA(const char* name, Color_RGBA8 value)
|
||||
{
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_S32;
|
||||
|
||||
cvar->type = CVarType::RGBA;
|
||||
cvar->value.valueRGBA = value;
|
||||
}
|
||||
|
||||
extern "C" void CVar_SetS32(const char* name, int32_t value) {
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVarType::S32;
|
||||
cvar->value.valueS32 = value;
|
||||
}
|
||||
|
||||
@ -61,7 +101,7 @@ void CVar_SetFloat(const char* name, float value) {
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_FLOAT;
|
||||
cvar->type = CVarType::Float;
|
||||
cvar->value.valueFloat = value;
|
||||
}
|
||||
|
||||
@ -70,11 +110,16 @@ extern "C" void CVar_SetString(const char* name, const char* value) {
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_STRING;
|
||||
cvar->value.valueStr = ImStrdup(value);
|
||||
cvar->type = CVarType::String;
|
||||
cvar->value.valueStr = value;
|
||||
}
|
||||
|
||||
extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) {
|
||||
extern "C" void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue) {
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetRGBA(name, defaultValue);
|
||||
}
|
||||
|
||||
extern "C" void CVar_RegisterS32(const char* name, int32_t defaultValue) {
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetS32(name, defaultValue);
|
||||
}
|
||||
|
@ -1,37 +1,53 @@
|
||||
#ifndef _CVAR_H
|
||||
#define _CVAR_H
|
||||
|
||||
#include <PR/ultra64/gbi.h>
|
||||
#include "color.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum CVarType { CVAR_TYPE_S32, CVAR_TYPE_FLOAT, CVAR_TYPE_STRING } CVarType;
|
||||
#ifdef __cplusplus
|
||||
typedef enum class CVarType
|
||||
{
|
||||
S32,
|
||||
Float,
|
||||
String,
|
||||
RGBA
|
||||
} CVarType;
|
||||
|
||||
typedef struct CVar {
|
||||
const char* name;
|
||||
CVarType type;
|
||||
|
||||
union {
|
||||
s32 valueS32;
|
||||
int32_t valueS32;
|
||||
float valueFloat;
|
||||
const char* valueStr;
|
||||
Color_RGBA8 valueRGBA;
|
||||
} value;
|
||||
} CVar;
|
||||
|
||||
extern "C" CVar * CVar_Get(const char* name);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
//#include <ultra64.h>
|
||||
|
||||
CVar* CVar_Get(const char* name);
|
||||
s32 CVar_GetS32(const char* name, s32 defaultValue);
|
||||
int32_t CVar_GetS32(const char* name, int32_t defaultValue);
|
||||
float CVar_GetFloat(const char* name, float defaultValue);
|
||||
const char* CVar_GetString(const char* name, const char* defaultValue);
|
||||
void CVar_SetS32(const char* name, s32 value);
|
||||
void CVar_SetS32(const char* name, int32_t value);
|
||||
void CVar_SetString(const char* name, const char* value);
|
||||
|
||||
void CVar_RegisterS32(const char* name, s32 defaultValue);
|
||||
Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue);
|
||||
Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue);
|
||||
void CVar_SetRGBA(const char* name, Color_RGBA8 value);
|
||||
|
||||
void CVar_RegisterS32(const char* name, int32_t defaultValue);
|
||||
void CVar_RegisterFloat(const char* name, float defaultValue);
|
||||
void CVar_RegisterString(const char* name, const char* defaultValue);
|
||||
void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
@ -43,6 +59,7 @@ void CVar_RegisterString(const char* name, const char* defaultValue);
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
//extern "C" CVar * CVar_Get(const char* name);
|
||||
extern std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||
void CVar_SetFloat(const char* name, float value);
|
||||
#endif
|
||||
|
@ -14,23 +14,25 @@ namespace Ship
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint64_t data = reader->ReadUInt64();
|
||||
uint32_t w0 = reader->ReadUInt32();
|
||||
uint32_t w1 = reader->ReadUInt32();
|
||||
|
||||
if (sizeof(uintptr_t) < 8){
|
||||
dl->instructions.push_back(data);
|
||||
dl->instructions.push_back(((uint64_t) w0 << 32) | w1);
|
||||
|
||||
uint8_t opcode = data >> 24;
|
||||
uint8_t opcode = w0 >> 24;
|
||||
|
||||
// These are 128-bit commands, so read an extra 64 bits...
|
||||
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR)
|
||||
dl->instructions.push_back(reader->ReadUInt64());
|
||||
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR) {
|
||||
w0 = reader->ReadUInt32();
|
||||
w1 = reader->ReadUInt32();
|
||||
|
||||
dl->instructions.push_back(((uint64_t) w0 << 32) | w1);
|
||||
}
|
||||
|
||||
if (opcode == G_ENDDL)
|
||||
break;
|
||||
} else {
|
||||
uint32_t w0 = (uint32_t)data;
|
||||
uint32_t w1 = (uint32_t)(data >> 32);
|
||||
|
||||
dl->instructions.push_back(w0);
|
||||
dl->instructions.push_back(w1);
|
||||
|
||||
@ -38,10 +40,8 @@ namespace Ship
|
||||
|
||||
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR)
|
||||
{
|
||||
data = reader->ReadUInt64();
|
||||
|
||||
w0 = (uint32_t)data;
|
||||
w1 = (uint32_t)(data >> 32);
|
||||
w0 = reader->ReadUInt32();
|
||||
w1 = reader->ReadUInt32();
|
||||
|
||||
dl->instructions.push_back(w0);
|
||||
dl->instructions.push_back(w1);
|
||||
|
@ -9,6 +9,7 @@ namespace SohUtils {
|
||||
void saveEnvironmentVar(const std::string& key, const std::string& value) {
|
||||
environmentVars[key] = value;
|
||||
}
|
||||
|
||||
std::string getEnvironmentVar(const std::string& key) {
|
||||
return environmentVars[key];
|
||||
}
|
||||
|
@ -25,12 +25,12 @@ namespace Ship
|
||||
auto memStream = std::make_shared<MemoryStream>(FileToLoad->buffer.get(), FileToLoad->dwBufferSize);
|
||||
auto reader = std::make_shared<BinaryReader>(memStream);
|
||||
|
||||
Endianess endianess = (Endianess)reader->ReadByte();
|
||||
Endianness endianness = (Endianness)reader->ReadByte();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
reader->ReadByte();
|
||||
|
||||
// OTRTODO: Setup the binaryreader to use the resource's endianess
|
||||
reader->SetEndianness(endianness);
|
||||
|
||||
ResourceType resourceType = (ResourceType)reader->ReadUInt32();
|
||||
Resource* result = nullptr;
|
||||
|
@ -162,15 +162,18 @@ void Ship::GameOverlay::Draw() {
|
||||
ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
switch (var->type) {
|
||||
case CVAR_TYPE_FLOAT:
|
||||
case CVarType::Float:
|
||||
this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat);
|
||||
break;
|
||||
case CVAR_TYPE_S32:
|
||||
case CVarType::S32:
|
||||
this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32);
|
||||
break;
|
||||
case CVAR_TYPE_STRING:
|
||||
case CVarType::String:
|
||||
this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr);
|
||||
break;
|
||||
case CVarType::RGBA:
|
||||
this->TextDraw(30, textY, true, color, "#%08X", text, var->value.valueRGBA);
|
||||
break;
|
||||
}
|
||||
|
||||
free((void*) text);
|
||||
|
@ -38,5 +38,5 @@ namespace Ship {
|
||||
void LoadFont(const std::string& name, const std::string& path, float fontSize);
|
||||
};
|
||||
|
||||
static bool OverlayCommand(const std::vector<std::string>& args);
|
||||
bool OverlayCommand(const std::vector<std::string>& args);
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "ModManager.h"
|
||||
#ifdef __APPLE__
|
||||
#include "OSXFolderManager.h"
|
||||
#elif defined(__SWITCH__)
|
||||
#include "SwitchImpl.h"
|
||||
#endif
|
||||
|
||||
namespace Ship {
|
||||
@ -72,11 +74,16 @@ namespace Ship {
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MessageBox(nullptr, L"Main OTR file not found!", L"Uh oh", MB_OK);
|
||||
#elif defined(__SWITCH__)
|
||||
printf("Main OTR file not found!\n");
|
||||
#else
|
||||
SPDLOG_ERROR("Main OTR file not found!");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
#ifdef __SWITCH__
|
||||
Ship::Switch::Init(PostInitPhase);
|
||||
#endif
|
||||
INSTANCE = new ModManager(ResMan);
|
||||
INSTANCE->Init();
|
||||
}
|
||||
|
@ -27,6 +27,16 @@
|
||||
#include "Lib/spdlog/include/spdlog/common.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
#if __APPLE__
|
||||
#include <SDL_hints.h>
|
||||
#else
|
||||
#include <SDL2/SDL_hints.h>
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include "SwitchImpl.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "Lib/ImGui/backends/imgui_impl_opengl3.h"
|
||||
#include "Lib/ImGui/backends/imgui_impl_sdl.h"
|
||||
@ -58,6 +68,13 @@ OSContPad* pads;
|
||||
std::map<std::string, GameAsset*> DefaultAssets;
|
||||
std::vector<std::string> emptyArgs;
|
||||
|
||||
bool isBetaQuestEnabled = false;
|
||||
|
||||
extern "C" {
|
||||
void enableBetaQuest() { isBetaQuestEnabled = true; }
|
||||
void disableBetaQuest() { isBetaQuestEnabled = false; }
|
||||
}
|
||||
|
||||
namespace SohImGui {
|
||||
|
||||
WindowImpl impl;
|
||||
@ -120,13 +137,15 @@ namespace SohImGui {
|
||||
}
|
||||
|
||||
void Tooltip(const char* text) {
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", text);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", BreakTooltip(text, 60).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiWMInit() {
|
||||
switch (impl.backend) {
|
||||
case Backend::SDL:
|
||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "1");
|
||||
ImGui_ImplSDL2_InitForOpenGL(static_cast<SDL_Window*>(impl.sdl.window), impl.sdl.context);
|
||||
break;
|
||||
#if defined(ENABLE_DX11) || defined(ENABLE_DX12)
|
||||
@ -269,22 +288,20 @@ namespace SohImGui {
|
||||
stbi_image_free(img_data);
|
||||
}
|
||||
|
||||
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha) {
|
||||
std::string Cvar_Red = cvarname;
|
||||
Cvar_Red += "R";
|
||||
std::string Cvar_Green = cvarname;
|
||||
Cvar_Green += "G";
|
||||
std::string Cvar_Blue = cvarname;
|
||||
Cvar_Blue += "B";
|
||||
std::string Cvar_Alpha = cvarname;
|
||||
Cvar_Alpha += "A";
|
||||
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha)
|
||||
{
|
||||
Color_RGBA8 defaultColors;
|
||||
defaultColors.r = default_colors.x;
|
||||
defaultColors.g = default_colors.y;
|
||||
defaultColors.b = default_colors.z;
|
||||
defaultColors.a = default_colors.w;
|
||||
|
||||
ColorArray.x = (float)CVar_GetS32(Cvar_Red.c_str(), default_colors.x) / 255;
|
||||
ColorArray.y = (float)CVar_GetS32(Cvar_Green.c_str(), default_colors.y) / 255;
|
||||
ColorArray.z = (float)CVar_GetS32(Cvar_Blue.c_str(), default_colors.z) / 255;
|
||||
if (has_alpha) {
|
||||
ColorArray.w = (float)CVar_GetS32(Cvar_Alpha.c_str(), default_colors.w) / 255;
|
||||
}
|
||||
Color_RGBA8 cvarColor = CVar_GetRGBA(cvarname, defaultColors);
|
||||
|
||||
ColorArray.x = cvarColor.r / 255.0;
|
||||
ColorArray.y = cvarColor.g / 255.0;
|
||||
ColorArray.z = cvarColor.b / 255.0;
|
||||
ColorArray.w = cvarColor.a / 255.0;
|
||||
}
|
||||
|
||||
void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint) {
|
||||
@ -339,10 +356,17 @@ namespace SohImGui {
|
||||
io = &ImGui::GetIO();
|
||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io->Fonts->AddFontDefault();
|
||||
#ifdef __SWITCH__
|
||||
Ship::Switch::SetupFont(io->Fonts);
|
||||
#endif
|
||||
|
||||
lastBackendID = GetBackendID(GlobalCtx2::GetInstance()->GetConfig());
|
||||
if (CVar_GetS32("gOpenMenuBar", 0) != 1) {
|
||||
#ifdef __SWITCH__
|
||||
SohImGui::overlay->TextDrawNotification(30.0f, true, "Press - to access enhancements menu");
|
||||
#else
|
||||
SohImGui::overlay->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu");
|
||||
#endif
|
||||
}
|
||||
|
||||
auto imguiIniPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui.ini");
|
||||
@ -358,6 +382,9 @@ namespace SohImGui {
|
||||
controller->Init();
|
||||
ImGuiWMInit();
|
||||
ImGuiBackendInit();
|
||||
#ifdef __SWITCH__
|
||||
ImGui::GetStyle().ScaleAllSizes(2);
|
||||
#endif
|
||||
|
||||
ModInternal::RegisterHook<ModInternal::GfxInit>([] {
|
||||
if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen())
|
||||
@ -386,7 +413,10 @@ namespace SohImGui {
|
||||
CVar_SetS32("gNewSeedGenerated", 0);
|
||||
CVar_SetS32("gNewFileDropped", 0);
|
||||
CVar_SetString("gDroppedFile", "None");
|
||||
// Game::SaveSettings();
|
||||
|
||||
#ifdef __SWITCH__
|
||||
Switch::ApplyOverclock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Update(EventImpl event) {
|
||||
@ -637,14 +667,6 @@ namespace SohImGui {
|
||||
}
|
||||
|
||||
void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha) {
|
||||
std::string Cvar_Red = cvarName;
|
||||
Cvar_Red += "R";
|
||||
std::string Cvar_Green = cvarName;
|
||||
Cvar_Green += "G";
|
||||
std::string Cvar_Blue = cvarName;
|
||||
Cvar_Blue += "B";
|
||||
std::string Cvar_Alpha = cvarName;
|
||||
Cvar_Alpha += "A";
|
||||
std::string Cvar_RBM = cvarName;
|
||||
Cvar_RBM += "RBM";
|
||||
std::string MakeInvisible = "Reset";
|
||||
@ -656,10 +678,14 @@ namespace SohImGui {
|
||||
colors->y = defaultcolors.y / 255;
|
||||
colors->z = defaultcolors.z / 255;
|
||||
if (has_alpha) { colors->w = defaultcolors.w / 255; };
|
||||
CVar_SetS32(Cvar_Red.c_str(), ClampFloatToInt(colors->x * 255, 0, 255));
|
||||
CVar_SetS32(Cvar_Green.c_str(), ClampFloatToInt(colors->y * 255, 0, 255));
|
||||
CVar_SetS32(Cvar_Blue.c_str(), ClampFloatToInt(colors->z * 255, 0, 255));
|
||||
if (has_alpha) { CVar_SetS32(Cvar_Alpha.c_str(), ClampFloatToInt(colors->w * 255, 0, 255)); };
|
||||
|
||||
Color_RGBA8 colorsRGBA;
|
||||
colorsRGBA.r = defaultcolors.x / 255;
|
||||
colorsRGBA.g = defaultcolors.y / 255;
|
||||
colorsRGBA.b = defaultcolors.z / 255;
|
||||
if (has_alpha) { colorsRGBA.a = defaultcolors.w / 255; };
|
||||
|
||||
CVar_SetRGBA(cvarName, colorsRGBA);
|
||||
CVar_SetS32(Cvar_RBM.c_str(), 0); //On click disable rainbow mode.
|
||||
needs_save = true;
|
||||
}
|
||||
@ -667,42 +693,47 @@ namespace SohImGui {
|
||||
}
|
||||
|
||||
void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow, bool has_alpha, bool TitleSameLine) {
|
||||
//This will be moved to external cosmetics ed
|
||||
std::string Cvar_Red = cvarName;
|
||||
Cvar_Red += "R";
|
||||
std::string Cvar_Green = cvarName;
|
||||
Cvar_Green += "G";
|
||||
std::string Cvar_Blue = cvarName;
|
||||
Cvar_Blue += "B";
|
||||
std::string Cvar_Alpha = cvarName;
|
||||
Cvar_Alpha += "A";
|
||||
std::string Cvar_RBM = cvarName;
|
||||
Cvar_RBM += "RBM";
|
||||
|
||||
LoadPickersColors(ColorRGBA, cvarName, default_colors, has_alpha);
|
||||
|
||||
ImGuiColorEditFlags flags = ImGuiColorEditFlags_None;
|
||||
|
||||
if (!TitleSameLine) {
|
||||
ImGui::Text("%s", text);
|
||||
flags = ImGuiColorEditFlags_NoLabel;
|
||||
}
|
||||
|
||||
ImGui::PushID(cvarName);
|
||||
|
||||
if (!has_alpha) {
|
||||
if (ImGui::ColorEdit3(text, (float*)&ColorRGBA, flags)) {
|
||||
CVar_SetS32(Cvar_Red.c_str(), ClampFloatToInt(ColorRGBA.x * 255, 0, 255));
|
||||
CVar_SetS32(Cvar_Green.c_str(), ClampFloatToInt(ColorRGBA.y * 255, 0, 255));
|
||||
CVar_SetS32(Cvar_Blue.c_str(), ClampFloatToInt(ColorRGBA.z * 255, 0, 255));
|
||||
if (ImGui::ColorEdit3(text, (float*)&ColorRGBA, flags))
|
||||
{
|
||||
Color_RGBA8 colors;
|
||||
colors.r = ColorRGBA.x * 255.0;
|
||||
colors.g = ColorRGBA.y * 255.0;
|
||||
colors.b = ColorRGBA.z * 255.0;
|
||||
colors.a = ColorRGBA.w * 255.0;
|
||||
|
||||
CVar_SetRGBA(cvarName, colors);
|
||||
needs_save = true;
|
||||
}
|
||||
} else {
|
||||
if (ImGui::ColorEdit4(text, (float*)&ColorRGBA, flags)) {
|
||||
CVar_SetS32(Cvar_Red.c_str(), ClampFloatToInt(ColorRGBA.x * 255, 0, 255));
|
||||
CVar_SetS32(Cvar_Green.c_str(), ClampFloatToInt(ColorRGBA.y * 255, 0, 255));
|
||||
CVar_SetS32(Cvar_Blue.c_str(), ClampFloatToInt(ColorRGBA.z * 255, 0, 255));
|
||||
CVar_SetS32(Cvar_Alpha.c_str(), ClampFloatToInt(ColorRGBA.w * 255, 0, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ImGui::ColorEdit4(text, (float*)&ColorRGBA, flags))
|
||||
{
|
||||
Color_RGBA8 colors;
|
||||
colors.r = ColorRGBA.x / 255;
|
||||
colors.g = ColorRGBA.y / 255;
|
||||
colors.b = ColorRGBA.z / 255;
|
||||
colors.a = ColorRGBA.w / 255;
|
||||
|
||||
CVar_SetRGBA(cvarName, colors);
|
||||
needs_save = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
}
|
||||
//ImGui::SameLine(); // Removing that one to gain some width spacing on the HUD editor
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
ResetColor(cvarName, &ColorRGBA, default_colors, has_alpha);
|
||||
@ -734,7 +765,7 @@ namespace SohImGui {
|
||||
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(ImVec2(wnd->GetCurrentWidth(), wnd->GetCurrentHeight()));
|
||||
ImGui::SetNextWindowSize(ImVec2((int) wnd->GetCurrentWidth(), (int) wnd->GetCurrentHeight()));
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
@ -757,7 +788,7 @@ namespace SohImGui {
|
||||
|
||||
ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None | ImGuiDockNodeFlags_NoDockingInCentralNode);
|
||||
|
||||
if (ImGui::IsKeyPressed(TOGGLE_BTN)) {
|
||||
if (ImGui::IsKeyPressed(TOGGLE_BTN) || ImGui::IsKeyPressed(TOGGLE_PAD_BTN)) {
|
||||
bool menu_bar = CVar_GetS32("gOpenMenuBar", 0);
|
||||
CVar_SetS32("gOpenMenuBar", !menu_bar);
|
||||
needs_save = true;
|
||||
@ -791,8 +822,13 @@ namespace SohImGui {
|
||||
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (DefaultAssets.contains("Game_Icon")) {
|
||||
#ifdef __SWITCH__
|
||||
ImVec2 iconSize = ImVec2(20.0f, 20.0f);
|
||||
#else
|
||||
ImVec2 iconSize = ImVec2(16.0f, 16.0f);
|
||||
#endif
|
||||
ImGui::SetCursorPos(ImVec2(5, 2.5f));
|
||||
ImGui::Image(GetTextureByID(DefaultAssets["Game_Icon"]->textureId), ImVec2(16.0f, 16.0f));
|
||||
ImGui::Image(GetTextureByID(DefaultAssets["Game_Icon"]->textureId), iconSize);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPos(ImVec2(25, 0));
|
||||
}
|
||||
@ -839,7 +875,7 @@ namespace SohImGui {
|
||||
|
||||
// TODO mutual exclusions -- There should be some system to prevent conclifting enhancements from being selected
|
||||
EnhancementCheckbox("D-pad Support on Pause and File Select", "gDpadPauseName");
|
||||
Tooltip("Enables Pause and File Select screen navigation with the D-pad\nIf used with D-pad as Equip Items, you must hold C-Up\nto equip instead of navigate");
|
||||
Tooltip("Enables Pause and File Select screen navigation with the D-pad\nIf used with D-pad as Equip Items, you must hold C-Up to equip instead of navigate");
|
||||
EnhancementCheckbox("D-pad Support in Ocarina and Text Choice", "gDpadOcarinaText");
|
||||
EnhancementCheckbox("D-pad Support for Browsing Shop Items", "gDpadShop");
|
||||
EnhancementCheckbox("D-pad as Equip Items", "gDpadEquips");
|
||||
@ -862,17 +898,17 @@ namespace SohImGui {
|
||||
if (ImGui::BeginMenu("Graphics"))
|
||||
{
|
||||
EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f, "", 1.0f, true);
|
||||
Tooltip("Multiplies your output resolution by the value inputted,\nas a more intensive but effective form of anti-aliasing");
|
||||
Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing");
|
||||
gfx_current_dimensions.internal_mul = CVar_GetFloat("gInternalResolution", 1);
|
||||
EnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "");
|
||||
Tooltip("Activates multi-sample anti-aliasing when above 1x\nup to 8x for 8 samples for every pixel");
|
||||
Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel");
|
||||
gfx_msaa_level = CVar_GetS32("gMSAAValue", 1);
|
||||
|
||||
if (impl.backend == Backend::DX11)
|
||||
{
|
||||
const char* cvar = "gExtraLatencyThreshold";
|
||||
int val = CVar_GetS32(cvar, 80);
|
||||
val = MAX(MIN(val, 250), 0);
|
||||
val = MAX(MIN(val, 360), 0);
|
||||
int fps = val;
|
||||
|
||||
if (fps == 0)
|
||||
@ -894,18 +930,13 @@ namespace SohImGui {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
|
||||
if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 250, "", ImGuiSliderFlags_AlwaysClamp))
|
||||
if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 360, "", ImGuiSliderFlags_AlwaysClamp))
|
||||
{
|
||||
CVar_SetS32(cvar, val);
|
||||
needs_save = true;
|
||||
}
|
||||
|
||||
Tooltip("When Interpolation FPS setting is at least this threshold,\n"
|
||||
"add one frame of input lag (e.g. 16.6 ms for 60 FPS)\n"
|
||||
"in order to avoid jitter.This setting allows the CPU\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"
|
||||
"to do CPU + GPU work in time.");
|
||||
Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag (e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to work on one frame while GPU works on the previous frame.\nThis setting should be used when your computer is too slow to do CPU + GPU work in time.");
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
@ -931,8 +962,6 @@ namespace SohImGui {
|
||||
EXPERIMENTAL();
|
||||
ImGui::Text("Texture Filter (Needs reload)");
|
||||
EnhancementCombobox("gTextureFilter", filters, 3, 0);
|
||||
GfxRenderingAPI* gapi = gfx_get_current_rendering_api();
|
||||
gapi->set_texture_filter((FilteringMode)CVar_GetS32("gTextureFilter", 0));
|
||||
overlay->DrawSettings();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@ -957,30 +986,32 @@ namespace SohImGui {
|
||||
EnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "");
|
||||
EnhancementSliderInt("King Zora Speed: %dx", "##MWEEPSPEED", "gMweepSpeed", 1, 5, "");
|
||||
EnhancementSliderInt("Biggoron Forge Time: %d days", "##FORGETIME", "gForgeTime", 0, 3, "");
|
||||
Tooltip("Allows you to change the number of days it takes for\nBiggoron to forge the Biggoron Sword");
|
||||
Tooltip("Allows you to change the number of days it takes for Biggoron to forge the Biggoron Sword");
|
||||
EnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", "gClimbSpeed", 0, 12, "");
|
||||
|
||||
EnhancementCheckbox("Faster Block Push", "gFasterBlockPush");
|
||||
EnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift");
|
||||
Tooltip("Speeds up lifting silver rocks and obelisks");
|
||||
EnhancementCheckbox("No Forced Navi", "gNoForcedNavi");
|
||||
Tooltip("Prevent forced Navi conversations");
|
||||
EnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze");
|
||||
Tooltip("Stops the game from freezing the player\nwhen picking up Gold Skulltulas");
|
||||
Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas");
|
||||
EnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood");
|
||||
Tooltip("Wearing the Bunny Hood grants a speed\nincrease like in Majora's Mask");
|
||||
Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask");
|
||||
EnhancementCheckbox("Fast Chests", "gFastChests");
|
||||
Tooltip("Kick open every chest");
|
||||
EnhancementCheckbox("Fast Drops", "gFastDrops");
|
||||
Tooltip("Skip first-time pickup messages for consumable items");
|
||||
EnhancementCheckbox("Skip Pickup Messages", "gFastDrops");
|
||||
Tooltip("Skip pickup messages for new consumable items and bottle swipes");
|
||||
EnhancementCheckbox("Better Owl", "gBetterOwl");
|
||||
Tooltip("The default response to Kaepora Gaebora is\nalways that you understood what he said");
|
||||
Tooltip("The default response to Kaepora Gaebora is always that you understood what he said");
|
||||
EnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback");
|
||||
Tooltip("Skip the part where the Ocarina playback is called when you play\na song");
|
||||
Tooltip("Skip the part where the Ocarina playback is called when you play a song");
|
||||
EnhancementCheckbox("Prevent Dropped Ocarina Inputs", "gDpadNoDropOcarinaInput");
|
||||
Tooltip("Prevent dropping inputs when playing the ocarina quickly");
|
||||
EnhancementCheckbox("Instant Putaway", "gInstantPutaway");
|
||||
Tooltip("Allow Link to put items away without having to wait around");
|
||||
EnhancementCheckbox("Mask Select in Inventory", "gMaskSelect");
|
||||
Tooltip("After completing the mask trading sub-quest,\npress A and any direction on the mask slot to change masks");
|
||||
Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
@ -1111,11 +1142,13 @@ namespace SohImGui {
|
||||
}
|
||||
|
||||
EnhancementCheckbox("Visual Stone of Agony", "gVisualAgony");
|
||||
Tooltip("Displays an icon and plays a sound when Stone of Agony\nshould be activated, for those without rumble");
|
||||
Tooltip("Displays an icon and plays a sound when Stone of Agony should be activated, for those without rumble");
|
||||
EnhancementCheckbox("Assignable Tunics and Boots", "gAssignableTunicsAndBoots");
|
||||
Tooltip("Allows equipping the tunic and boots to c-buttons");
|
||||
EnhancementCheckbox("Equipment Toggle", "gEquipmentCanBeRemoved");
|
||||
Tooltip("Allows equipment to be removed by toggling it off on\nthe equipment subscreen.");
|
||||
EnhancementCheckbox("Link's Cow in Both Time Periods", "gCowOfTime");
|
||||
Tooltip("Allows the Lon Lon Ranch obstacle course reward to be\nshared across time periods");
|
||||
Tooltip("Allows the Lon Lon Ranch obstacle course reward to be shared across time periods");
|
||||
EnhancementCheckbox("Enable visible guard vision", "gGuardVision");
|
||||
EnhancementCheckbox("Enable passage of time on file select", "gTimeFlowFileSelect");
|
||||
EnhancementCheckbox("Allow the cursor to be on any slot", "gPauseAnyCursor");
|
||||
@ -1133,7 +1166,7 @@ namespace SohImGui {
|
||||
ImGui::Text("Rotation");
|
||||
EnhancementRadioButton("Disabled", "gPauseLiveLinkRotation", 0);
|
||||
EnhancementRadioButton("Rotate Link with D-pad", "gPauseLiveLinkRotation", 1);
|
||||
Tooltip("Allow you to rotate Link on the Equipment menu with the DPAD\nUse DPAD-Up or DPAD-Down to reset Link's rotation");
|
||||
Tooltip("Allow you to rotate Link on the Equipment menu with the D-pad\nUse D-pad Up or D-pad Down to reset Link's rotation");
|
||||
EnhancementRadioButton("Rotate Link with C-buttons", "gPauseLiveLinkRotation", 2);
|
||||
Tooltip("Allow you to rotate Link on the Equipment menu with the C-buttons\nUse C-Up or C-Down to reset Link's rotation");
|
||||
EnhancementRadioButton("Rotate Link with Right Stick", "gPauseLiveLinkRotation", 3);
|
||||
@ -1178,7 +1211,7 @@ namespace SohImGui {
|
||||
EnhancementCheckbox("Enable 3D Dropped items/projectiles", "gNewDrops");
|
||||
Tooltip("Change most 2D items and projectiles on the overworld to their 3D versions");
|
||||
EnhancementCheckbox("Disable Black Bar Letterboxes", "gDisableBlackBars");
|
||||
Tooltip("Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be minor visual glitches that\nwere covered up by the black bars\nPlease disable this setting before reporting a bug");
|
||||
Tooltip("Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be minor visual glitches that were covered up by the black bars\nPlease disable this setting before reporting a bug");
|
||||
EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon");
|
||||
Tooltip("Changes the rupee in the wallet icon to match the wallet size you currently have");
|
||||
EnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon");
|
||||
@ -1194,19 +1227,19 @@ namespace SohImGui {
|
||||
EnhancementCheckbox("Fix L&Z Page switch in Pause menu", "gNGCKaleidoSwitcher");
|
||||
Tooltip("Makes L and R switch pages like on the GameCube\nZ opens the Debug Menu instead");
|
||||
EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon");
|
||||
Tooltip("Removes the dungeon entrance icon on the top-left corner\nof the screen when no dungeon is present on the current map");
|
||||
Tooltip("Removes the dungeon entrance icon on the top-left corner of the screen when no dungeon is present on the current map");
|
||||
EnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle");
|
||||
Tooltip("Re-enables the two-handed idle animation, a seemingly\nfinished animation that was disabled on accident in the original game");
|
||||
Tooltip("Re-enables the two-handed idle animation, a seemingly finished animation that was disabled on accident in the original game");
|
||||
EnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix");
|
||||
Tooltip("Fixes a bug where the Gravedigging Tour Heart\nPiece disappears if the area reloads");
|
||||
Tooltip("Fixes a bug where the Gravedigging Tour Heart Piece disappears if the area reloads");
|
||||
EnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix");
|
||||
Tooltip("Prevents the Forest Stage Deku Nut upgrade from\nbecoming unobtainable after receiving the Poacher's Saw");
|
||||
Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw");
|
||||
EnhancementCheckbox("Fix Navi text HUD position", "gNaviTextFix");
|
||||
Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button");
|
||||
EnhancementCheckbox("Fix Anubis fireballs", "gAnubisFix");
|
||||
Tooltip("Make Anubis fireballs do fire damage when reflected\nback at them with the Mirror Shield");
|
||||
Tooltip("Make Anubis fireballs do fire damage when reflected back at them with the Mirror Shield");
|
||||
EnhancementCheckbox("Fix Megaton Hammer crouch stab", "gCrouchStabHammerFix");
|
||||
Tooltip("Make the Megaton Hammer's crouch stab able to destroy\nrocks without first swinging it normally");
|
||||
Tooltip("Make the Megaton Hammer's crouch stab able to destroy rocks without first swinging it normally");
|
||||
if (CVar_GetS32("gCrouchStabHammerFix", 0) == 0) {
|
||||
CVar_SetS32("gCrouchStabFix", 0);
|
||||
} else {
|
||||
@ -1222,7 +1255,7 @@ namespace SohImGui {
|
||||
EnhancementCheckbox("Red Ganon blood", "gRedGanonBlood");
|
||||
Tooltip("Restore the original red blood from NTSC 1.0/1.1. Disable for green blood");
|
||||
EnhancementCheckbox("Fish while hovering", "gHoverFishing");
|
||||
Tooltip("Restore a bug from NTSC 1.0 that allows casting\nthe Fishing Rod while using the Hover Boots");
|
||||
Tooltip("Restore a bug from NTSC 1.0 that allows casting the Fishing Rod while using the Hover Boots");
|
||||
EnhancementCheckbox("N64 Weird Frames", "gN64WeirdFrames");
|
||||
Tooltip("Restores N64 Weird Frames allowing weirdshots to behave the same as N64");
|
||||
EnhancementCheckbox("Bombchus out of bounds", "gBombchusOOB");
|
||||
@ -1235,8 +1268,16 @@ namespace SohImGui {
|
||||
|
||||
const char* fps_cvar = "gInterpolationFPS";
|
||||
{
|
||||
int val = CVar_GetS32(fps_cvar, 20);
|
||||
val = MAX(MIN(val, 250), 20);
|
||||
#ifdef __SWITCH__
|
||||
int minFps = 20;
|
||||
int maxFps = 60;
|
||||
#else
|
||||
int minFps = 20;
|
||||
int maxFps = 360;
|
||||
#endif
|
||||
|
||||
int val = CVar_GetS32(fps_cvar, minFps);
|
||||
val = MAX(MIN(val, maxFps), 20);
|
||||
int fps = val;
|
||||
|
||||
if (fps == 20)
|
||||
@ -1258,11 +1299,11 @@ namespace SohImGui {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
|
||||
if (ImGui::SliderInt("##FPSInterpolation", &val, 20, 250, "", ImGuiSliderFlags_AlwaysClamp))
|
||||
if (ImGui::SliderInt("##FPSInterpolation", &val, minFps, maxFps, "", ImGuiSliderFlags_AlwaysClamp))
|
||||
{
|
||||
if (val > 250)
|
||||
if (val > 360)
|
||||
{
|
||||
val = 250;
|
||||
val = 360;
|
||||
}
|
||||
else if (val < 20)
|
||||
{
|
||||
@ -1275,7 +1316,7 @@ namespace SohImGui {
|
||||
|
||||
Tooltip("Interpolate extra frames to get smoother graphics\n"
|
||||
"Set to match your monitor's refresh rate, or a divisor of it\n"
|
||||
"A higher target FPS than your monitor's refresh rate will just waste resources,\n"
|
||||
"A higher target FPS than your monitor's refresh rate will just waste resources, "
|
||||
"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"
|
||||
"Ctrl+Click for keyboard input");
|
||||
@ -1293,7 +1334,7 @@ namespace SohImGui {
|
||||
if (ImGui::Button("Match Refresh Rate"))
|
||||
{
|
||||
int hz = roundf(gfx_get_detected_hz());
|
||||
if (hz >= 20 && hz <= 250)
|
||||
if (hz >= 20 && hz <= 360)
|
||||
{
|
||||
CVar_SetS32(fps_cvar, hz);
|
||||
needs_save = true;
|
||||
@ -1303,7 +1344,7 @@ namespace SohImGui {
|
||||
EnhancementCheckbox("Disable LOD", "gDisableLOD");
|
||||
Tooltip("Turns off the Level of Detail setting, making models use their higher-poly variants at any distance");
|
||||
EnhancementCheckbox("Disable Draw Distance", "gDisableDrawDistance");
|
||||
Tooltip("Turns off the objects draw distance,\nmaking objects being visible from a longer range");
|
||||
Tooltip("Turns off the objects draw distance, making objects being visible from a longer range");
|
||||
if (CVar_GetS32("gDisableDrawDistance", 0) == 0) {
|
||||
CVar_SetS32("gDisableKokiriDrawDistance", 0);
|
||||
} else if (CVar_GetS32("gDisableDrawDistance", 0) == 1) {
|
||||
@ -1314,7 +1355,24 @@ namespace SohImGui {
|
||||
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.");
|
||||
Tooltip("Enables camera control\nNote: You must remap C buttons off of the right stick in the controller config menu, and map the camera stick to the right stick.");
|
||||
|
||||
#ifdef __SWITCH__
|
||||
int slot = CVar_GetS32("gSwitchPerfMode", (int)SwitchProfiles::STOCK);
|
||||
ImGui::Text("Switch performance mode");
|
||||
if (ImGui::BeginCombo("##perf", SWITCH_CPU_PROFILES[slot])) {
|
||||
for (int sId = 0; sId <= SwitchProfiles::POWERSAVINGM3; sId++) {
|
||||
if (ImGui::Selectable(SWITCH_CPU_PROFILES[sId], sId == slot)) {
|
||||
INFO("Profile:: %s", SWITCH_CPU_PROFILES[sId]);
|
||||
CVar_SetS32("gSwitchPerfMode", sId);
|
||||
Switch::ApplyOverclock();
|
||||
needs_save = true;
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@ -1353,7 +1411,79 @@ namespace SohImGui {
|
||||
EnhancementCheckbox("Fireproof Deku Shield", "gFireproofDekuShield");
|
||||
Tooltip("Prevents the Deku Shield from burning on contact with fire");
|
||||
EnhancementCheckbox("Shield with Two-Handed Weapons", "gShieldTwoHanded");
|
||||
Tooltip("This allows you to put up your shield with any two-handed weapon in hand\nexcept for Deku Sticks");
|
||||
Tooltip("This allows you to put up your shield with any two-handed weapon in hand except for Deku Sticks");
|
||||
|
||||
{
|
||||
static int32_t betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0);
|
||||
static int32_t lastBetaQuestEnabled = betaQuestEnabled;
|
||||
static int32_t betaQuestWorld = CVar_GetS32("gBetaQuestWorld", 0xFFEF);
|
||||
static int32_t lastBetaQuestWorld = betaQuestWorld;
|
||||
|
||||
if (!isBetaQuestEnabled) {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
}
|
||||
|
||||
EnhancementCheckbox("Enable Beta Quest", "gEnableBetaQuest");
|
||||
Tooltip("Turns on OoT Beta Quest. *WARNING* This will reset your game.");
|
||||
betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0);
|
||||
if (betaQuestEnabled) {
|
||||
if (betaQuestEnabled != lastBetaQuestEnabled) {
|
||||
betaQuestWorld = 0;
|
||||
}
|
||||
|
||||
ImGui::Text("Beta Quest World: %d", betaQuestWorld);
|
||||
|
||||
if (ImGui::Button(" - ##BetaQuest")) {
|
||||
betaQuestWorld--;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
|
||||
ImGui::SliderInt("##BetaQuest", &betaQuestWorld, 0, 8, "", ImGuiSliderFlags_AlwaysClamp);
|
||||
Tooltip("Set the Beta Quest world to explore. *WARNING* Changing this will reset your game.\nCtrl+Click to type in a value.");
|
||||
|
||||
ImGui::Text("After Slider Beta Quest World: %d", betaQuestWorld);
|
||||
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f);
|
||||
if (ImGui::Button(" + ##BetaQuest")) {
|
||||
betaQuestWorld++;
|
||||
}
|
||||
|
||||
if (betaQuestWorld > 8) {
|
||||
betaQuestWorld = 8;
|
||||
}
|
||||
else if (betaQuestWorld < 0) {
|
||||
betaQuestWorld = 0;
|
||||
}
|
||||
|
||||
ImGui::Text("After Clamp Beta Quest World: %d", betaQuestWorld);
|
||||
}
|
||||
else {
|
||||
lastBetaQuestWorld = betaQuestWorld = 0xFFEF;
|
||||
CVar_SetS32("gBetaQuestWorld", betaQuestWorld);
|
||||
needs_save = true;
|
||||
}
|
||||
if (betaQuestEnabled != lastBetaQuestEnabled || betaQuestWorld != lastBetaQuestWorld)
|
||||
{
|
||||
// Reset the game if the beta quest state or world changed because beta quest happens on redirecting the title screen cutscene.
|
||||
lastBetaQuestEnabled = betaQuestEnabled;
|
||||
lastBetaQuestWorld = betaQuestWorld;
|
||||
CVar_SetS32("gEnableBetaQuest", betaQuestEnabled);
|
||||
CVar_SetS32("gBetaQuestWorld", betaQuestWorld);
|
||||
|
||||
console->Commands["reset"].handler(emptyArgs);
|
||||
|
||||
needs_save = true;
|
||||
}
|
||||
|
||||
if (!isBetaQuestEnabled) {
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@ -1363,11 +1493,11 @@ namespace SohImGui {
|
||||
if (ImGui::BeginMenu("Developer Tools"))
|
||||
{
|
||||
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
|
||||
Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right,\nand open the debug menu with L on the pause screen");
|
||||
Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right, and open the debug menu with L on the pause screen");
|
||||
EnhancementCheckbox("OoT Skulltula Debug", "gSkulltulaDebugEnabled");
|
||||
Tooltip("Enables Skulltula Debug, when moving the cursor in the menu above various map\nicons (boss key, compass, map screen locations, etc) will set the GS bits in that\narea. USE WITH CAUTION AS IT DOES NOT UPDATE THE GS COUNT.");
|
||||
Tooltip("Enables Skulltula Debug, when moving the cursor in the menu above various map icons (boss key, compass, map screen locations, etc) will set the GS bits in that area.\nUSE WITH CAUTION AS IT DOES NOT UPDATE THE GS COUNT.");
|
||||
EnhancementCheckbox("Fast File Select", "gSkipLogoTitle");
|
||||
Tooltip("Load the game to the selected menu or file\n\"Zelda Map Select\" require debug mode else you will fallback to File choose menu\nUsing a file number that don't have save will create a save file only\nif you toggle on \"Create a new save if none ?\" else it will bring you to the\nFile choose menu");
|
||||
Tooltip("Load the game to the selected menu or file\n\"Zelda Map Select\" require debug mode else you will fallback to File choose menu\nUsing a file number that don't have save will create a save file only if you toggle on \"Create a new save if none ?\" else it will bring you to the File choose menu");
|
||||
if (CVar_GetS32("gSkipLogoTitle", 0)) {
|
||||
const char* FastFileSelect[5] = {
|
||||
"File N.1",
|
||||
@ -1379,13 +1509,13 @@ namespace SohImGui {
|
||||
ImGui::Text("Loading :");
|
||||
EnhancementCombobox("gSaveFileID", FastFileSelect, 5, 0);
|
||||
EnhancementCheckbox("Create a new save if none", "gCreateNewSave");
|
||||
Tooltip("Enable the creation of a new save file\nif none exist in the File number selected\nNo file name will be assigned please do in Save editor once you see the first text\nelse your save file name will be named \"00000000\"\nIf disabled you will fall back in File select menu");
|
||||
Tooltip("Enable the creation of a new save file if none exist in the File number selected\nNo file name will be assigned please do in Save editor once you see the first text else your save file name will be named \"00000000\"\nIf disabled you will fall back in File select menu");
|
||||
};
|
||||
ImGui::Separator();
|
||||
EnhancementCheckbox("Stats", "gStatsEnabled");
|
||||
Tooltip("Shows the stats window, with your FPS and frametimes,\nand the OS you're playing on");
|
||||
Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on");
|
||||
EnhancementCheckbox("Console", "gConsoleEnabled");
|
||||
Tooltip("Enables the console window, allowing you to input commands,\ntype help for some examples");
|
||||
Tooltip("Enables the console window, allowing you to input commands, type help for some examples");
|
||||
console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
||||
|
||||
ImGui::EndMenu();
|
||||
@ -1454,6 +1584,8 @@ namespace SohImGui {
|
||||
ImGui::Text("Platform: Windows");
|
||||
#elif __APPLE__
|
||||
ImGui::Text("Platform: macOS");
|
||||
#elif defined(__SWITCH__)
|
||||
ImGui::Text("Platform: Nintendo Switch");
|
||||
#else
|
||||
ImGui::Text("Platform: Linux");
|
||||
#endif
|
||||
@ -1749,4 +1881,36 @@ namespace SohImGui {
|
||||
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
// Automatically add newlines to break up tooltips longer than a specified number of characters
|
||||
// Manually included newlines will still be respected and reset the line length
|
||||
// Default line length is 60 characters
|
||||
std::string BreakTooltip(const char* text, int lineLength) {
|
||||
std::string newText(text);
|
||||
const int tipLength = newText.length();
|
||||
int lastSpace = -1;
|
||||
int currentLineLength = 0;
|
||||
for (int currentCharacter = 0; currentCharacter < tipLength; currentCharacter++) {
|
||||
if (newText[currentCharacter] == '\n') {
|
||||
currentLineLength = 0;
|
||||
lastSpace = -1;
|
||||
continue;
|
||||
}
|
||||
else if (newText[currentCharacter] == ' ') {
|
||||
lastSpace = currentCharacter;
|
||||
}
|
||||
|
||||
if ((currentLineLength >= lineLength) && (lastSpace >= 0)) {
|
||||
newText[lastSpace] = '\n';
|
||||
currentLineLength = currentCharacter - lastSpace - 1;
|
||||
lastSpace = -1;
|
||||
}
|
||||
currentLineLength++;
|
||||
}
|
||||
return newText;
|
||||
}
|
||||
|
||||
std::string BreakTooltip(const std::string& text, int lineLength) {
|
||||
return BreakTooltip(text.c_str(), lineLength);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void enableBetaQuest();
|
||||
void disableBetaQuest();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "GameOverlay.h"
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
#include "Console.h"
|
||||
@ -94,4 +104,8 @@ namespace SohImGui {
|
||||
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);
|
||||
std::string BreakTooltip(const char* text, int lineLength = 60);
|
||||
std::string BreakTooltip(const std::string& text, int lineLength = 60);
|
||||
}
|
||||
|
||||
#endif
|
@ -9,7 +9,6 @@
|
||||
|
||||
namespace Ship {
|
||||
|
||||
extern "C" uint8_t __enableGameInput;
|
||||
#define SEPARATION() ImGui::Dummy(ImVec2(0, 5))
|
||||
|
||||
void InputEditor::Init() {
|
||||
@ -116,7 +115,11 @@ namespace Ship {
|
||||
DrawButton("Z", BTN_Z);
|
||||
DrawButton("START", BTN_START);
|
||||
SEPARATION();
|
||||
#ifdef __SWITCH__
|
||||
SohImGui::EndGroupPanel(IsKeyboard ? 7.0f : 56.0f);
|
||||
#else
|
||||
SohImGui::EndGroupPanel(IsKeyboard ? 7.0f : 48.0f);
|
||||
#endif
|
||||
ImGui::SameLine();
|
||||
SohImGui::BeginGroupPanel("Digital Pad", ImVec2(150, 20));
|
||||
DrawButton("Up", BTN_DUP);
|
||||
@ -124,7 +127,11 @@ namespace Ship {
|
||||
DrawButton("Left", BTN_DLEFT);
|
||||
DrawButton("Right", BTN_DRIGHT);
|
||||
SEPARATION();
|
||||
#ifdef __SWITCH__
|
||||
SohImGui::EndGroupPanel(IsKeyboard ? 53.0f : 122.0f);
|
||||
#else
|
||||
SohImGui::EndGroupPanel(IsKeyboard ? 53.0f : 94.0f);
|
||||
#endif
|
||||
ImGui::SameLine();
|
||||
SohImGui::BeginGroupPanel("Analog Stick", ImVec2(150, 20));
|
||||
DrawButton("Up", BTN_STICKUP);
|
||||
@ -148,7 +155,11 @@ namespace Ship {
|
||||
} else {
|
||||
ImGui::Dummy(ImVec2(0, 6));
|
||||
}
|
||||
#ifdef __SWITCH__
|
||||
SohImGui::EndGroupPanel(IsKeyboard ? 52.0f : 52.0f);
|
||||
#else
|
||||
SohImGui::EndGroupPanel(IsKeyboard ? 52.0f : 24.0f);
|
||||
#endif
|
||||
ImGui::SameLine();
|
||||
|
||||
if (!IsKeyboard) {
|
||||
@ -174,7 +185,11 @@ namespace Ship {
|
||||
ImGui::InputFloat("##MSensitivity", &profile.Thresholds[SENSITIVITY], 1.0f, 0.0f, "%.0f");
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndChild();
|
||||
#ifdef __SWITCH__
|
||||
SohImGui::EndGroupPanel(43.0f);
|
||||
#else
|
||||
SohImGui::EndGroupPanel(14.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(Backend->CanGyro()) {
|
||||
@ -211,7 +226,11 @@ namespace Ship {
|
||||
ImGui::InputFloat("##GDriftY", &profile.Thresholds[DRIFT_Y], 1.0f, 0.0f, "%.1f");
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndChild();
|
||||
#ifdef __SWITCH__
|
||||
SohImGui::EndGroupPanel(46.0f);
|
||||
#else
|
||||
SohImGui::EndGroupPanel(14.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
@ -227,7 +246,11 @@ namespace Ship {
|
||||
SohImGui::EndGroupPanel();
|
||||
|
||||
ImGui::SetCursorPosX(cursor.x);
|
||||
#ifdef __SWITCH__
|
||||
ImGui::SetCursorPosY(cursor.y + 167);
|
||||
#else
|
||||
ImGui::SetCursorPosY(cursor.y + 120);
|
||||
#endif
|
||||
SohImGui::BeginGroupPanel("Options", ImVec2(158, 20));
|
||||
float cursorX = ImGui::GetCursorPosX() + 5;
|
||||
ImGui::SetCursorPosX(cursorX);
|
||||
@ -245,16 +268,21 @@ namespace Ship {
|
||||
}
|
||||
|
||||
void InputEditor::DrawHud() {
|
||||
|
||||
__enableGameInput = true;
|
||||
|
||||
if (!this->Opened) {
|
||||
BtnReading = -1;
|
||||
CVar_SetS32("gControllerConfigurationEnabled", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(641, 250), ImVec2(1200, 290));
|
||||
#ifdef __SWITCH__
|
||||
ImVec2 minSize = ImVec2(641, 250);
|
||||
ImVec2 maxSize = ImVec2(2200, 505);
|
||||
#else
|
||||
ImVec2 minSize = ImVec2(641, 250);
|
||||
ImVec2 maxSize = ImVec2(1200, 290);
|
||||
#endif
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(minSize, maxSize);
|
||||
//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);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) && defined(X11_SUPPORTED)
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
@ -156,6 +156,7 @@ static struct {
|
||||
Atom atom_wm_delete_window;
|
||||
|
||||
bool is_fullscreen;
|
||||
bool is_running = true;
|
||||
void (*on_fullscreen_changed)(bool is_now_fullscreen);
|
||||
|
||||
int keymap[256];
|
||||
@ -399,7 +400,7 @@ static void gfx_glx_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bo
|
||||
}
|
||||
|
||||
static void gfx_glx_main_loop(void (*run_one_game_iter)(void)) {
|
||||
while (1) {
|
||||
while (glx.is_running) {
|
||||
run_one_game_iter();
|
||||
}
|
||||
}
|
||||
@ -440,7 +441,7 @@ static void gfx_glx_handle_events(void) {
|
||||
}
|
||||
}
|
||||
if (xev.type == ClientMessage && (Atom)xev.xclient.data.l[0] == glx.atom_wm_delete_window) {
|
||||
exit(0);
|
||||
glx.is_running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,9 @@
|
||||
#elif __APPLE__
|
||||
#include <SDL.h>
|
||||
#include <GL/glew.h>
|
||||
#elif __SWITCH__
|
||||
#include <SDL2/SDL.h>
|
||||
#include <glad/glad.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#include <GL/glew.h>
|
||||
@ -643,6 +646,10 @@ static void gfx_opengl_upload_texture(const uint8_t *rgba32_buf, uint32_t width,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf);
|
||||
}
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
|
||||
#endif
|
||||
|
||||
static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
||||
switch (val) {
|
||||
case G_TX_NOMIRROR | G_TX_CLAMP:
|
||||
@ -710,9 +717,9 @@ static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_
|
||||
}
|
||||
|
||||
static void gfx_opengl_init(void) {
|
||||
//#if FOR_WINDOWS
|
||||
#ifndef __SWITCH__
|
||||
glewInit();
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
glGenBuffers(1, &opengl_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo);
|
||||
@ -840,9 +847,7 @@ void gfx_opengl_start_draw_to_framebuffer(int fb_id, float noise_scale) {
|
||||
if (noise_scale != 0.0f) {
|
||||
current_noise_scale = 1.0f / noise_scale;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.fbo);
|
||||
|
||||
current_framebuffer = fb_id;
|
||||
}
|
||||
|
||||
|
@ -1206,8 +1206,8 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bo
|
||||
rdp.viewport_or_scissor_changed = false;
|
||||
}
|
||||
|
||||
uint64_t cc_id = rdp.combine_mode;
|
||||
|
||||
uint64_t cc_id = rdp.combine_mode;
|
||||
bool use_alpha = (rdp.other_mode_l & (3 << 20)) == (G_BL_CLR_MEM << 20) && (rdp.other_mode_l & (3 << 16)) == (G_BL_1MA << 16);
|
||||
bool use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
|
||||
bool texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
|
||||
|
@ -15,6 +15,11 @@
|
||||
#include "SDL_opengl.h"
|
||||
#elif __APPLE__
|
||||
#include <SDL.h>
|
||||
#elif __SWITCH__
|
||||
#include <SDL2/SDL.h>
|
||||
#include <switch.h>
|
||||
#include <glad/glad.h>
|
||||
#include "../../SwitchImpl.h"
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
@ -42,6 +47,7 @@ static int vsync_enabled = 0;
|
||||
static int window_width = DESIRED_SCREEN_WIDTH;
|
||||
static int window_height = DESIRED_SCREEN_HEIGHT;
|
||||
static bool fullscreen_state;
|
||||
static bool is_running = true;
|
||||
static void (*on_fullscreen_changed_callback)(bool is_now_fullscreen);
|
||||
static bool (*on_key_down_callback)(int scancode);
|
||||
static bool (*on_key_up_callback)(int scancode);
|
||||
@ -146,31 +152,43 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen, uint32
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
#elif defined(__SWITCH__)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
timer = CreateWaitableTimer(nullptr, false, nullptr);
|
||||
#endif
|
||||
|
||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
||||
|
||||
char title[512];
|
||||
int len = sprintf(title, "%s (%s)", game_name, GFX_API_NAME);
|
||||
|
||||
window_width = width;
|
||||
window_height = height;
|
||||
#ifdef __SWITCH__
|
||||
// For Switch we need to set the window width before creating the window
|
||||
Ship::Switch::GetDisplaySize(&window_width, &window_height);
|
||||
#endif
|
||||
|
||||
wnd = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
|
||||
#ifndef __SWITCH__
|
||||
SDL_GL_GetDrawableSize(wnd, &window_width, &window_height);
|
||||
|
||||
if (start_in_fullscreen) {
|
||||
set_fullscreen(true, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx = SDL_GL_CreateContext(wnd);
|
||||
|
||||
#ifdef __SWITCH__
|
||||
if(!gladLoadGLLoader(SDL_GL_GetProcAddress)){
|
||||
printf("Failed to initialize glad\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
SohImGui::WindowImpl window_impl;
|
||||
@ -211,10 +229,17 @@ static void gfx_sdl_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bo
|
||||
}
|
||||
|
||||
static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
|
||||
while (1)
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
while(Ship::Switch::IsRunning()) {
|
||||
#else
|
||||
while(is_running) {
|
||||
#endif
|
||||
run_one_game_iter();
|
||||
}
|
||||
#ifdef __SWITCH__
|
||||
Ship::Switch::Exit();
|
||||
#endif
|
||||
ModInternal::ExecuteHooks<ModInternal::ExitGame>();
|
||||
}
|
||||
|
||||
static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
|
||||
@ -271,7 +296,11 @@ static void gfx_sdl_handle_events(void) {
|
||||
#endif
|
||||
case SDL_WINDOWEVENT:
|
||||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
#ifdef __SWITCH__
|
||||
Ship::Switch::GetDisplaySize(&window_width, &window_height);
|
||||
#else
|
||||
SDL_GL_GetDrawableSize(wnd, &window_width, &window_height);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case SDL_DROPFILE:
|
||||
@ -303,7 +332,7 @@ static inline void sync_framerate_with_timer(void) {
|
||||
const int64_t next = previous_time + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR;
|
||||
const int64_t left = next - t;
|
||||
if (left > 0) {
|
||||
#if defined __linux__ || defined __APPLE__
|
||||
#ifndef _WIN32
|
||||
const timespec spec = { 0, left * 100 };
|
||||
nanosleep(&spec, nullptr);
|
||||
#else
|
||||
|
@ -132,6 +132,10 @@
|
||||
#else
|
||||
#include <GLES3/gl3.h> // Use GL ES 3
|
||||
#endif
|
||||
#elif defined(__SWITCH__)
|
||||
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#include <glad/glad.h>
|
||||
#elif !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
||||
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
|
||||
// Helper libraries are often used for this purpose! Here we are using our own minimal custom loader based on gl3w.
|
||||
|
@ -65,6 +65,7 @@
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
// SDL
|
||||
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
|
||||
@ -77,7 +78,7 @@
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
|
||||
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) && !defined(__SWITCH__)
|
||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
|
||||
#else
|
||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
||||
@ -105,6 +106,7 @@ struct ImGui_ImplSDL2_Data
|
||||
char* ClipboardTextData;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool UseVulkan;
|
||||
bool ShowingVirtualKeyboard;
|
||||
|
||||
ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@ -269,6 +271,23 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
ImGuiInputTextState* state = ImGui::GetInputTextState(ImGui::GetActiveID());
|
||||
|
||||
#ifdef __SWITCH__
|
||||
if (io.WantTextInput) {
|
||||
if (!bd->ShowingVirtualKeyboard) {
|
||||
state->ClearText();
|
||||
|
||||
bd->ShowingVirtualKeyboard = true;
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
} else {
|
||||
if (bd->ShowingVirtualKeyboard) {
|
||||
bd->ShowingVirtualKeyboard = false;
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
@ -411,6 +430,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = (void*)window;
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWindowWMInfo(window, &info))
|
||||
@ -421,6 +441,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
|
||||
// Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
|
||||
@ -583,8 +604,11 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
|
||||
static void ImGui_ImplSDL2_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
// Remove this check because we always want to be able to trigger the menu via controller
|
||||
// The ImGuiConfigFlags_NavEnableGamepad is still separately used by ImGui for enabling imgui navigation
|
||||
// if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
// return;
|
||||
|
||||
// Get gamepad
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
@ -600,10 +624,17 @@ static void ImGui_ImplSDL2_UpdateGamepads()
|
||||
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
|
||||
MAP_BUTTON(ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START);
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK);
|
||||
#ifdef __SWITCH__
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_B); // Xbox A, PS Cross
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_A); // Xbox B, PS Circle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_Y); // Xbox X, PS Square
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_X); // Xbox Y, PS Triangle
|
||||
#else
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle
|
||||
#endif
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||
@ -757,6 +788,7 @@ static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
|
||||
SDL_GL_MakeCurrent(vd->Window, backup_context);
|
||||
|
||||
viewport->PlatformHandle = (void*)vd->Window;
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWindowWMInfo(vd->Window, &info))
|
||||
@ -767,6 +799,7 @@ static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
|
||||
viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
|
||||
|
@ -51,12 +51,6 @@ namespace Ship
|
||||
F64 = 10
|
||||
};
|
||||
|
||||
enum class Endianess
|
||||
{
|
||||
Little = 0,
|
||||
Big = 1,
|
||||
};
|
||||
|
||||
enum class Version
|
||||
{
|
||||
// BR
|
||||
@ -90,7 +84,7 @@ namespace Ship
|
||||
class ResourceFile
|
||||
{
|
||||
public:
|
||||
Endianess endianess; // 0x00 - Endianess of the file
|
||||
Endianness endianness; // 0x00 - Endianness of the file
|
||||
uint32_t resourceType; // 0x01 - 4 byte MAGIC
|
||||
Version version; // 0x05 - Based on Ship release numbers
|
||||
uint64_t id; // 0x09 - Unique Resource ID
|
||||
|
@ -10,7 +10,7 @@ namespace Ship {
|
||||
SDL_AudioSpec want, have;
|
||||
SDL_zero(want);
|
||||
want.freq = this->GetSampleRate();
|
||||
want.format = AUDIO_S16;
|
||||
want.format = AUDIO_S16SYS;
|
||||
want.channels = 2;
|
||||
want.samples = 1024;
|
||||
want.callback = NULL;
|
||||
|
@ -4,6 +4,10 @@
|
||||
#include "Window.h"
|
||||
#include <Utils/StringHelper.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
extern "C" uint8_t __osMaxControllers;
|
||||
|
||||
namespace Ship {
|
||||
@ -25,11 +29,16 @@ namespace Ship {
|
||||
|
||||
char GuidBuf[33];
|
||||
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(physicalSlot), GuidBuf, sizeof(GuidBuf));
|
||||
GUID = std::string(GuidBuf);
|
||||
Cont = NewCont;
|
||||
wCamX = 0;
|
||||
wCamY = 0;
|
||||
|
||||
#ifdef __SWITCH__
|
||||
GUID = StringHelper::Sprintf("%s:%d", GuidBuf, physicalSlot);
|
||||
ControllerName = StringHelper::Sprintf("%s #%d", SDL_GameControllerNameForIndex(physicalSlot), physicalSlot + 1);
|
||||
#else
|
||||
GUID = std::string(GuidBuf);
|
||||
ControllerName = std::string(SDL_GameControllerNameForIndex(physicalSlot));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -441,7 +450,7 @@ namespace Ship {
|
||||
}
|
||||
|
||||
const char* SDLController::GetControllerName() {
|
||||
return SDL_GameControllerNameForIndex(physicalSlot);
|
||||
return strdup(ControllerName.c_str());
|
||||
}
|
||||
|
||||
void SDLController::CreateDefaultBinding(int32_t slot) {
|
||||
|
@ -31,6 +31,7 @@ namespace Ship {
|
||||
void CreateDefaultBinding(int32_t slot) override;
|
||||
|
||||
private:
|
||||
std::string ControllerName = "Unknown";
|
||||
SDL_GameController* Cont;
|
||||
int physicalSlot;
|
||||
bool supportsGyro;
|
||||
|
286
libultraship/libultraship/SwitchImpl.cpp
Normal file
286
libultraship/libultraship/SwitchImpl.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
#ifdef __SWITCH__
|
||||
#include "SwitchImpl.h"
|
||||
#include <switch.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include "SwitchPerformanceProfiles.h"
|
||||
#include "Cvar.h"
|
||||
#include "Hooks.h"
|
||||
|
||||
extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue);
|
||||
extern "C" void CVar_SetS32(const char* name, s32 value);
|
||||
|
||||
#define DOCKED_MODE 1
|
||||
#define HANDHELD_MODE 0
|
||||
|
||||
static AppletHookCookie applet_hook_cookie;
|
||||
static bool isRunning = true;
|
||||
static bool hasFocus = true;
|
||||
|
||||
void DetectAppletMode();
|
||||
|
||||
static void on_applet_hook(AppletHookType hook, void *param);
|
||||
|
||||
void Ship::Switch::Init(SwitchPhase phase){
|
||||
switch(phase){
|
||||
case PreInitPhase:
|
||||
DetectAppletMode();
|
||||
break;
|
||||
case PostInitPhase:
|
||||
appletInitializeGamePlayRecording();
|
||||
#ifdef DEBUG
|
||||
socketInitializeDefault();
|
||||
nxlinkStdio();
|
||||
#endif
|
||||
appletSetGamePlayRecordingState(true);
|
||||
appletHook(&applet_hook_cookie, on_applet_hook, NULL);
|
||||
appletSetFocusHandlingMode(AppletFocusHandlingMode_NoSuspend);
|
||||
if (!hosversionBefore(8, 0, 0)) {
|
||||
clkrstInitialize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::Switch::Exit(){
|
||||
#ifdef DEBUG
|
||||
socketExit();
|
||||
#endif
|
||||
clkrstExit();
|
||||
appletSetGamePlayRecordingState(false);
|
||||
}
|
||||
|
||||
void Ship::Switch::SetupFont(ImFontAtlas* fonts) {
|
||||
plInitialize(PlServiceType_System);
|
||||
static PlFontData stdFontData, extFontData;
|
||||
|
||||
PlFontData fonts_std;
|
||||
PlFontData fonts_ext;
|
||||
|
||||
plGetSharedFontByType(&fonts_std, PlSharedFontType_Standard);
|
||||
plGetSharedFontByType(&fonts_ext, PlSharedFontType_NintendoExt);
|
||||
|
||||
ImFontConfig config;
|
||||
config.FontDataOwnedByAtlas = false;
|
||||
|
||||
strcpy(config.Name, "Nintendo Standard");
|
||||
fonts->AddFontFromMemoryTTF (fonts_std.address, fonts_std.size, 24.0f, &config, fonts->GetGlyphRangesCyrillic());
|
||||
|
||||
strcpy(config.Name, "Nintendo Ext");
|
||||
static const ImWchar ranges[] =
|
||||
{
|
||||
0xE000, 0xE06B,
|
||||
0xE070, 0xE07E,
|
||||
0xE080, 0xE099,
|
||||
0xE0A0, 0xE0BA,
|
||||
0xE0C0, 0xE0D6,
|
||||
0xE0E0, 0xE0F5,
|
||||
0xE100, 0xE105,
|
||||
0xE110, 0xE116,
|
||||
0xE121, 0xE12C,
|
||||
0xE130, 0xE13C,
|
||||
0xE140, 0xE14D,
|
||||
0xE150, 0xE153,
|
||||
0,
|
||||
};
|
||||
|
||||
fonts->AddFontFromMemoryTTF (fonts_ext.address, fonts_ext.size, 24.0f, &config, ranges);
|
||||
fonts->Build ();
|
||||
|
||||
plExit();
|
||||
}
|
||||
|
||||
bool Ship::Switch::IsRunning(){
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
void Ship::Switch::GetDisplaySize(int *width, int *height) {
|
||||
switch (appletGetOperationMode()) {
|
||||
case DOCKED_MODE:
|
||||
*width = 1920;
|
||||
*height = 1080;
|
||||
break;
|
||||
case HANDHELD_MODE:
|
||||
*width = 1280;
|
||||
*height = 720;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::Switch::ApplyOverclock(void) {
|
||||
SwitchProfiles perfMode = (SwitchProfiles) CVar_GetS32("gSwitchPerfMode", (int) Ship::MAXIMUM);
|
||||
|
||||
if (perfMode >= 0 && perfMode <= Ship::POWERSAVINGM3) {
|
||||
if (hosversionBefore(8, 0, 0)) {
|
||||
pcvSetClockRate(PcvModule_CpuBus, SWITCH_CPU_SPEEDS_VALUES[ perfMode ]);
|
||||
} else {
|
||||
ClkrstSession session = {0};
|
||||
clkrstOpenSession(&session, PcvModuleId_CpuBus, 3);
|
||||
clkrstSetClockRate(&session, SWITCH_CPU_SPEEDS_VALUES[ perfMode ]);
|
||||
clkrstCloseSession(&session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Star {
|
||||
SDL_Rect* rect;
|
||||
float speed;
|
||||
int layer;
|
||||
int8_t color[3];
|
||||
};
|
||||
|
||||
std::vector<Star*> stars;
|
||||
|
||||
void Ship::Switch::PrintErrorMessageToScreen(const char *str, ...) {
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
return;
|
||||
|
||||
int width, height;
|
||||
Uint64 now, last, deltaTime;
|
||||
GetDisplaySize(&width, &height);
|
||||
|
||||
SDL_Window* win = SDL_CreateWindow("Switch-Error", 0, 0, width, height, 0);
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
||||
va_list args;
|
||||
va_start(args, str);
|
||||
vprintf(str, args);
|
||||
va_end(args);
|
||||
|
||||
int layers = 9;
|
||||
|
||||
for(int layer = 0; layer < layers; layer++) {
|
||||
for(int i = 0; i < 100; i++) {
|
||||
srand(time(0));
|
||||
|
||||
int brightness = 50 - layer * (rand() * 5);
|
||||
SDL_Rect rect;
|
||||
rect.x = rand() % width;
|
||||
rect.y = i*i;
|
||||
rect.w = rand() % 20;
|
||||
rect.h = rand() % 20;
|
||||
|
||||
stars.push_back(new Star{
|
||||
&rect,
|
||||
0.03f,
|
||||
layer,
|
||||
{
|
||||
120 + brightness,
|
||||
120 + brightness,
|
||||
120 + brightness
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
while(appletMainLoop()){
|
||||
SDL_Event e;
|
||||
if ( SDL_PollEvent(&e) ) {
|
||||
if (e.type == SDL_QUIT)
|
||||
break;
|
||||
}
|
||||
|
||||
last = now;
|
||||
now = SDL_GetPerformanceCounter();
|
||||
|
||||
deltaTime = (double)((now - last) * 1000 / (double) SDL_GetPerformanceFrequency() );
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
for(int i = 0; i < stars.size(); i++){
|
||||
Star* star = stars[i];
|
||||
|
||||
if(star->rect->x >= width){
|
||||
star->rect->x = -star->rect->w;
|
||||
}
|
||||
|
||||
star->rect->x += 1;
|
||||
// star->rect->y += (cos((star->rect->x / star->layer)) * .9f ) / 16;
|
||||
SDL_SetRenderDrawColor(renderer, star->color[0], star->color[1], star->color[2], 255);
|
||||
SDL_RenderFillRect( renderer, star->rect );
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
SDL_Delay(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void on_applet_hook(AppletHookType hook, void *param) {
|
||||
AppletFocusState focus_state;
|
||||
|
||||
/* Exit request */
|
||||
switch (hook) {
|
||||
case AppletHookType_OnExitRequest:
|
||||
isRunning = false;
|
||||
break;
|
||||
|
||||
/* Focus state*/
|
||||
case AppletHookType_OnFocusState:
|
||||
focus_state = appletGetFocusState();
|
||||
hasFocus = focus_state == AppletFocusState_InFocus;
|
||||
|
||||
if (!hasFocus) {
|
||||
if (hosversionBefore(8, 0, 0)) {
|
||||
pcvSetClockRate(PcvModule_CpuBus, SWITCH_CPU_SPEEDS_VALUES[ Ship::STOCK ]);
|
||||
} else {
|
||||
ClkrstSession session = {0};
|
||||
clkrstOpenSession(&session, PcvModuleId_CpuBus, 3);
|
||||
clkrstSetClockRate(&session, SWITCH_CPU_SPEEDS_VALUES[ Ship::STOCK ]);
|
||||
clkrstCloseSession(&session);
|
||||
}
|
||||
} else
|
||||
Ship::Switch::ApplyOverclock();
|
||||
break;
|
||||
|
||||
/* Performance mode */
|
||||
case AppletHookType_OnPerformanceMode:
|
||||
Ship::Switch::ApplyOverclock();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
const char* RandomTexts[] = {
|
||||
"Psst, don't forget to blame Melon",
|
||||
"Potsanity when?",
|
||||
"Why are you acting so random?",
|
||||
"Enough! My ship sails in the morning",
|
||||
"Do you want 2 or 7 of those?",
|
||||
"Lamp oil, rope, bombs you want it, it's yours my friend as long as you have enough rupees",
|
||||
"You can build it yourself",
|
||||
"Descargar para android",
|
||||
"Made with <3 by the Harbour Masters!",
|
||||
"They say that Kenix is not a developer",
|
||||
"Squadala we're off",
|
||||
"They say one once saw an equals not get set equals",
|
||||
"This is the port all true gamers dock at"
|
||||
"Enhancements? Times Savers? Cheats? You want them? They're yours my friend!",
|
||||
"They say you gotta have the BIIIIG salad",
|
||||
"They say Louis stopped working on the imports so he can focus on the exports",
|
||||
"They say ZAPD is good software",
|
||||
};
|
||||
|
||||
void DetectAppletMode() {
|
||||
AppletType at = appletGetAppletType();
|
||||
if (at == AppletType_Application || at == AppletType_SystemApplication)
|
||||
return;
|
||||
|
||||
srand(time(0));
|
||||
Ship::Switch::PrintErrorMessageToScreen(
|
||||
"\x1b[2;2HYou've launched the Ship while in Applet mode."
|
||||
"\x1b[4;2HPlease relaunch while in full-memory mode."
|
||||
"\x1b[5;2HHold R when opening any game to enter HBMenu."
|
||||
"\x1b[44;2H%s."
|
||||
, RandomTexts[rand() % 25]);
|
||||
}
|
||||
|
||||
void Ship::Switch::ThrowMissingOTR(std::string OTRPath){
|
||||
Ship::Switch::PrintErrorMessageToScreen(
|
||||
"\x1b[2;2HYou've launched the Ship without the OTR file."
|
||||
"\x1b[4;2HPlease relaunch making sure %s exists."
|
||||
"\x1b[44;2H%s."
|
||||
, OTRPath.c_str(), RandomTexts[rand() % 25]);
|
||||
}
|
||||
#endif
|
36
libultraship/libultraship/SwitchImpl.h
Normal file
36
libultraship/libultraship/SwitchImpl.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
#include "SwitchPerformanceProfiles.h"
|
||||
|
||||
namespace Ship {
|
||||
enum SwitchProfiles {
|
||||
MAXIMUM,
|
||||
HIGH,
|
||||
BOOST,
|
||||
STOCK,
|
||||
POWERSAVINGM1,
|
||||
POWERSAVINGM2,
|
||||
POWERSAVINGM3
|
||||
};
|
||||
|
||||
enum SwitchPhase {
|
||||
PreInitPhase,
|
||||
PostInitPhase
|
||||
};
|
||||
|
||||
class Switch {
|
||||
public:
|
||||
static void Init(SwitchPhase phase);
|
||||
static void Exit();
|
||||
static void SetupFont(ImFontAtlas* fonts);
|
||||
static bool IsRunning();
|
||||
static void GetDisplaySize(int *width, int *height);
|
||||
static void ApplyOverclock();
|
||||
static void ThrowMissingOTR(std::string OTRPath);
|
||||
static void PrintErrorMessageToScreen(const char *str, ...);
|
||||
};
|
||||
};
|
21
libultraship/libultraship/SwitchPerformanceProfiles.h
Normal file
21
libultraship/libultraship/SwitchPerformanceProfiles.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
static const char *SWITCH_CPU_PROFILES[] = {
|
||||
"Maximum Performance",
|
||||
"High Performance",
|
||||
"Boost Performance",
|
||||
"Stock Performance",
|
||||
"Powersaving Mode 1",
|
||||
"Powersaving Mode 2",
|
||||
"Powersaving Mode 3",
|
||||
};
|
||||
|
||||
static unsigned SWITCH_CPU_SPEEDS_VALUES[] = {
|
||||
1785000000,
|
||||
1581000000,
|
||||
1224000000,
|
||||
1020000000,
|
||||
918000000,
|
||||
816000000,
|
||||
714000000
|
||||
};
|
@ -28,14 +28,16 @@
|
||||
#include <chrono>
|
||||
#include "Hooks.h"
|
||||
#include "Console.h"
|
||||
#include "Cvar.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define LOAD_TEX(texPath) static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
|
||||
|
||||
extern "C" {
|
||||
struct OSMesgQueue;
|
||||
|
||||
uint8_t __osMaxControllers = MAXCONTROLLERS;
|
||||
uint8_t __enableGameInput = 1;
|
||||
|
||||
int32_t osContInit(OSMesgQueue* mq, uint8_t* controllerBits, OSContStatus* status) {
|
||||
*controllerBits = 0;
|
||||
@ -45,6 +47,7 @@ extern "C" {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef __SWITCH__
|
||||
const char* controllerDb = "gamecontrollerdb.txt";
|
||||
int mappingsAdded = SDL_GameControllerAddMappingsFromFile(controllerDb);
|
||||
if (mappingsAdded >= 0) {
|
||||
@ -52,6 +55,7 @@ extern "C" {
|
||||
} else {
|
||||
SPDLOG_ERROR("Failed add SDL game controller mappings from \"{}\" ({})", controllerDb, SDL_GetError());
|
||||
}
|
||||
#endif
|
||||
|
||||
Ship::Window::ControllerApi->Init(controllerBits);
|
||||
|
||||
@ -72,7 +76,7 @@ extern "C" {
|
||||
pad->gyro_x = 0;
|
||||
pad->gyro_y = 0;
|
||||
|
||||
if (__enableGameInput) {
|
||||
if (!CVar_GetS32("gOpenMenuBar", 0)) {
|
||||
Ship::Window::ControllerApi->WriteToPad(pad);
|
||||
}
|
||||
|
||||
@ -121,8 +125,7 @@ extern "C" {
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (hashStr != nullptr) {
|
||||
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get());
|
||||
|
||||
const auto res = LOAD_TEX(hashStr->c_str());
|
||||
ModInternal::ExecuteHooks<ModInternal::LoadTexture>(hashStr->c_str(), &res->imageData);
|
||||
|
||||
return reinterpret_cast<char*>(res->imageData);
|
||||
@ -149,13 +152,40 @@ extern "C" {
|
||||
}
|
||||
|
||||
char* ResourceMgr_LoadTexByName(char* texPath) {
|
||||
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
|
||||
const auto res = LOAD_TEX(texPath);
|
||||
ModInternal::ExecuteHooks<ModInternal::LoadTexture>(texPath, &res->imageData);
|
||||
return (char*)res->imageData;
|
||||
}
|
||||
|
||||
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath) {
|
||||
const auto res = LOAD_TEX(texPath);
|
||||
if (res != nullptr)
|
||||
return res->width;
|
||||
|
||||
SPDLOG_ERROR("Given texture path is a non-existent resource");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t ResourceMgr_LoadTexHeightByName(char* texPath) {
|
||||
const auto res = LOAD_TEX(texPath);
|
||||
if (res != nullptr)
|
||||
return res->height;
|
||||
|
||||
SPDLOG_ERROR("Given texture path is a non-existent resource");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ResourceMgr_LoadTexSizeByName(char* texPath) {
|
||||
const auto res = LOAD_TEX(texPath);
|
||||
if (res != nullptr)
|
||||
return res->imageDataSize;
|
||||
|
||||
SPDLOG_ERROR("Given texture path is a non-existent resource");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ResourceMgr_WriteTexS16ByName(char* texPath, size_t index, s16 value) {
|
||||
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
|
||||
const auto res = LOAD_TEX(texPath);
|
||||
|
||||
if (res != nullptr)
|
||||
{
|
||||
@ -302,7 +332,6 @@ namespace Ship {
|
||||
void Window::MainLoop(void (*MainFunction)(void)) {
|
||||
WmApi->main_loop(MainFunction);
|
||||
}
|
||||
|
||||
bool Window::KeyUp(int32_t dwScancode) {
|
||||
std::shared_ptr<Mercury> pConf = GlobalCtx2::GetInstance()->GetConfig();
|
||||
|
||||
|
@ -22,7 +22,7 @@ void SetWindowManager(struct GfxWindowManagerAPI** WmApi, struct GfxRenderingAPI
|
||||
// First set default
|
||||
#ifdef ENABLE_OPENGL
|
||||
*RenderingApi = &gfx_opengl_api;
|
||||
#if defined(__linux__)
|
||||
#if defined(__linux__) && defined(X11_SUPPORTED)
|
||||
// LINUX_TODO:
|
||||
// *WmApi = &gfx_glx;
|
||||
*WmApi = &gfx_sdl;
|
||||
@ -51,7 +51,7 @@ void SetWindowManager(struct GfxWindowManagerAPI** WmApi, struct GfxRenderingAPI
|
||||
*RenderingApi = &gfx_opengl_api;
|
||||
*WmApi = &gfx_sdl;
|
||||
}
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) && defined(X11_SUPPORTED)
|
||||
if (gfx_backend == "glx") {
|
||||
*RenderingApi = &gfx_opengl_api;
|
||||
*WmApi = &gfx_glx;
|
||||
|
50
libultraship/libultraship/color.h
Normal file
50
libultraship/libultraship/color.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "endianness.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t r, g, b;
|
||||
} Color_RGB8;
|
||||
|
||||
typedef struct {
|
||||
uint8_t r, g, b, a;
|
||||
} Color_RGBA8;
|
||||
|
||||
// only use when necessary for alignment purposes
|
||||
typedef union {
|
||||
struct {
|
||||
#ifdef IS_BIGENDIAN
|
||||
uint8_t r, g, b, a;
|
||||
#else
|
||||
uint8_t a, b, g, r;
|
||||
#endif
|
||||
};
|
||||
uint32_t rgba;
|
||||
} Color_RGBA8_u32;
|
||||
|
||||
typedef struct {
|
||||
float r, g, b, a;
|
||||
} Color_RGBAf;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint16_t r : 5;
|
||||
uint16_t g : 5;
|
||||
uint16_t b : 5;
|
||||
uint16_t a : 1;
|
||||
};
|
||||
uint16_t rgba;
|
||||
} Color_RGBA16;
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
67
libultraship/libultraship/endianness.h
Normal file
67
libultraship/libultraship/endianness.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef ENDIANESS_H
|
||||
#define ENDIANESS_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BOMSWAP16 _byteswap_ushort
|
||||
#define BOMSWAP32 _byteswap_ulong
|
||||
#define BOMSWAP64 _byteswap_uint64
|
||||
|
||||
#define BOMSWAP16_CONST(x) \
|
||||
((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
|
||||
#define BOMSWAP32_CONST(x) \
|
||||
((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \
|
||||
(((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000))
|
||||
#define BOMSWAP64_CONST(x) \
|
||||
((((x) >> 56) & 0x00000000000000FF) | (((x) >> 40) & 0x000000000000FF00) | \
|
||||
(((x) >> 24) & 0x0000000000FF0000) | (((x) >> 8) & 0x00000000FF000000) | \
|
||||
(((x) << 8) & 0x000000FF00000000) | (((x) << 24) & 0x0000FF0000000000) | \
|
||||
(((x) << 40) & 0x00FF000000000000) | (((x) << 56) & 0xFF00000000000000))
|
||||
#else
|
||||
#define BOMSWAP16 __builtin_bswap16
|
||||
#define BOMSWAP32 __builtin_bswap32
|
||||
#define BOMSWAP64 __builtin_bswap64
|
||||
|
||||
#define BOMSWAP16_CONST __builtin_bswap16
|
||||
#define BOMSWAP32_CONST __builtin_bswap32
|
||||
#define BOMSWAP64_CONST __builtin_bswap64
|
||||
#endif
|
||||
|
||||
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
|
||||
#ifndef IS_BIGENDIAN
|
||||
#define IS_BIGENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef IS_BIGENDIAN
|
||||
#define BE16SWAP(x) (x)
|
||||
#define BE32SWAP(x) (x)
|
||||
#define BE64SWAP(x) (x)
|
||||
#define LE16SWAP(x) BOMSWAP16(x)
|
||||
#define LE32SWAP(x) BOMSWAP32(x)
|
||||
#define LE64SWAP(x) BOMSWAP64(x)
|
||||
|
||||
#define BE16SWAP_CONST(x) (x)
|
||||
#define BE32SWAP_CONST(x) (x)
|
||||
#define BE64SWAP_CONST(x) (x)
|
||||
#define LE16SWAP_CONST(x) BOMSWAP16_CONST(x)
|
||||
#define LE32SWAP_CONST(x) BOMSWAP32_CONST(x)
|
||||
#define LE64SWAP_CONST(x) BOMSWAP64_CONST(x)
|
||||
#else
|
||||
#define BE16SWAP(x) BOMSWAP16(x)
|
||||
#define BE32SWAP(x) BOMSWAP32(x)
|
||||
#define BE64SWAP(x) BOMSWAP64(x)
|
||||
#define LE16SWAP(x) (x)
|
||||
#define LE32SWAP(x) (x)
|
||||
#define LE64SWAP(x) (x)
|
||||
|
||||
#define BE16SWAP_CONST(x) BOMSWAP16_CONST(x)
|
||||
#define BE32SWAP_CONST(x) BOMSWAP32_CONST(x)
|
||||
#define BE64SWAP_CONST(x) BOMSWAP64_CONST(x)
|
||||
#define LE16SWAP_CONST(x) (x)
|
||||
#define LE32SWAP_CONST(x) (x)
|
||||
#define LE64SWAP_CONST(x) (x)
|
||||
#endif
|
||||
|
||||
#endif
|
@ -351,6 +351,7 @@
|
||||
<ClInclude Include="Audio.h" />
|
||||
<ClInclude Include="AudioPlayer.h" />
|
||||
<ClInclude Include="Blob.h" />
|
||||
<ClInclude Include="color.h" />
|
||||
<ClInclude Include="ControlDeck.h" />
|
||||
<ClInclude Include="Cvar.h" />
|
||||
<ClInclude Include="Environment.h" />
|
||||
@ -450,12 +451,6 @@
|
||||
<ClInclude Include="SDLController.h" />
|
||||
<ClInclude Include="WindowShim.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OTRGui\build\ZERO_CHECK.vcxproj">
|
||||
<Project>{02d10590-9542-3f55-aaf8-6055677e2a2a}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -653,6 +653,9 @@
|
||||
<ClInclude Include="GameVersions.h">
|
||||
<Filter>Source Files\Resources</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="color.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GameOverlay.h">
|
||||
<Filter>Source Files\CustomImpl\Overlay</Filter>
|
||||
</ClInclude>
|
||||
|
@ -6,7 +6,7 @@ curl -sSfL https://github.com$(curl https://github.com/probonopd/go-appimage/rel
|
||||
chmod a+x mkappimage.AppImage
|
||||
|
||||
mkdir -p AppDir/usr/bin
|
||||
cp appimage/{soh.desktop,soh.sh} AppDir/
|
||||
cp scripts/linux/{soh.desktop,soh.sh} AppDir/
|
||||
cp soh/macosx/sohIcon.png AppDir/soh.png
|
||||
curl -sSfL https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt -o AppDir/usr/bin/gamecontrollerdb.txt
|
||||
|
11
scripts/linux/build.sh
Executable file
11
scripts/linux/build.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd soh
|
||||
make setup -j$(nproc) OPTFLAGS=-O2 DEBUG=0
|
||||
make -j$(nproc) OPTFLAGS=-O2 DEBUG=0
|
||||
|
||||
cd ../OTRGui
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . --config Release
|
4
scripts/switch/build.sh
Executable file
4
scripts/switch/build.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
make setup -C soh -j$(nproc) OPTFLAGS=-O2 DEBUG=0
|
||||
make -f Makefile.switch -j$(nproc)
|
71
soh/Makefile
71
soh/Makefile
@ -16,26 +16,35 @@ DEBUG ?= 1
|
||||
OPTFLAGS ?= -O0
|
||||
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)
|
||||
|
||||
WARN := \
|
||||
-Wno-return-type \
|
||||
-Wno-unused-command-line-argument \
|
||||
-Wno-implicit-function-declaration \
|
||||
-Wno-c++11-narrowing \
|
||||
-funsigned-char \
|
||||
-fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -ffreestanding -fwrapv \
|
||||
|
||||
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -no-pie -nostdlib
|
||||
CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -no-pie -nostdlib
|
||||
LDFLAGS :=
|
||||
|
||||
ifeq ($(UNAME), Linux) #LINUX
|
||||
CXXFLAGS += -mhard-float -msse2 -mfpmath=sse
|
||||
CFLAGS += -mhard-float -msse2 -mfpmath=sse
|
||||
ifeq ($(CXX_IS_CLANG),1)
|
||||
WARN += -Wno-c++11-narrowing
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin) #APPLE
|
||||
CXXFLAGS += $(shell pkg-config --cflags sdl2) $(shell sdl2-config --cflags) $(shell pkg-config --cflags glew) -framework OpenGL
|
||||
CFLAGS += $(shell pkg-config --cflags sdl2) $(shell sdl2-config --cflags) $(shell pkg-config --cflags glew) -framework OpenGL
|
||||
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -nostdlib $(shell pkg-config --cflags glew) $(shell sdl2-config --cflags)
|
||||
CFLAGS := $(WARN) -std=c99 -Wno-implicit-function-declaration -D_GNU_SOURCE -nostdlib $(shell pkg-config --cflags glew) $(shell sdl2-config --cflags)
|
||||
LDFLAGS :=
|
||||
|
||||
ifneq ($(CXX_IS_CLANG),1)
|
||||
CXXFLAGS += -no-pie
|
||||
CFLAGS += -no-pie
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Linux)
|
||||
ifeq ($(UNAMEM), x86_64)
|
||||
CXXFLAGS += -msse2 -mfpmath=sse -mhard-float
|
||||
CFLAGS += -msse2 -mfpmath=sse -mhard-float
|
||||
endif
|
||||
|
||||
CXXFLAGS += $(shell pkg-config --cflags libpulse)
|
||||
CFLAGS += $(shell pkg-config --cflags libpulse)
|
||||
endif
|
||||
|
||||
CPPFLAGS := -MMD
|
||||
@ -57,11 +66,11 @@ ifneq ($(LTO),0)
|
||||
LDFLAGS += -flto
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Linux) #LINUX
|
||||
ifeq ($(UNAME), Linux)
|
||||
TARGET := soh.elf
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin) #APPLE
|
||||
ifeq ($(UNAME), Darwin)
|
||||
TARGET := soh-$(UNAMEM)
|
||||
endif
|
||||
|
||||
@ -78,25 +87,15 @@ INC_DIRS := $(addprefix -I, \
|
||||
../libultraship/libultraship/Lib/Fast3D/U64/PR \
|
||||
)
|
||||
|
||||
ifeq ($(UNAME), Linux) #LINUX
|
||||
INC_DIRS += $(addprefix -I, \
|
||||
/opt/X11/include \
|
||||
)
|
||||
endif
|
||||
|
||||
LDDIRS := $(addprefix -L, \
|
||||
../libultraship/ \
|
||||
)
|
||||
|
||||
ifeq ($(UNAME), Linux) #LINUX
|
||||
LDDIRS += $(addprefix -L, \
|
||||
/opt/X11/lib \
|
||||
)
|
||||
endif
|
||||
|
||||
LDLIBS := \
|
||||
$(ZAPDUTILS) \
|
||||
$(LIBSTORM) \
|
||||
$(shell sdl2-config --libs) \
|
||||
$(shell pkg-config --libs glew) \
|
||||
$(addprefix -l, \
|
||||
dl \
|
||||
bz2 \
|
||||
@ -105,24 +104,16 @@ LDLIBS := \
|
||||
ultraship \
|
||||
)
|
||||
|
||||
ifeq ($(UNAME), Linux) #LINUX
|
||||
LDLIBS += \
|
||||
$(addprefix -l, \
|
||||
X11 \
|
||||
SDL2 \
|
||||
GL \
|
||||
GLEW \
|
||||
pulse \
|
||||
)
|
||||
ifeq ($(UNAME), Linux)
|
||||
LDLIBS += $(shell pkg-config --libs x11 libpulse)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin) #APPLE
|
||||
ifeq ($(UNAME), Darwin)
|
||||
LDLIBS += \
|
||||
$(addprefix -framework , \
|
||||
OpenGL \
|
||||
Foundation \
|
||||
) \
|
||||
$(shell sdl2-config --libs) $(shell pkg-config --libs glew)
|
||||
)
|
||||
endif
|
||||
|
||||
ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*")
|
||||
@ -179,7 +170,7 @@ all:
|
||||
$(MAKE) $(TARGET)
|
||||
|
||||
setup:
|
||||
cd ../OTRExporter && python3 extract_baserom.py
|
||||
cd ../OTRExporter
|
||||
$(MAKE) mpq
|
||||
|
||||
mpq:
|
||||
|
280
soh/Makefile.switch
Normal file
280
soh/Makefile.switch
Normal file
@ -0,0 +1,280 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
|
||||
#
|
||||
# NO_ICON: if set to anything, do not use icon.
|
||||
# NO_NACP: if set to anything, no .nacp file is generated.
|
||||
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
|
||||
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
|
||||
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
|
||||
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
|
||||
# ICON is the filename of the icon (.jpg), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.jpg
|
||||
# - icon.jpg
|
||||
# - <libnx folder>/default_icon.jpg
|
||||
#
|
||||
# CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
|
||||
# If not set, it attempts to use one of the following (in this order):
|
||||
# - <Project name>.json
|
||||
# - config.json
|
||||
# If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
|
||||
# of a homebrew executable (.nro). This is intended to be used for sysmodules.
|
||||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := switch
|
||||
DATA :=
|
||||
INCLUDES := \
|
||||
. \
|
||||
assets \
|
||||
build \
|
||||
include \
|
||||
src \
|
||||
../ZAPDTR/ZAPDUtils \
|
||||
../libultraship/libultraship \
|
||||
../libultraship/libultraship/Lib/spdlog/include \
|
||||
../libultraship/libultraship/Lib/Fast3D/U64 \
|
||||
../libultraship/libultraship/Lib/Fast3D/U64/PR
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# source files
|
||||
#-------------------------------------------------------------------------------
|
||||
SOURCEFILES_C := \
|
||||
$(shell find soh -type f -name "*.c") \
|
||||
$(shell find src/boot -type f -name "*.c") \
|
||||
$(shell find src/buffers -type f -name "*.c") \
|
||||
$(shell find src/code -type f -name "*.c") \
|
||||
$(shell find src/overlays -type f -name "*.c") \
|
||||
src/libultra/gu/coss.c \
|
||||
src/libultra/gu/guLookAt.c \
|
||||
src/libultra/gu/guLookAtHilite.c \
|
||||
src/libultra/gu/guPerspectiveF.c \
|
||||
src/libultra/gu/guPosition.c \
|
||||
src/libultra/gu/guS2DInitBg.c \
|
||||
src/libultra/gu/ortho.c \
|
||||
src/libultra/gu/rotate.c \
|
||||
src/libultra/gu/sins.c \
|
||||
src/libultra/gu/sintable.c \
|
||||
src/libultra/libc/sprintf.c
|
||||
|
||||
SOURCEFILES_CPP := \
|
||||
$(shell find soh -type f -name "*.cpp")
|
||||
#---------------------------------------------------------------------------------
|
||||
# app info
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
APP_TITLE := Ship of Harkinian
|
||||
APP_AUTHOR := Harbour Masters
|
||||
APP_VERSION := Rachael-Alfa
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE -ffast-math -O3
|
||||
|
||||
CFLAGS := -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ \
|
||||
-DSPDLOG_NO_THREAD_ID \
|
||||
-DSTBI_NO_THREAD_LOCALS \
|
||||
`sdl2-config --cflags`
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++20 -fpermissive
|
||||
CFLAGS += -std=gnu11
|
||||
|
||||
# disable some warnings
|
||||
CFLAGS += -Wno-incompatible-pointer-types -Wno-int-conversion \
|
||||
-Wno-builtin-declaration-mismatch -Wno-implicit-function-declaration \
|
||||
-Wno-stringop-overflow -Wno-discarded-qualifiers -Wno-switch-unreachable
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
STATIC_LIBS := $(SOH_TOP_DIR)/libultraship/lib/libultraship.a \
|
||||
$(SOH_TOP_DIR)/ZAPDTR/ZAPDUtils/lib/libZAPDUtils.a \
|
||||
$(SOH_TOP_DIR)/ZAPDTR/ZAPDUtils/lib/libZAPDUtils.a \
|
||||
$(SOH_TOP_DIR)/StormLib/nxbuild/libstorm.a \
|
||||
|
||||
LIBS := -L$(SOH_TOP_DIR)/StormLib/nxbuild/ -lultraship -lZAPDUtils -lstorm -lz -lbz2 -lnx -lglad -lglapi -ldrm_nouveau -lm `sdl2-config --libs`
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(SOH_TOP_DIR)/StormLib/nxbuild $(SOH_TOP_DIR)/libultraship $(SOH_TOP_DIR)/ZAPDTR/ZAPDUtils
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||
$(foreach sf,$(SOURCEFILES_C),$(CURDIR)/$(dir $(sf))) \
|
||||
$(foreach sf,$(SOURCEFILES_CPP),$(CURDIR)/$(dir $(sf)))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) \
|
||||
$(foreach f,$(SOURCEFILES_C),$(notdir $(f)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) \
|
||||
$(foreach f,$(SOURCEFILES_CPP),$(notdir $(f)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
ifeq ($(strip $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
||||
else
|
||||
ifneq (,$(findstring config.json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/config.json
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ICON)),)
|
||||
icons := $(wildcard *.jpg)
|
||||
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
|
||||
else
|
||||
ifneq (,$(findstring icon.jpg,$(icons)))
|
||||
export APP_ICON := $(TOPDIR)/icon.jpg
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_ICON := $(TOPDIR)/$(ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_ICON)),)
|
||||
export NROFLAGS += --icon=$(APP_ICON)
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(NO_NACP)),)
|
||||
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
|
||||
endif
|
||||
|
||||
ifneq ($(APP_TITLEID),)
|
||||
export NACPFLAGS += --titleid=$(APP_TITLEID)
|
||||
endif
|
||||
|
||||
ifneq ($(ROMFS),)
|
||||
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile.switch
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
|
||||
else
|
||||
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
|
||||
endif
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(APP_JSON)),)
|
||||
|
||||
all : $(OUTPUT).nro
|
||||
|
||||
ifeq ($(strip $(NO_NACP)),)
|
||||
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
|
||||
else
|
||||
$(OUTPUT).nro : $(OUTPUT).elf
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
all : $(OUTPUT).nsp
|
||||
|
||||
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
|
||||
|
||||
$(OUTPUT).nso : $(OUTPUT).elf
|
||||
|
||||
endif
|
||||
|
||||
$(OUTPUT).elf : $(OFILES) \
|
||||
$(STATIC_LIBS)
|
||||
|
||||
$(OFILES_SRC) : $(HFILES_BIN)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
BIN
soh/icon.jpg
Normal file
BIN
soh/icon.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
@ -1,34 +0,0 @@
|
||||
#ifndef COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
typedef struct {
|
||||
u8 r, g, b;
|
||||
} Color_RGB8;
|
||||
|
||||
typedef struct {
|
||||
u8 r, g, b, a;
|
||||
} Color_RGBA8;
|
||||
|
||||
// only use when necessary for alignment purposes
|
||||
typedef union {
|
||||
struct {
|
||||
u8 a, b, g, r;
|
||||
};
|
||||
u32 rgba;
|
||||
} Color_RGBA8_u32;
|
||||
|
||||
typedef struct {
|
||||
f32 r, g, b, a;
|
||||
} Color_RGBAf;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
u16 r : 5;
|
||||
u16 g : 5;
|
||||
u16 b : 5;
|
||||
u16 a : 1;
|
||||
};
|
||||
u16 rgba;
|
||||
} Color_RGBA16;
|
||||
|
||||
#endif
|
@ -6,6 +6,15 @@
|
||||
* Each macro packs bytes (B), halfwords (H) and words (W, for consistency) into a single word
|
||||
*/
|
||||
|
||||
#ifdef IS_BIGENDIAN
|
||||
#define CMD_BBBB(a, b, c, d) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 8, 8) | _SHIFTL(d, 0, 8))
|
||||
|
||||
#define CMD_BBH(a, b, c) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 0, 16))
|
||||
|
||||
#define CMD_HBB(a, b, c) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 0, 8))
|
||||
|
||||
#define CMD_HH(a, b) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 0, 16))
|
||||
#else
|
||||
#define CMD_BBBB(a, b, c, d) (_SHIFTL(a, 0, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 16, 8) | _SHIFTL(d, 24, 8))
|
||||
|
||||
#define CMD_BBH(a, b, c) (_SHIFTL(a, 0, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 16, 16))
|
||||
@ -13,6 +22,7 @@
|
||||
#define CMD_HBB(a, b, c) (_SHIFTL(a, 0, 16) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 24, 8))
|
||||
|
||||
#define CMD_HH(a, b) (_SHIFTL(a, 0, 16) | _SHIFTL(b, 16, 16))
|
||||
#endif
|
||||
|
||||
#define CMD_W(a) (a)
|
||||
|
||||
|
@ -60,7 +60,7 @@ void Locale_ResetRegion(void);
|
||||
u32 func_80001F48(void);
|
||||
u32 func_80001F8C(void);
|
||||
u32 Locale_IsRegionNative(void);
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__APPLE__) && !defined(__SWITCH__)
|
||||
void __assert(const char* exp, const char* file, s32 line);
|
||||
#endif
|
||||
void isPrintfInit(void);
|
||||
@ -1872,7 +1872,7 @@ void FaultDrawer_SetCharPad(s8, s8);
|
||||
void FaultDrawer_SetCursor(s32, s32);
|
||||
void FaultDrawer_FillScreen();
|
||||
void* FaultDrawer_FormatStringFunc(void*, const char*, u32);
|
||||
void FaultDrawer_VPrintf(const char*, char*);
|
||||
void FaultDrawer_VPrintf(const char*, va_list);
|
||||
void FaultDrawer_Printf(const char*, ...);
|
||||
void FaultDrawer_DrawText(s32, s32, const char*, ...);
|
||||
void FaultDrawer_SetDrawerFB(void*, u16, u16);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef MACROS_H
|
||||
#define MACROS_H
|
||||
|
||||
#include "endianness.h"
|
||||
|
||||
#define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0]))
|
||||
#define ARRAY_COUNTU(arr) (u32)(sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
@ -254,12 +256,5 @@ extern GraphicsContext* __gfxCtx;
|
||||
|
||||
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define BOMSWAP16 _byteswap_ushort
|
||||
#define BOMSWAP32 _byteswap_ulong
|
||||
#else
|
||||
#define BOMSWAP16 __builtin_bswap16
|
||||
#define BOMSWAP32 __builtin_bswap32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "ichain.h"
|
||||
#include "regs.h"
|
||||
|
||||
#if defined(_WIN64) || defined(__x86_64__) || defined(__arm64__)
|
||||
#if defined(__LP64__)
|
||||
#define _SOH64
|
||||
#endif
|
||||
|
||||
@ -1458,8 +1458,6 @@ typedef struct {
|
||||
/* 0x18 */ s16 (*roomCompassOffsetY)[44]; // dungeon compass icon Y offset by room
|
||||
/* 0x1C */ u8* dgnMinimapCount; // number of room minimaps
|
||||
/* 0x20 */ u16* dgnMinimapTexIndexOffset; // dungeon minimap texture index offset
|
||||
/* 0x24 */ u16* owMinimapTexSize;
|
||||
/* 0x28 */ u16* owMinimapTexOffset;
|
||||
/* 0x2C */ s16* owMinimapPosX;
|
||||
/* 0x30 */ s16* owMinimapPosY;
|
||||
/* 0x34 */ s16 (*owCompassInfo)[4]; // [X scale, Y scale, X offset, Y offset]
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef Z64_AUDIO_H
|
||||
#define Z64_AUDIO_H
|
||||
|
||||
#include "endianness.h"
|
||||
|
||||
#define MK_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0))
|
||||
|
||||
#define NO_LAYER ((SequenceLayer*)(-1))
|
||||
@ -685,6 +687,35 @@ typedef struct {
|
||||
} AudioPreloadReq; // size = 0x14
|
||||
|
||||
typedef struct {
|
||||
#ifdef IS_BIGENDIAN
|
||||
union{
|
||||
u32 opArgs;
|
||||
struct {
|
||||
u8 op;
|
||||
u8 arg0;
|
||||
u8 arg1;
|
||||
u8 arg2;
|
||||
};
|
||||
};
|
||||
union {
|
||||
void* data;
|
||||
f32 asFloat;
|
||||
s32 asInt;
|
||||
struct {
|
||||
u16 asUShort;
|
||||
u8 pad2[2];
|
||||
};
|
||||
struct {
|
||||
s8 asSbyte;
|
||||
u8 pad1[3];
|
||||
};
|
||||
struct {
|
||||
u8 asUbyte;
|
||||
u8 pad0[3];
|
||||
};
|
||||
u32 asUInt;
|
||||
};
|
||||
#else
|
||||
union{
|
||||
u32 opArgs;
|
||||
struct {
|
||||
@ -712,6 +743,7 @@ typedef struct {
|
||||
};
|
||||
u32 asUInt;
|
||||
};
|
||||
#endif
|
||||
} AudioCmd;
|
||||
|
||||
typedef struct {
|
||||
@ -783,6 +815,8 @@ typedef struct {
|
||||
/* 0x0E */ u8 ttl; // duration after which the DMA can be discarded
|
||||
} SampleDma; // size = 0x10
|
||||
|
||||
#include <PR/ultra64/abi.h>
|
||||
|
||||
typedef struct {
|
||||
/* 0x0000 */ char unk_0000;
|
||||
/* 0x0001 */ s8 numSynthesisReverbs;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "ultra64.h"
|
||||
#include "z64math.h"
|
||||
#include "z64audio.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
|
||||
typedef struct {
|
||||
@ -114,9 +115,9 @@ typedef struct {
|
||||
/* 0x0EF8 */ u16 infTable[30]; // "inf_table"
|
||||
/* 0x0F38 */ u32 worldMapAreaData; // "area_arrival"
|
||||
/* 0x0F40 */ u8 scarecrowCustomSongSet;
|
||||
/* 0x0F41 */ u8 scarecrowCustomSong[0x360];
|
||||
/* 0x0F41 */ OcarinaNote scarecrowCustomSong[108];
|
||||
/* 0x12C5 */ u8 scarecrowSpawnSongSet;
|
||||
/* 0x12C6 */ u8 scarecrowSpawnSong[0x80];
|
||||
/* 0x12C6 */ OcarinaNote scarecrowSpawnSong[16];
|
||||
/* 0x1346 */ char unk_1346[0x02];
|
||||
/* 0x1348 */ HorseData horseData;
|
||||
/* 0x1354 */ s32 fileNum; // "file_no"
|
||||
|
@ -988,7 +988,6 @@
|
||||
<ClInclude Include="soh\frame_interpolation.h" />
|
||||
<ClInclude Include="include\alloca.h" />
|
||||
<ClInclude Include="include\bgm.h" />
|
||||
<ClInclude Include="include\color.h" />
|
||||
<ClInclude Include="include\command_macros_base.h" />
|
||||
<ClInclude Include="include\fp.h" />
|
||||
<ClInclude Include="include\functions.h" />
|
||||
|
@ -2384,9 +2384,6 @@
|
||||
<ClInclude Include="include\bgm.h">
|
||||
<Filter>Header Files\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\color.h">
|
||||
<Filter>Header Files\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\command_macros_base.h">
|
||||
<Filter>Header Files\include</Filter>
|
||||
</ClInclude>
|
||||
|
@ -6668,10 +6668,12 @@
|
||||
"$(inherited)",
|
||||
"-DENABLE_OPENGL",
|
||||
"-DNDEBUG",
|
||||
"-DSPDLOG_ACTIVE_LEVEL=0",
|
||||
);
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"-DENABLE_OPENGL",
|
||||
"-DNDEBUG",
|
||||
"-DSPDLOG_ACTIVE_LEVEL=0",
|
||||
);
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
OTHER_REZFLAGS = "";
|
||||
@ -6728,10 +6730,12 @@
|
||||
"$(inherited)",
|
||||
"-DENABLE_OPENGL",
|
||||
"-D_DEBUG",
|
||||
"-DSPDLOG_ACTIVE_LEVEL=0",
|
||||
);
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"-DENABLE_OPENGL",
|
||||
"-D_DEBUG",
|
||||
"-DSPDLOG_ACTIVE_LEVEL=0",
|
||||
);
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
OTHER_REZFLAGS = "";
|
||||
@ -6842,7 +6846,6 @@
|
||||
"-DENABLE_OPENGL",
|
||||
"-D_CRT_SECURE_NO_WARNINGS",
|
||||
"-D_CONSOLE",
|
||||
"-DSPDLOG_ACTIVE_LEVEL=0",
|
||||
"-DNDEBUG",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
@ -7031,7 +7034,6 @@
|
||||
"-DENABLE_OPENGL",
|
||||
"-D_CRT_SECURE_NO_WARNINGS",
|
||||
"-D_CONSOLE",
|
||||
"-DSPDLOG_ACTIVE_LEVEL=0",
|
||||
"-D_DEBUG",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
|
78
soh/soh.xcodeproj/xcshareddata/xcschemes/soh.xcscheme
Normal file
78
soh/soh.xcodeproj/xcshareddata/xcschemes/soh.xcscheme
Normal file
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1400"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "6D85CFA44008444FB26F04BA"
|
||||
BuildableName = "soh.app"
|
||||
BlueprintName = "soh"
|
||||
ReferencedContainer = "container:soh.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "6D85CFA44008444FB26F04BA"
|
||||
BuildableName = "soh.app"
|
||||
BlueprintName = "soh"
|
||||
ReferencedContainer = "container:soh.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "6D85CFA44008444FB26F04BA"
|
||||
BuildableName = "soh.app"
|
||||
BlueprintName = "soh"
|
||||
ReferencedContainer = "container:soh.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -44,11 +44,6 @@ void BootCommands_ParseBootArgs(s32 argc, char** argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
DebugArena_Free(argv[i]);
|
||||
|
||||
//DebugArena_Free(argv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <Cvar.h>
|
||||
#include <PR/ultra64/types.h>
|
||||
|
||||
/**
|
||||
* Colors variables
|
||||
@ -228,28 +229,28 @@ void Draw_Npcs(){
|
||||
ImGui::TableSetupColumn("Outer colors##Navi", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort, TablesCellsWidth/2);
|
||||
Table_InitHeader();
|
||||
Draw_HelpIcon("Inner color for Navi (idle flying around)");
|
||||
SohImGui::EnhancementColor("Navi Idle (Primary)", "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();
|
||||
Draw_HelpIcon("Outer color for Navi (idle flying around)");
|
||||
SohImGui::EnhancementColor("Navi Idle (Secondary)", "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();
|
||||
Draw_HelpIcon("Inner color for Navi (when Navi fly around NPCs)");
|
||||
SohImGui::EnhancementColor("Navi NPC (Primary)", "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();
|
||||
Draw_HelpIcon("Outer color for Navi (when Navi fly around NPCs)");
|
||||
SohImGui::EnhancementColor("Navi NPC (Secondary)", "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();
|
||||
Draw_HelpIcon("Inner color for Navi (when Navi fly around Enemies or Bosses)");
|
||||
SohImGui::EnhancementColor("Navi Enemy (Primary)", "gNavi_Enemy_Inner_", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false);
|
||||
SohImGui::EnhancementColor("Navi Enemy", "gNavi_Enemy_Inner", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false);
|
||||
Table_NextCol();
|
||||
Draw_HelpIcon("Outer color for Navi (when Navi fly around Enemies or Bosses)");
|
||||
SohImGui::EnhancementColor("Navi Enemy (Secondary)", "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();
|
||||
Draw_HelpIcon("Inner color for Navi (when Navi fly around props (signs etc))");
|
||||
SohImGui::EnhancementColor("Navi Prop (Primary)", "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();
|
||||
Draw_HelpIcon("Outer color for Navi (when Navi fly around props (signs etc))");
|
||||
SohImGui::EnhancementColor("Navi Prop (Secondary)", "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();
|
||||
}
|
||||
SohImGui::EnhancementCheckbox("Custom colors for Keese", "gUseKeeseCol");
|
||||
|
@ -375,11 +375,16 @@ static bool StateSlotSelectHandler(const std::vector<std::string>& args) {
|
||||
#define VARTYPE_INTEGER 0
|
||||
#define VARTYPE_FLOAT 1
|
||||
#define VARTYPE_STRING 2
|
||||
#define VARTYPE_RGBA 3
|
||||
|
||||
static int CheckVarType(const std::string& input)
|
||||
{
|
||||
int result = VARTYPE_STRING;
|
||||
|
||||
if (input[0] == '#') {
|
||||
return VARTYPE_RGBA;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < input.size(); i++)
|
||||
{
|
||||
if (!(std::isdigit(input[i]) || input[i] == '.'))
|
||||
@ -407,7 +412,17 @@ static bool SetCVarHandler(const std::vector<std::string>& args) {
|
||||
if (vType == VARTYPE_STRING)
|
||||
CVar_SetString(args[1].c_str(), args[2].c_str());
|
||||
else if (vType == VARTYPE_FLOAT)
|
||||
CVar_SetFloat(args[1].c_str(), std::stof(args[2]));
|
||||
CVar_SetFloat((char*)args[1].c_str(), std::stof(args[2]));
|
||||
else if (vType == VARTYPE_RGBA)
|
||||
{
|
||||
uint32_t val = std::stoul(&args[2].c_str()[1], nullptr, 16);
|
||||
Color_RGBA8 clr;
|
||||
clr.r = val >> 24;
|
||||
clr.g = val >> 16;
|
||||
clr.b = val >> 8;
|
||||
clr.a = val & 0xFF;
|
||||
CVar_SetRGBA((char*)args[1].c_str(), clr);
|
||||
}
|
||||
else
|
||||
CVar_SetS32(args[1].c_str(), std::stoi(args[2]));
|
||||
|
||||
@ -426,12 +441,14 @@ static bool GetCVarHandler(const std::vector<std::string>& args) {
|
||||
|
||||
if (cvar != nullptr)
|
||||
{
|
||||
if (cvar->type == CVAR_TYPE_S32)
|
||||
if (cvar->type == CVarType::S32)
|
||||
INFO("[SOH] Variable %s is %i", args[1].c_str(), cvar->value.valueS32);
|
||||
else if (cvar->type == CVAR_TYPE_FLOAT)
|
||||
else if (cvar->type == CVarType::Float)
|
||||
INFO("[SOH] Variable %s is %f", args[1].c_str(), cvar->value.valueFloat);
|
||||
else if (cvar->type == CVAR_TYPE_STRING)
|
||||
else if (cvar->type == CVarType::String)
|
||||
INFO("[SOH] Variable %s is %s", args[1].c_str(), cvar->value.valueStr);
|
||||
else if (cvar->type == CVarType::RGBA)
|
||||
INFO("[SOH] Variable %s is %08X", args[1].c_str(), cvar->value.valueRGBA);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -508,6 +525,22 @@ void DebugConsole_LoadLegacyCVars() {
|
||||
std::vector<std::string> cfg = StringHelper::Split(line, " = ");
|
||||
if (line.empty()) continue;
|
||||
if (cfg.size() < 2) continue;
|
||||
|
||||
if (cfg[1].find("\"") == std::string::npos && (cfg[1].find("#") != std::string::npos))
|
||||
{
|
||||
std::string value(cfg[1]);
|
||||
value.erase(std::remove_if(value.begin(), value.end(), [](char c) { return c == '#'; }), value.end());
|
||||
auto splitTest = StringHelper::Split(value, "\r")[0];
|
||||
|
||||
uint32_t val = std::stoul(splitTest, nullptr, 16);
|
||||
Color_RGBA8 clr;
|
||||
clr.r = val >> 24;
|
||||
clr.g = val >> 16;
|
||||
clr.b = val >> 8;
|
||||
clr.a = val & 0xFF;
|
||||
CVar_SetRGBA(cfg[0].c_str(), clr);
|
||||
}
|
||||
|
||||
if (cfg[1].find("\"") != std::string::npos) {
|
||||
std::string value(cfg[1]);
|
||||
value.erase(std::remove(value.begin(), value.end(), '\"'), value.end());
|
||||
@ -536,6 +569,18 @@ void DebugConsole_LoadCVars() {
|
||||
case nlohmann::detail::value_t::array:
|
||||
break;
|
||||
case nlohmann::detail::value_t::string:
|
||||
if (StringHelper::StartsWith(value.get<std::string>(), "#"))
|
||||
{
|
||||
uint32_t val = std::stoul(&value.get<std::string>().c_str()[1], nullptr, 16);
|
||||
Color_RGBA8 clr;
|
||||
clr.r = val >> 24;
|
||||
clr.g = val >> 16;
|
||||
clr.b = val >> 8;
|
||||
clr.a = val & 0xFF;
|
||||
|
||||
CVar_SetRGBA(item.key().c_str(), clr);
|
||||
}
|
||||
else
|
||||
CVar_SetString(item.key().c_str(), value.get<std::string>().c_str());
|
||||
break;
|
||||
case nlohmann::detail::value_t::boolean:
|
||||
@ -565,12 +610,19 @@ void DebugConsole_SaveCVars()
|
||||
for (const auto &cvar : cvars) {
|
||||
const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str());
|
||||
|
||||
if (cvar.second->type == CVAR_TYPE_STRING && cvar.second->value.valueStr != nullptr)
|
||||
if (cvar.second->type == CVarType::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 == CVarType::S32)
|
||||
pConf->setInt(key, cvar.second->value.valueS32);
|
||||
else if (cvar.second->type == CVAR_TYPE_FLOAT)
|
||||
else if (cvar.second->type == CVarType::Float)
|
||||
pConf->setFloat(key, cvar.second->value.valueFloat);
|
||||
else if (cvar.second->type == CVarType::RGBA)
|
||||
{
|
||||
Color_RGBA8 clr = cvar.second->value.valueRGBA;
|
||||
uint32_t val = (clr.r << 24) + (clr.g << 16) + (clr.b << 8) + clr.a;
|
||||
std::string str = StringHelper::Sprintf("#%08X", val);
|
||||
pConf->setString(key, str);
|
||||
}
|
||||
}
|
||||
|
||||
pConf->save();
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include "ImGuiHelpers.h"
|
||||
#include "../../../../libultraship/libultraship/ImGuiImpl.h"
|
||||
|
||||
// Adds a text tooltip for the previous ImGui item
|
||||
void SetLastItemHoverText(const std::string& text) {
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text(text.c_str());
|
||||
ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str());
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
@ -15,7 +16,7 @@ void InsertHelpHoverText(const std::string& text) {
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?");
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text(text.c_str());
|
||||
ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str());
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
@ -1001,7 +1001,7 @@ void DrawFlagsTab() {
|
||||
|
||||
// Draws a combo that lets you choose and upgrade value from a drop-down of text values
|
||||
void DrawUpgrade(const std::string& categoryName, int32_t categoryId, const std::vector<std::string>& names) {
|
||||
ImGui::Text(categoryName.c_str());
|
||||
ImGui::Text("%s", categoryName.c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(categoryName.c_str());
|
||||
if (ImGui::BeginCombo("##upgrade", names[CUR_UPG_VALUE(categoryId)].c_str())) {
|
||||
@ -1435,7 +1435,7 @@ void DrawPlayerTab() {
|
||||
InsertHelpHoverText("Link's speed along the Y plane. Caps at -20");
|
||||
|
||||
ImGui::InputScalar("Wall Height", ImGuiDataType_Float, &player->wallHeight);
|
||||
InsertHelpHoverText("\"height used to determine whether link can climb or grab a ledge at the top\"");
|
||||
InsertHelpHoverText("Height used to determine whether Link can climb or grab a ledge at the top");
|
||||
|
||||
ImGui::InputScalar("Invincibility Timer", ImGuiDataType_S8, &player->invincibilityTimer);
|
||||
InsertHelpHoverText("Can't take damage while this is nonzero");
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define NOGDI
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <GlobalCtx2.h>
|
||||
#include <PR/ultra64/types.h>
|
||||
|
||||
#define TICKS_PER_SEC 268123480.0
|
||||
|
||||
|
@ -3767,25 +3767,25 @@ void DrawRandoEditor(bool& open) {
|
||||
// Forest
|
||||
ImGui::Text(Settings::OpenForest.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Closed - Kokiri sword & shield are required to access\n"
|
||||
"the Deku Tree, and completing the Deku Tree is required to\n"
|
||||
"Closed - Kokiri sword & shield are required to access "
|
||||
"the Deku Tree, and completing the Deku Tree is required to "
|
||||
"access the Hyrule Field exit.\n"
|
||||
"\n"
|
||||
"Closed Deku - Kokiri boy no longer blocks the path to Hyrule\n"
|
||||
"Field but Mido still requires the Kokiri sword and Deku shield\n"
|
||||
"Closed Deku - Kokiri boy no longer blocks the path to Hyrule "
|
||||
"Field but Mido still requires the Kokiri sword and Deku shield "
|
||||
"to access the tree.\n"
|
||||
"\n"
|
||||
"Open - Mido no longer blocks the path to the Deku Tree. Kokiri\n"
|
||||
"Open - Mido no longer blocks the path to the Deku Tree. Kokiri "
|
||||
"boy no longer blocks the path out of the forest.");
|
||||
SohImGui::EnhancementCombobox("gRandomizeForest", randoForest, 3, 0);
|
||||
PaddedSeparator();
|
||||
// Kakariko Gate
|
||||
ImGui::Text(Settings::OpenKakariko.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Closed - The gate will remain closed until Zelda's letter\n"
|
||||
"Closed - The gate will remain closed until Zelda's letter "
|
||||
"is shown to the guard.\n"
|
||||
"\n"
|
||||
"Open - The gate is always open. The happy mask shop\n"
|
||||
"Open - The gate is always open. The happy mask shop "
|
||||
"will open immediately after obtaining Zelda's letter."
|
||||
);
|
||||
SohImGui::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 0);
|
||||
@ -3794,14 +3794,13 @@ void DrawRandoEditor(bool& open) {
|
||||
// Door of Time
|
||||
ImGui::Text(Settings::OpenDoorOfTime.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Closed - The Ocarina of Time, the Song of Time and all\n"
|
||||
"Closed - The Ocarina of Time, the Song of Time and all "
|
||||
"three spiritual stones are required to open the Door of Time.\n"
|
||||
"\n"
|
||||
"Song only - Play the Song of Time in front of the Door of\n"
|
||||
"Song only - Play the Song of Time in front of the Door of "
|
||||
"Time to open it.\n"
|
||||
"\n"
|
||||
"Open - The Door of Time is permanently open with no\n"
|
||||
"requirements."
|
||||
"Open - The Door of Time is permanently open with no requirements."
|
||||
);
|
||||
SohImGui::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0);
|
||||
PaddedSeparator();
|
||||
@ -3809,14 +3808,14 @@ void DrawRandoEditor(bool& open) {
|
||||
// Zora's Fountain
|
||||
ImGui::Text(Settings::ZorasFountain.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Closed - King Zora obstructs the way to Zora's Fountain.\n"
|
||||
"Ruto's letter must be shown as child Link in order to move\n"
|
||||
"Closed - King Zora obstructs the way to Zora's Fountain. "
|
||||
"Ruto's letter must be shown as child Link in order to move "
|
||||
"him in both time periods.\n"
|
||||
"\n"
|
||||
"Closed as child - Ruto's Letter is only required to move King Zora\n"
|
||||
"Closed as child - Ruto's Letter is only required to move King Zora "
|
||||
"as child Link. Zora's Fountain starts open as adult.\n"
|
||||
"\n"
|
||||
"Open - King Zora has already mweeped out of the way in both\n"
|
||||
"Open - King Zora has already mweeped out of the way in both "
|
||||
"time periods. Ruto's Letter is removed from the item pool."
|
||||
);
|
||||
SohImGui::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0);
|
||||
@ -3825,7 +3824,7 @@ void DrawRandoEditor(bool& open) {
|
||||
// Gerudo Fortress
|
||||
ImGui::Text(Settings::GerudoFortress.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Sets the amount of carpenters required to repair the bridge\n"
|
||||
"Sets the amount of carpenters required to repair the bridge "
|
||||
"in Gerudo Valley.\n"
|
||||
"\n"
|
||||
"Normal - All 4 carpenters are required to be saved.\n"
|
||||
@ -3842,8 +3841,7 @@ void DrawRandoEditor(bool& open) {
|
||||
InsertHelpHoverText(
|
||||
"Alters the requirements to open the bridge to Ganon's Castle.\n"
|
||||
"\n"
|
||||
"Vanilla - Obtain the Shadow Medallion, Spirit Medallion and Light\n"
|
||||
"Arrows.\n"
|
||||
"Vanilla - Obtain the Shadow Medallion, Spirit Medallion and Light Arrows.\n"
|
||||
"\n"
|
||||
"Always open - No requirements.\n"
|
||||
"\n"
|
||||
@ -3851,11 +3849,11 @@ void DrawRandoEditor(bool& open) {
|
||||
"\n"
|
||||
"Medallions - Obtain the specified amount of medallions.\n"
|
||||
"\n"
|
||||
"Dungeon rewards - Obtain the specified total sum of spiritual\n"
|
||||
"Dungeon rewards - Obtain the specified total sum of spiritual "
|
||||
"stones or medallions.\n"
|
||||
"\n"
|
||||
"Dungeons - Complete the specified amount of dungeons. Dungeons\n"
|
||||
"are considered complete after stepping in to the blue warp after\n"
|
||||
"Dungeons - Complete the specified amount of dungeons. Dungeons "
|
||||
"are considered complete after stepping in to the blue warp after "
|
||||
"the boss.\n"
|
||||
"\n"
|
||||
"Tokens - Obtain the specified amount of Skulltula tokens."
|
||||
@ -3922,8 +3920,7 @@ void DrawRandoEditor(bool& open) {
|
||||
// Shuffle Songs
|
||||
ImGui::Text(Settings::ShuffleSongs.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Song locations - Songs will only appear at locations that normally\n"
|
||||
"teach songs.\n"
|
||||
"Song locations - Songs will only appear at locations that normally teach songs.\n"
|
||||
"\n"
|
||||
"Dungeon rewards - Songs appear after beating a major dungeon boss.\n"
|
||||
"The 4 remaining songs are located at:\n"
|
||||
@ -3941,7 +3938,7 @@ void DrawRandoEditor(bool& open) {
|
||||
// Shuffle Tokens
|
||||
ImGui::Text(Settings::Tokensanity.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Shuffles Golden Skulltula Tokens into the item pool. This means\n"
|
||||
"Shuffles Golden Skulltula Tokens into the item pool. This means "
|
||||
"Golden Skulltulas can contain other items as well.\n"
|
||||
"\n"
|
||||
"Off - GS tokens will not be shuffled.\n"
|
||||
@ -3956,7 +3953,7 @@ void DrawRandoEditor(bool& open) {
|
||||
PaddedSeparator();
|
||||
|
||||
SohImGui::EnhancementCheckbox("Nighttime GS expect Sun's Song", "gRandomizeGsExpectSunsSong");
|
||||
InsertHelpHoverText("All Golden Skulltulas that require nighttime to appear will only be\n"
|
||||
InsertHelpHoverText("All Golden Skulltulas that require nighttime to appear will only be "
|
||||
"expected to be collected after getting Sun's Song.");
|
||||
PaddedSeparator();
|
||||
|
||||
@ -3966,8 +3963,7 @@ void DrawRandoEditor(bool& open) {
|
||||
InsertHelpHoverText(
|
||||
"Shuffles the Kokiri Sword into the item pool.\n"
|
||||
"\n"
|
||||
"This will require the use of sticks until the Kokiri\n"
|
||||
"Sword is found."
|
||||
"This will require the use of sticks until the Kokiri Sword is found."
|
||||
);
|
||||
PaddedSeparator();
|
||||
}
|
||||
@ -3976,8 +3972,7 @@ void DrawRandoEditor(bool& open) {
|
||||
// Shuffle Ocarinas
|
||||
SohImGui::EnhancementCheckbox(Settings::ShuffleOcarinas.GetName().c_str(), "gRandomizeShuffleOcarinas");
|
||||
InsertHelpHoverText(
|
||||
"Enabling this shuffles the Fairy Ocarina and the Ocarina of Time\n"
|
||||
"into the item pool.\n"
|
||||
"Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n"
|
||||
"\n"
|
||||
"This will require finding an Ocarina before being able to play songs."
|
||||
);
|
||||
@ -4003,7 +3998,7 @@ void DrawRandoEditor(bool& open) {
|
||||
ImGui::PopItemFlag();
|
||||
}
|
||||
InsertHelpHoverText(
|
||||
"Shuffles the Weird Egg from Malon in to the item pool. Enabling\n"
|
||||
"Shuffles the Weird Egg from Malon in to the item pool. Enabling "
|
||||
"\"Skip Child Zelda\" disables this feature.\n"
|
||||
"\n"
|
||||
"The Weird Egg is required to unlock several events:\n"
|
||||
@ -4020,7 +4015,7 @@ void DrawRandoEditor(bool& open) {
|
||||
InsertHelpHoverText(
|
||||
"Shuffles the Gerudo Membership Card into the item pool.\n"
|
||||
"\n"
|
||||
"The Gerudo Card is required to enter the Gerudo Training Grounds, opening\n"
|
||||
"The Gerudo Card is required to enter the Gerudo Training Grounds, opening "
|
||||
"the gate to Haunted Wasteland and the Horseback Archery minigame."
|
||||
);
|
||||
}
|
||||
@ -4036,7 +4031,7 @@ void DrawRandoEditor(bool& open) {
|
||||
InsertHelpHoverText(
|
||||
"Shuffles the location of spiritual stones and medallions.\n"
|
||||
"\n"
|
||||
"End of dungeons - Spiritual stones and medallions will be given as rewards\n"
|
||||
"End of dungeons - Spiritual stones and medallions will be given as rewards "
|
||||
"for beating major dungeons. Link will always start with one stone or medallion.\n"
|
||||
"\n"
|
||||
"Any dungeon - Spiritual stones and medallions can be found inside any dungeon.\n"
|
||||
@ -4121,14 +4116,13 @@ void DrawRandoEditor(bool& open) {
|
||||
}
|
||||
ImGui::PopItemFlag();
|
||||
}
|
||||
InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping\n"
|
||||
"the guards.");
|
||||
InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.");
|
||||
PaddedSeparator();
|
||||
|
||||
// Skip child zelda
|
||||
SohImGui::EnhancementCheckbox("Skip Child Zelda", "gRandomizeSkipChildZelda");
|
||||
InsertHelpHoverText(
|
||||
"Start with Zelda's Letter in your inventory and skip the sequence up\n"
|
||||
"Start with Zelda's Letter in your inventory and skip the sequence up "
|
||||
"until after meeting Zelda. Disables the ability to shuffle Weird Egg."
|
||||
);
|
||||
PaddedSeparator();
|
||||
@ -4154,8 +4148,8 @@ void DrawRandoEditor(bool& open) {
|
||||
// Gossip Stone Hints
|
||||
ImGui::Text(Settings::GossipStoneHints.GetName().c_str());
|
||||
InsertHelpHoverText(
|
||||
"Allows Gossip Stones to provide hints on item locations. Hints mentioning\n"
|
||||
"\"Way of the Hero\" indicate a location that holds an item required to beat\n"
|
||||
"Allows Gossip Stones to provide hints on item locations. Hints mentioning "
|
||||
"\"Way of the Hero\" indicate a location that holds an item required to beat "
|
||||
"the seed.\n"
|
||||
"\n"
|
||||
"No hints - No hints will be given at all.\n"
|
||||
@ -4238,7 +4232,7 @@ void DrawRandoEditor(bool& open) {
|
||||
"\n"
|
||||
"Mayhem - All added junk items will be Ice Traps.\n"
|
||||
"\n"
|
||||
"Onslaught - All junk items will be replaced by Ice Traps, even those\n"
|
||||
"Onslaught - All junk items will be replaced by Ice Traps, even those "
|
||||
"in the base pool."
|
||||
);
|
||||
SohImGui::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1);
|
||||
|
@ -1017,7 +1017,7 @@ void DrawItemTracker(bool& open) {
|
||||
}
|
||||
SohImGui::EnhancementCheckbox("Display \"Ammo/MaxAmo\"", "gItemTrackerAmmoDisplay");
|
||||
SohImGui::EnhancementCheckbox("Randomizer colors for Songs", "gItemTrackeSongColor");
|
||||
SohImGui::Tooltip("Will dispaly non-warp songs with randomizer\ncolors instead of pure white");
|
||||
SohImGui::Tooltip("Will display non-warp songs with randomizer colors instead of pure white");
|
||||
SohImGui::EnhancementCheckbox("Personal notes space", "gItemTrackerNotes");
|
||||
SohImGui::Tooltip("Adds a textbox under the item tracker to keep your own notes in");
|
||||
SohImGui::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gRandoTrackIconSize", 32, 128, "");
|
||||
|
@ -17,6 +17,9 @@ void ResourceMgr_CacheDirectory(const char* resName);
|
||||
void ResourceMgr_LoadFile(const char* resName);
|
||||
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
|
||||
char* ResourceMgr_LoadTexByName(char* texPath);
|
||||
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
|
||||
uint16_t ResourceMgr_LoadTexHeightByName(char* texPath);
|
||||
uint32_t ResourceMgr_LoadTexSizeByName(char* texPath);
|
||||
char* ResourceMgr_LoadTexOrDListByName(char* filePath);
|
||||
char* ResourceMgr_LoadPlayerAnimByName(char* animPath);
|
||||
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);
|
||||
|
@ -51,6 +51,10 @@
|
||||
#include <SDL2/SDL_scancode.h>
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include "SwitchImpl.h"
|
||||
#endif
|
||||
|
||||
#include <Audio.h>
|
||||
|
||||
OTRGlobals* OTRGlobals::Instance;
|
||||
@ -104,14 +108,16 @@ extern "C" void OTRExtScanner() {
|
||||
}
|
||||
|
||||
extern "C" void InitOTR() {
|
||||
#ifdef __SWITCH__
|
||||
Ship::Switch::Init(Ship::PreInitPhase);
|
||||
#endif
|
||||
OTRGlobals::Instance = new OTRGlobals();
|
||||
SaveManager::Instance = new SaveManager();
|
||||
auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version");
|
||||
|
||||
if (!t->bHasLoadError)
|
||||
{
|
||||
//uint32_t gameVersion = BitConverter::ToUInt32BE((uint8_t*)t->buffer.get(), 0);
|
||||
uint32_t gameVersion = *((uint32_t*)t->buffer.get());
|
||||
uint32_t gameVersion = LE32SWAP(*((uint32_t*)t->buffer.get()));
|
||||
OTRGlobals::Instance->context->GetResourceManager()->SetGameVersion(gameVersion);
|
||||
}
|
||||
|
||||
@ -225,6 +231,7 @@ extern "C" void Graph_StartFrame() {
|
||||
|
||||
// C->C++ Bridge
|
||||
extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
||||
#ifndef __SWITCH__
|
||||
if (!audio.initialized) {
|
||||
audio.initialized = true;
|
||||
std::thread([]() {
|
||||
@ -251,19 +258,16 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
||||
|
||||
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
||||
#define NUM_AUDIO_CHANNELS 2
|
||||
|
||||
int samples_left = AudioPlayer_Buffered();
|
||||
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||
// printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
||||
|
||||
// 3 is the maximum authentic frame divisor.
|
||||
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
|
||||
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
|
||||
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
|
||||
}
|
||||
//for (uint32_t i = 0; i < 2 * num_audio_samples; i++) {
|
||||
// audio_buffer[i] = Rand_Next() & 0xFF;
|
||||
//}
|
||||
// printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
|
||||
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
|
||||
|
||||
audio.processing = false;
|
||||
@ -276,8 +280,9 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
audio.processing = true;
|
||||
}
|
||||
audio.cv_to_thread.notify_one();
|
||||
#endif
|
||||
|
||||
audio.cv_to_thread.notify_one();
|
||||
std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements;
|
||||
int target_fps = CVar_GetS32("gInterpolationFPS", 20);
|
||||
static int last_fps;
|
||||
@ -318,12 +323,14 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
||||
last_fps = fps;
|
||||
last_update_rate = R_UPDATE_RATE;
|
||||
|
||||
#ifndef __SWITCH__
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(audio.mutex);
|
||||
while (audio.processing) {
|
||||
audio.cv_from_thread.wait(Lock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// OTRTODO: FIGURE OUT END FRAME POINT
|
||||
/* if (OTRGlobals::Instance->context->GetWindow()->lastScancode != -1)
|
||||
@ -445,6 +452,12 @@ extern "C" char* ResourceMgr_LoadJPEG(char* data, int dataSize)
|
||||
|
||||
extern "C" char* ResourceMgr_LoadTexByName(const char* texPath);
|
||||
|
||||
extern "C" uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
|
||||
|
||||
extern "C" uint16_t ResourceMgr_LoadTexHeightByName(char* texPath);
|
||||
|
||||
extern "C" uint32_t ResourceMgr_LoadTexSizeByName(const char* texPath);
|
||||
|
||||
extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) {
|
||||
auto res = OTRGlobals::Instance->context->GetResourceManager()->LoadResource(filePath);
|
||||
|
||||
@ -787,8 +800,8 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) {
|
||||
|
||||
for (size_t k = 0; k < soundFont->drums[i].env.size(); k++)
|
||||
{
|
||||
drum->envelope[k].delay = BOMSWAP16(soundFont->drums[i].env[k]->delay);
|
||||
drum->envelope[k].arg = BOMSWAP16(soundFont->drums[i].env[k]->arg);
|
||||
drum->envelope[k].delay = BE16SWAP(soundFont->drums[i].env[k]->delay);
|
||||
drum->envelope[k].arg = BE16SWAP(soundFont->drums[i].env[k]->arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -819,8 +832,8 @@ extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) {
|
||||
|
||||
for (int k = 0; k < soundFont->instruments[i].env.size(); k++)
|
||||
{
|
||||
inst->envelope[k].delay = BOMSWAP16(soundFont->instruments[i].env[k]->delay);
|
||||
inst->envelope[k].arg = BOMSWAP16(soundFont->instruments[i].env[k]->arg);
|
||||
inst->envelope[k].delay = BE16SWAP(soundFont->instruments[i].env[k]->delay);
|
||||
inst->envelope[k].arg = BE16SWAP(soundFont->instruments[i].env[k]->arg);
|
||||
}
|
||||
}
|
||||
if (soundFont->instruments[i].lowNotesSound != nullptr)
|
||||
|
@ -44,6 +44,9 @@ void ResourceMgr_LoadFile(const char* resName);
|
||||
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
|
||||
char* ResourceMgr_LoadJPEG(char* data, int dataSize);
|
||||
char* ResourceMgr_LoadTexByName(const char* texPath);
|
||||
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
|
||||
uint16_t ResourceMgr_LoadTexHeightByName(char* texPath);
|
||||
uint32_t ResourceMgr_LoadTexSizeByName(char* texPath);
|
||||
char* ResourceMgr_LoadTexOrDListByName(const char* filePath);
|
||||
char* ResourceMgr_LoadPlayerAnimByName(const char* animPath);
|
||||
AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path);
|
||||
|
@ -22,7 +22,8 @@ std::filesystem::path SaveManager::GetFileName(int fileNum) {
|
||||
|
||||
SaveManager::SaveManager() {
|
||||
AddLoadFunction("base", 1, LoadBaseVersion1);
|
||||
AddSaveFunction("base", 1, SaveBase);
|
||||
AddLoadFunction("base", 2, LoadBaseVersion2);
|
||||
AddSaveFunction("base", 2, SaveBase);
|
||||
|
||||
AddLoadFunction("randomizer", 1, LoadRandomizerVersion1);
|
||||
AddSaveFunction("randomizer", 1, SaveRandomizer);
|
||||
@ -49,6 +50,8 @@ SaveManager::SaveManager() {
|
||||
}
|
||||
|
||||
void SaveManager::LoadRandomizerVersion1() {
|
||||
if(!CVar_GetS32("gRandomizer", 0)) return;
|
||||
|
||||
for (int i = 0; i < ARRAY_COUNT(gSaveContext.itemLocations); i++) {
|
||||
SaveManager::Instance->LoadData("get" + std::to_string(i), gSaveContext.itemLocations[i].get);
|
||||
SaveManager::Instance->LoadData("check" + std::to_string(i), gSaveContext.itemLocations[i].check);
|
||||
@ -88,6 +91,9 @@ void SaveManager::LoadRandomizerVersion1() {
|
||||
}
|
||||
|
||||
void SaveManager::SaveRandomizer() {
|
||||
|
||||
if(!gSaveContext.n64ddFlag) return;
|
||||
|
||||
for (int i = 0; i < ARRAY_COUNT(gSaveContext.itemLocations); i++) {
|
||||
SaveManager::Instance->SaveData("get" + std::to_string(i), gSaveContext.itemLocations[i].get);
|
||||
SaveManager::Instance->SaveData("check" + std::to_string(i), gSaveContext.itemLocations[i].check);
|
||||
@ -314,11 +320,23 @@ void SaveManager::InitFileNormal() {
|
||||
gSaveContext.worldMapAreaData = 0;
|
||||
gSaveContext.scarecrowCustomSongSet = 0;
|
||||
for (int i = 0; i < ARRAY_COUNT(gSaveContext.scarecrowCustomSong); i++) {
|
||||
gSaveContext.scarecrowCustomSong[i] = 0;
|
||||
gSaveContext.scarecrowCustomSong[i].noteIdx = 0;
|
||||
gSaveContext.scarecrowCustomSong[i].unk_01 = 0;
|
||||
gSaveContext.scarecrowCustomSong[i].unk_02 = 0;
|
||||
gSaveContext.scarecrowCustomSong[i].volume = 0;
|
||||
gSaveContext.scarecrowCustomSong[i].vibrato = 0;
|
||||
gSaveContext.scarecrowCustomSong[i].tone = 0;
|
||||
gSaveContext.scarecrowCustomSong[i].semitone = 0;
|
||||
}
|
||||
gSaveContext.scarecrowSpawnSongSet = 0;
|
||||
for (int i = 0; i < ARRAY_COUNT(gSaveContext.scarecrowSpawnSong); i++) {
|
||||
gSaveContext.scarecrowSpawnSong[i] = 0;
|
||||
gSaveContext.scarecrowSpawnSong[i].noteIdx = 0;
|
||||
gSaveContext.scarecrowSpawnSong[i].unk_01 = 0;
|
||||
gSaveContext.scarecrowSpawnSong[i].unk_02 = 0;
|
||||
gSaveContext.scarecrowSpawnSong[i].volume = 0;
|
||||
gSaveContext.scarecrowSpawnSong[i].vibrato = 0;
|
||||
gSaveContext.scarecrowSpawnSong[i].tone = 0;
|
||||
gSaveContext.scarecrowSpawnSong[i].semitone = 0;
|
||||
}
|
||||
|
||||
gSaveContext.horseData.scene = SCENE_SPOT00;
|
||||
@ -695,12 +713,172 @@ void SaveManager::LoadBaseVersion1() {
|
||||
});
|
||||
SaveManager::Instance->LoadData("worldMapAreaData", gSaveContext.worldMapAreaData);
|
||||
SaveManager::Instance->LoadData("scarecrowCustomSongSet", gSaveContext.scarecrowCustomSongSet);
|
||||
SaveManager::Instance->LoadArray("scarecrowCustomSong", sizeof(gSaveContext.scarecrowCustomSong), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", ((u8*)&gSaveContext.scarecrowCustomSong)[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
|
||||
SaveManager::Instance->LoadArray("scarecrowSpawnSong", sizeof(gSaveContext.scarecrowSpawnSong), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", ((u8*)&gSaveContext.scarecrowSpawnSong)[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("horseData", []() {
|
||||
SaveManager::Instance->LoadData("scene", gSaveContext.horseData.scene);
|
||||
SaveManager::Instance->LoadStruct("pos", []() {
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.horseData.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.horseData.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.horseData.pos.z);
|
||||
});
|
||||
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("dungeonsDone", ARRAY_COUNT(gSaveContext.dungeonsDone), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.dungeonsDone[i]);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.trialsDone[i]); });
|
||||
}
|
||||
|
||||
void SaveManager::LoadBaseVersion2() {
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.entranceIndex);
|
||||
SaveManager::Instance->LoadData("linkAge", gSaveContext.linkAge);
|
||||
SaveManager::Instance->LoadData("cutsceneIndex", gSaveContext.cutsceneIndex);
|
||||
SaveManager::Instance->LoadData("dayTime", gSaveContext.dayTime);
|
||||
SaveManager::Instance->LoadData("nightFlag", gSaveContext.nightFlag);
|
||||
SaveManager::Instance->LoadData("totalDays", gSaveContext.totalDays);
|
||||
SaveManager::Instance->LoadData("bgsDayCount", gSaveContext.bgsDayCount);
|
||||
SaveManager::Instance->LoadData("deaths", gSaveContext.deaths);
|
||||
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.playerName[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("n64ddFlag", gSaveContext.n64ddFlag);
|
||||
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
|
||||
SaveManager::Instance->LoadData("health", gSaveContext.health);
|
||||
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
|
||||
SaveManager::Instance->LoadData("magic", gSaveContext.magic);
|
||||
SaveManager::Instance->LoadData("rupees", gSaveContext.rupees);
|
||||
SaveManager::Instance->LoadData("swordHealth", gSaveContext.swordHealth);
|
||||
SaveManager::Instance->LoadData("naviTimer", gSaveContext.naviTimer);
|
||||
SaveManager::Instance->LoadData("magicAcquired", gSaveContext.magicAcquired);
|
||||
SaveManager::Instance->LoadData("doubleMagic", gSaveContext.doubleMagic);
|
||||
SaveManager::Instance->LoadData("doubleDefense", gSaveContext.doubleDefense);
|
||||
SaveManager::Instance->LoadData("bgsFlag", gSaveContext.bgsFlag);
|
||||
SaveManager::Instance->LoadData("ocarinaGameRoundNum", gSaveContext.ocarinaGameRoundNum);
|
||||
SaveManager::Instance->LoadStruct("childEquips", []() {
|
||||
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.childEquips.buttonItems), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.childEquips.buttonItems[i],
|
||||
static_cast<uint8_t>(ITEM_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.childEquips.cButtonSlots), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.childEquips.cButtonSlots[i],
|
||||
static_cast<uint8_t>(SLOT_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.childEquips.equipment);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("adultEquips", []() {
|
||||
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.adultEquips.buttonItems), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.buttonItems[i],
|
||||
static_cast<uint8_t>(ITEM_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.adultEquips.cButtonSlots), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.cButtonSlots[i],
|
||||
static_cast<uint8_t>(SLOT_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.adultEquips.equipment);
|
||||
});
|
||||
SaveManager::Instance->LoadData("unk_54", gSaveContext.unk_54);
|
||||
SaveManager::Instance->LoadData("savedSceneNum", gSaveContext.savedSceneNum);
|
||||
SaveManager::Instance->LoadStruct("equips", []() {
|
||||
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.equips.buttonItems), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.equips.buttonItems[i], static_cast<uint8_t>(ITEM_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.equips.cButtonSlots), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.equips.cButtonSlots[i], static_cast<uint8_t>(SLOT_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.equips.equipment);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("inventory", []() {
|
||||
SaveManager::Instance->LoadArray("items", ARRAY_COUNT(gSaveContext.inventory.items), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.items[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("ammo", ARRAY_COUNT(gSaveContext.inventory.ammo), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.ammo[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
|
||||
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
|
||||
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
|
||||
SaveManager::Instance->LoadArray("dungeonItems", ARRAY_COUNT(gSaveContext.inventory.dungeonItems), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.inventory.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
|
||||
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
|
||||
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
|
||||
SaveManager::Instance->LoadData("clear", gSaveContext.sceneFlags[i].clear);
|
||||
SaveManager::Instance->LoadData("collect", gSaveContext.sceneFlags[i].collect);
|
||||
SaveManager::Instance->LoadData("unk", gSaveContext.sceneFlags[i].unk);
|
||||
SaveManager::Instance->LoadData("rooms", gSaveContext.sceneFlags[i].rooms);
|
||||
SaveManager::Instance->LoadData("floors", gSaveContext.sceneFlags[i].floors);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("fw", []() {
|
||||
SaveManager::Instance->LoadStruct("pos", []() {
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.fw.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.fw.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.fw.pos.z);
|
||||
});
|
||||
SaveManager::Instance->LoadData("yaw", gSaveContext.fw.yaw);
|
||||
SaveManager::Instance->LoadData("playerParams", gSaveContext.fw.playerParams);
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.fw.entranceIndex);
|
||||
SaveManager::Instance->LoadData("roomIndex", gSaveContext.fw.roomIndex);
|
||||
SaveManager::Instance->LoadData("set", gSaveContext.fw.set);
|
||||
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.fw.tempSwchFlags);
|
||||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.fw.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("gsFlags", ARRAY_COUNT(gSaveContext.gsFlags), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.gsFlags[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("highScores", ARRAY_COUNT(gSaveContext.highScores), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.highScores[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("eventChkInf", ARRAY_COUNT(gSaveContext.eventChkInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.eventChkInf[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("itemGetInf", ARRAY_COUNT(gSaveContext.itemGetInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.itemGetInf[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("infTable", ARRAY_COUNT(gSaveContext.infTable), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.infTable[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("worldMapAreaData", gSaveContext.worldMapAreaData);
|
||||
SaveManager::Instance->LoadData("scarecrowCustomSongSet", gSaveContext.scarecrowCustomSongSet);
|
||||
SaveManager::Instance->LoadArray("scarecrowCustomSong", ARRAY_COUNT(gSaveContext.scarecrowCustomSong), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.scarecrowCustomSong[i]);
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowCustomSong[i].noteIdx);
|
||||
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowCustomSong[i].unk_01);
|
||||
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowCustomSong[i].unk_02);
|
||||
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowCustomSong[i].volume);
|
||||
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowCustomSong[i].vibrato);
|
||||
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowCustomSong[i].tone);
|
||||
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowCustomSong[i].semitone);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
|
||||
SaveManager::Instance->LoadArray("scarecrowSpawnSong", ARRAY_COUNT(gSaveContext.scarecrowSpawnSong), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.scarecrowSpawnSong[i]);
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowSpawnSong[i].noteIdx);
|
||||
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowSpawnSong[i].unk_01);
|
||||
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowSpawnSong[i].unk_02);
|
||||
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowSpawnSong[i].volume);
|
||||
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowSpawnSong[i].vibrato);
|
||||
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowSpawnSong[i].tone);
|
||||
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowSpawnSong[i].semitone);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("horseData", []() {
|
||||
SaveManager::Instance->LoadData("scene", gSaveContext.horseData.scene);
|
||||
@ -836,11 +1014,27 @@ void SaveManager::SaveBase() {
|
||||
SaveManager::Instance->SaveData("worldMapAreaData", gSaveContext.worldMapAreaData);
|
||||
SaveManager::Instance->SaveData("scarecrowCustomSongSet", gSaveContext.scarecrowCustomSongSet);
|
||||
SaveManager::Instance->SaveArray("scarecrowCustomSong", ARRAY_COUNT(gSaveContext.scarecrowCustomSong), [](size_t i) {
|
||||
SaveManager::Instance->SaveData("", gSaveContext.scarecrowCustomSong[i]);
|
||||
SaveManager::Instance->SaveStruct("", [&i]() {
|
||||
SaveManager::Instance->SaveData("noteIdx", gSaveContext.scarecrowCustomSong[i].noteIdx);
|
||||
SaveManager::Instance->SaveData("unk_01", gSaveContext.scarecrowCustomSong[i].unk_01);
|
||||
SaveManager::Instance->SaveData("unk_02", gSaveContext.scarecrowCustomSong[i].unk_02);
|
||||
SaveManager::Instance->SaveData("volume", gSaveContext.scarecrowCustomSong[i].volume);
|
||||
SaveManager::Instance->SaveData("vibrato", gSaveContext.scarecrowCustomSong[i].vibrato);
|
||||
SaveManager::Instance->SaveData("tone", gSaveContext.scarecrowCustomSong[i].tone);
|
||||
SaveManager::Instance->SaveData("semitone", gSaveContext.scarecrowCustomSong[i].semitone);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->SaveData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
|
||||
SaveManager::Instance->SaveArray("scarecrowSpawnSong", ARRAY_COUNT(gSaveContext.scarecrowSpawnSong), [](size_t i) {
|
||||
SaveManager::Instance->SaveData("", gSaveContext.scarecrowSpawnSong[i]);
|
||||
SaveManager::Instance->SaveStruct("", [&i]() {
|
||||
SaveManager::Instance->SaveData("noteIdx", gSaveContext.scarecrowSpawnSong[i].noteIdx);
|
||||
SaveManager::Instance->SaveData("unk_01", gSaveContext.scarecrowSpawnSong[i].unk_01);
|
||||
SaveManager::Instance->SaveData("unk_02", gSaveContext.scarecrowSpawnSong[i].unk_02);
|
||||
SaveManager::Instance->SaveData("volume", gSaveContext.scarecrowSpawnSong[i].volume);
|
||||
SaveManager::Instance->SaveData("vibrato", gSaveContext.scarecrowSpawnSong[i].vibrato);
|
||||
SaveManager::Instance->SaveData("tone", gSaveContext.scarecrowSpawnSong[i].tone);
|
||||
SaveManager::Instance->SaveData("semitone", gSaveContext.scarecrowSpawnSong[i].semitone);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->SaveStruct("horseData", []() {
|
||||
SaveManager::Instance->SaveData("scene", gSaveContext.horseData.scene);
|
||||
@ -1247,13 +1441,9 @@ void CopyV0Save(SaveContext_v0& src, SaveContext& dst) {
|
||||
}
|
||||
dst.worldMapAreaData = src.worldMapAreaData;
|
||||
dst.scarecrowCustomSongSet = src.scarecrowCustomSongSet;
|
||||
for (size_t i = 0; i < ARRAY_COUNT(src.scarecrowCustomSong); i++) {
|
||||
dst.scarecrowCustomSong[i] = src.scarecrowCustomSong[i];
|
||||
}
|
||||
memcpy(&dst.scarecrowCustomSong[0], &src.scarecrowCustomSong[0], sizeof(src.scarecrowCustomSong));
|
||||
dst.scarecrowSpawnSongSet = src.scarecrowSpawnSongSet;
|
||||
for (size_t i = 0; i < ARRAY_COUNT(src.scarecrowSpawnSong); i++) {
|
||||
dst.scarecrowSpawnSong[i] = src.scarecrowSpawnSong[i];
|
||||
}
|
||||
memcpy(&dst.scarecrowSpawnSong[0], &src.scarecrowSpawnSong[0], sizeof(src.scarecrowSpawnSong));
|
||||
dst.horseData.scene = src.horseData.scene;
|
||||
dst.horseData.pos.x = src.horseData.pos.x;
|
||||
dst.horseData.pos.y = src.horseData.pos.y;
|
||||
|
@ -117,6 +117,7 @@ public:
|
||||
static void SaveRandomizer();
|
||||
|
||||
static void LoadBaseVersion1();
|
||||
static void LoadBaseVersion2();
|
||||
static void SaveBase();
|
||||
|
||||
std::vector<InitFunc> initFuncs;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "global.h"
|
||||
|
||||
#ifndef __SWITCH__
|
||||
void __assert(const char* exp, const char* file, s32 line) {
|
||||
char msg[256];
|
||||
|
||||
@ -7,3 +8,4 @@ void __assert(const char* exp, const char* file, s32 line) {
|
||||
sprintf(msg, "ASSERT: %s:%d(%d)", file, line, osGetThreadId(NULL));
|
||||
Fault_AddHungupAndCrashImpl(msg, exp);
|
||||
}
|
||||
#endif
|
@ -544,10 +544,10 @@ u8 gDefaultShortNoteGateTimeTable[] = {
|
||||
};
|
||||
|
||||
AdsrEnvelope gDefaultEnvelope[] = {
|
||||
{ 0x0100, 0x007D },
|
||||
{ 0xE803, 0x007D },
|
||||
{ 0xFFFF, 0x0000 },
|
||||
{ 0x0000, 0x0000 },
|
||||
{ BE16SWAP_CONST(1), BE16SWAP_CONST(32000) },
|
||||
{ BE16SWAP_CONST(1000), BE16SWAP_CONST(32000) },
|
||||
{ BE16SWAP_CONST(-1), BE16SWAP_CONST(0) },
|
||||
{ BE16SWAP_CONST(0), BE16SWAP_CONST(0) },
|
||||
};
|
||||
|
||||
NoteSubEu gZeroNoteSub = { 0 };
|
||||
|
@ -246,7 +246,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) {
|
||||
|
||||
retry:
|
||||
case ADSR_STATE_LOOP:
|
||||
adsr->delay = (s16)BOMSWAP16(adsr->envelope[adsr->envIndex].delay);
|
||||
adsr->delay = (s16)BE16SWAP(adsr->envelope[adsr->envIndex].delay);
|
||||
switch (adsr->delay) {
|
||||
case ADSR_DISABLE:
|
||||
adsr->action.s.state = ADSR_STATE_DISABLED;
|
||||
@ -255,7 +255,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) {
|
||||
adsr->action.s.state = ADSR_STATE_HANG;
|
||||
break;
|
||||
case ADSR_GOTO:
|
||||
adsr->envIndex = (s16)BOMSWAP16(adsr->envelope[adsr->envIndex].arg);
|
||||
adsr->envIndex = (s16)BE16SWAP(adsr->envelope[adsr->envIndex].arg);
|
||||
goto retry;
|
||||
case ADSR_RESTART:
|
||||
adsr->action.s.state = ADSR_STATE_INITIAL;
|
||||
@ -266,7 +266,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) {
|
||||
if (adsr->delay == 0) {
|
||||
adsr->delay = 1;
|
||||
}
|
||||
adsr->target = (s16)BOMSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0f;
|
||||
adsr->target = (s16)BE16SWAP(adsr->envelope[adsr->envIndex].arg) / 32767.0f;
|
||||
adsr->target = adsr->target * adsr->target;
|
||||
adsr->velocity = (adsr->target - adsr->current) / adsr->delay;
|
||||
adsr->action.s.state = ADSR_STATE_FADE;
|
||||
|
@ -1340,13 +1340,13 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
||||
break;
|
||||
case 0xB2:
|
||||
offset = (u16)parameters[0];
|
||||
channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
|
||||
channel->unk_22 = BE16SWAP(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
|
||||
break;
|
||||
case 0xB4:
|
||||
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
|
||||
break;
|
||||
case 0xB5:
|
||||
channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]);
|
||||
channel->unk_22 = BE16SWAP(((u16*)(channel->dynTable))[scriptState->value]);
|
||||
break;
|
||||
case 0xB6:
|
||||
scriptState->value = (*channel->dynTable)[0][scriptState->value];
|
||||
|
@ -265,16 +265,14 @@ void* FaultDrawer_FormatStringFunc(void* arg, const char* str, u32 count) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
void FaultDrawer_VPrintf(const char* str, char* args) { // va_list
|
||||
void FaultDrawer_VPrintf(const char* str, va_list args) { // va_list
|
||||
_Printf(FaultDrawer_FormatStringFunc, (char*)&sFaultDrawerStruct, str, args);
|
||||
}
|
||||
|
||||
void FaultDrawer_Printf(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
FaultDrawer_VPrintf(fmt, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@ -284,7 +282,6 @@ void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...) {
|
||||
|
||||
FaultDrawer_SetCursor(x, y);
|
||||
FaultDrawer_VPrintf(fmt, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
@ -481,6 +481,22 @@ static void RunFrame()
|
||||
uint64_t ticksA, ticksB;
|
||||
ticksA = GetPerfCounter();
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#define SAMPLES_HIGH 752
|
||||
#define SAMPLES_LOW 720
|
||||
|
||||
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
||||
#define NUM_AUDIO_CHANNELS 2
|
||||
int samples_left = AudioPlayer_Buffered();
|
||||
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||
|
||||
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
|
||||
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
|
||||
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
|
||||
}
|
||||
|
||||
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
|
||||
#endif
|
||||
Graph_StartFrame();
|
||||
|
||||
// TODO: Workaround for rumble being too long. Implement os thread functions.
|
||||
|
@ -41,8 +41,6 @@ void main(int argc, char** argv)
|
||||
GameConsole_Init();
|
||||
InitOTR();
|
||||
BootCommands_Init();
|
||||
|
||||
BootCommands_ParseBootArgs(argc - 1, (char**)&argv[1]);
|
||||
Main(0);
|
||||
}
|
||||
|
||||
|
@ -355,36 +355,20 @@ void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, Gl
|
||||
}
|
||||
} else {
|
||||
if (actorCategory == ACTORCAT_PLAYER) {
|
||||
naviColor->inner.r = CVar_GetS32("gNavi_Idle_Inner_R", naviColor->inner.r);
|
||||
naviColor->inner.g = CVar_GetS32("gNavi_Idle_Inner_G", naviColor->inner.g);
|
||||
naviColor->inner.b = CVar_GetS32("gNavi_Idle_Inner_B", naviColor->inner.b);
|
||||
naviColor->outer.r = CVar_GetS32("gNavi_Idle_Outer_R", naviColor->outer.r);
|
||||
naviColor->outer.g = CVar_GetS32("gNavi_Idle_Outer_G", naviColor->outer.g);
|
||||
naviColor->outer.b = CVar_GetS32("gNavi_Idle_Outer_B", naviColor->outer.b);
|
||||
naviColor->inner = CVar_GetRGBA("gNavi_Idle_Inner", naviColor->inner);
|
||||
naviColor->outer = CVar_GetRGBA("gNavi_Idle_Outer", naviColor->outer);
|
||||
}
|
||||
if (actorCategory == ACTORCAT_NPC) {
|
||||
naviColor->inner.r = CVar_GetS32("gNavi_NPC_Inner_R", naviColor->inner.r);
|
||||
naviColor->inner.g = CVar_GetS32("gNavi_NPC_Inner_G", naviColor->inner.g);
|
||||
naviColor->inner.b = CVar_GetS32("gNavi_NPC_Inner_B", naviColor->inner.b);
|
||||
naviColor->outer.r = CVar_GetS32("gNavi_NPC_Outer_R", naviColor->outer.r);
|
||||
naviColor->outer.g = CVar_GetS32("gNavi_NPC_Outer_G", naviColor->outer.g);
|
||||
naviColor->outer.b = CVar_GetS32("gNavi_NPC_Outer_B", naviColor->outer.b);
|
||||
naviColor->inner = CVar_GetRGBA("gNavi_NPC_Inner", naviColor->inner);
|
||||
naviColor->outer = CVar_GetRGBA("gNavi_NPC_Outer", naviColor->outer);
|
||||
}
|
||||
if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) {
|
||||
naviColor->inner.r = CVar_GetS32("gNavi_Enemy_Inner_R", naviColor->inner.r);
|
||||
naviColor->inner.g = CVar_GetS32("gNavi_Enemy_Inner_G", naviColor->inner.g);
|
||||
naviColor->inner.b = CVar_GetS32("gNavi_Enemy_Inner_B", naviColor->inner.b);
|
||||
naviColor->outer.r = CVar_GetS32("gNavi_Enemy_Outer_R", naviColor->outer.r);
|
||||
naviColor->outer.g = CVar_GetS32("gNavi_Enemy_Outer_G", naviColor->outer.g);
|
||||
naviColor->outer.b = CVar_GetS32("gNavi_Enemy_Outer_B", naviColor->outer.b);
|
||||
naviColor->inner = CVar_GetRGBA("gNavi_Enemy_Inner", naviColor->inner);
|
||||
naviColor->outer = CVar_GetRGBA("gNavi_Enemy_Outer", naviColor->outer);
|
||||
}
|
||||
if (actorCategory == ACTORCAT_PROP) {
|
||||
naviColor->inner.r = CVar_GetS32("gNavi_Prop_Inner_R", naviColor->inner.r);
|
||||
naviColor->inner.g = CVar_GetS32("gNavi_Prop_Inner_G", naviColor->inner.g);
|
||||
naviColor->inner.b = CVar_GetS32("gNavi_Prop_Inner_B", naviColor->inner.b);
|
||||
naviColor->outer.r = CVar_GetS32("gNavi_Prop_Outer_R", naviColor->outer.r);
|
||||
naviColor->outer.g = CVar_GetS32("gNavi_Prop_Outer_G", naviColor->outer.g);
|
||||
naviColor->outer.b = CVar_GetS32("gNavi_Prop_Outer_B", naviColor->outer.b);
|
||||
naviColor->inner = CVar_GetRGBA("gNavi_Prop_Inner", naviColor->inner);
|
||||
naviColor->outer = CVar_GetRGBA("gNavi_Prop_Outer", naviColor->outer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ void SaveContext_Init(void) {
|
||||
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
|
||||
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
|
||||
gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
|
||||
gSaveContext.nextCutsceneIndex = 0xFFEF;
|
||||
gSaveContext.nextCutsceneIndex = CVar_GetS32("gBetaQuestWorld", 0xFFEF);
|
||||
gSaveContext.cutsceneTrigger = 0;
|
||||
gSaveContext.chamberCutsceneNum = 0;
|
||||
gSaveContext.nextDayTime = 0xFFFF;
|
||||
|
@ -8,7 +8,6 @@ void func_80110990(GlobalContext* globalCtx) {
|
||||
void func_801109B0(GlobalContext* globalCtx) {
|
||||
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
|
||||
u32 parameterSize;
|
||||
u16 doActionOffset;
|
||||
u8 temp;
|
||||
|
||||
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
|
||||
@ -49,30 +48,11 @@ void func_801109B0(GlobalContext* globalCtx) {
|
||||
|
||||
ASSERT(interfaceCtx->doActionSegment != NULL);
|
||||
|
||||
if (gSaveContext.language == LANGUAGE_ENG) {
|
||||
doActionOffset = 0;
|
||||
} else if (gSaveContext.language == LANGUAGE_GER) {
|
||||
doActionOffset = 0x2B80;
|
||||
} else {
|
||||
doActionOffset = 0x5700;
|
||||
}
|
||||
uint32_t attackDoActionTexSize = ResourceMgr_LoadTexSizeByName(gAttackDoActionENGTex);
|
||||
memcpy(interfaceCtx->doActionSegment, ResourceMgr_LoadTexByName(gAttackDoActionENGTex), attackDoActionTexSize);
|
||||
memcpy(interfaceCtx->doActionSegment + (attackDoActionTexSize / 2), ResourceMgr_LoadTexByName(gCheckDoActionENGTex), attackDoActionTexSize);
|
||||
|
||||
memcpy(interfaceCtx->doActionSegment, ResourceMgr_LoadTexByName(gAttackDoActionENGTex), 0x180);
|
||||
memcpy(interfaceCtx->doActionSegment + 0x180, ResourceMgr_LoadTexByName(gCheckDoActionENGTex), 0x180);
|
||||
//DmaMgr_SendRequest1(interfaceCtx->doActionSegment, (uintptr_t)_do_action_staticSegmentRomStart + doActionOffset, 0x300,
|
||||
//__FILE__, __LINE__);
|
||||
|
||||
if (gSaveContext.language == LANGUAGE_ENG) {
|
||||
doActionOffset = 0x480;
|
||||
} else if (gSaveContext.language == LANGUAGE_GER) {
|
||||
doActionOffset = 0x3000;
|
||||
} else {
|
||||
doActionOffset = 0x5B80;
|
||||
}
|
||||
|
||||
memcpy(interfaceCtx->doActionSegment + 0x300, ResourceMgr_LoadTexByName(gReturnDoActionENGTex), 0x180);
|
||||
//DmaMgr_SendRequest1(interfaceCtx->doActionSegment + 0x300, (uintptr_t)_do_action_staticSegmentRomStart + doActionOffset,
|
||||
//0x180);
|
||||
memcpy(interfaceCtx->doActionSegment + attackDoActionTexSize, ResourceMgr_LoadTexByName(gReturnDoActionENGTex), ResourceMgr_LoadTexSizeByName(gReturnDoActionENGTex));
|
||||
|
||||
interfaceCtx->iconItemSegment = GAMESTATE_ALLOC_MC(
|
||||
&globalCtx->state, 0x1000 * ARRAY_COUNT(gSaveContext.equips.buttonItems));
|
||||
|
@ -493,7 +493,8 @@ void Cutscene_Command_Terminator(GlobalContext* globalCtx, CutsceneContext* csCt
|
||||
|
||||
// Automatically skip certain cutscenes when in rando
|
||||
// cmd->base == 33: Zelda escaping with impa cutscene
|
||||
bool randoCsSkip = (gSaveContext.n64ddFlag && cmd->base == 33);
|
||||
// cmd->base == 8: Traveling back/forward in time cutscene
|
||||
bool randoCsSkip = (gSaveContext.n64ddFlag && (cmd->base == 33 || cmd->base == 8));
|
||||
bool debugCsSkip = (CHECK_BTN_ALL(globalCtx->state.input[0].press.button, BTN_START) &&
|
||||
(gSaveContext.fileNum != 0xFEDC) && CVar_GetS32("gDebugEnabled", 0));
|
||||
|
||||
|
@ -184,16 +184,6 @@ static u16 sDgnMinimapTexIndexOffset[10] = {
|
||||
0, 13, 32, 49, 76, 114, 158, 190, 217, 227,
|
||||
};
|
||||
|
||||
static u16 sOwMinimapTexSize[24] = {
|
||||
2920, 2560, 1560, 2784, 2976, 2040, 3240, 2336, 2080, 2600, 1792, 1888,
|
||||
3400, 1792, 1888, 2040, 3120, 2304, 2176, 1888, 1560, 3240, 2600, 3400,
|
||||
};
|
||||
|
||||
static u16 sOwMinimapTexOffset[24] = {
|
||||
0x0000, 0x0B68, 0x1568, 0x1B80, 0x2660, 0x3200, 0x39F8, 0x46A0, 0x4FC0, 0x57E0, 0x6208, 0x6908,
|
||||
0x7068, 0x7DB0, 0x84B0, 0x8C10, 0x9408, 0xA038, 0xA938, 0xB1B8, 0xB918, 0xBF30, 0xCBD8, 0xD600,
|
||||
};
|
||||
|
||||
static s16 sOwMinimapPosX[24] = {
|
||||
216, 216, 218, 202, 202, 250, 216, 234, 234, 216, 234, 234,
|
||||
216, 234, 234, 250, 216, 234, 234, 234, 218, 80, 80, 216,
|
||||
@ -322,11 +312,10 @@ MapData gMapDataTable = {
|
||||
sFloorTexIndexOffset, sBossFloor, sRoomPalette,
|
||||
sMaxPaletteCount, sPaletteRoom, sRoomCompassOffsetX,
|
||||
sRoomCompassOffsetY, sDgnMinimapCount, sDgnMinimapTexIndexOffset,
|
||||
sOwMinimapTexSize, sOwMinimapTexOffset, sOwMinimapPosX,
|
||||
sOwMinimapPosY, sOwCompassInfo, sDgnMinimapTexIndexBase,
|
||||
sDgnCompassInfo, sOwMinimapWidth, sOwMinimapHeight,
|
||||
sOwEntranceIconPosX, sOwEntranceIconPosY, sOwEntranceFlag,
|
||||
sFloorCoordY, sSwitchEntryCount, sSwitchFromRoom,
|
||||
sSwitchFromFloor, sSwitchToRoom, sFloorID,
|
||||
sSkullFloorIconY,
|
||||
sOwMinimapPosX, sOwMinimapPosY, sOwCompassInfo,
|
||||
sDgnMinimapTexIndexBase, sDgnCompassInfo, sOwMinimapWidth,
|
||||
sOwMinimapHeight, sOwEntranceIconPosX, sOwEntranceIconPosY,
|
||||
sOwEntranceFlag, sFloorCoordY, sSwitchEntryCount,
|
||||
sSwitchFromRoom, sSwitchFromFloor, sSwitchToRoom,
|
||||
sFloorID, sSkullFloorIconY,
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user