From 3add9798008a409ec7bf85b3829e4dc2b9b21491 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Tue, 17 May 2022 21:46:17 -0500 Subject: [PATCH] Added nintendo switch support --- .gitignore | 9 +- Makefile | 27 + ZAPDTR/ZAPDUtils/Makefile.switch | 171 ++++ ZAPDTR/ZAPDUtils/Utils/Directory.h | 4 + libultraship/Makefile.switch | 256 +++++ libultraship/libultraship/Archive.cpp | 27 +- libultraship/libultraship/Environment.cpp | 5 + libultraship/libultraship/Environment.h | 1 + libultraship/libultraship/GlobalCtx2.cpp | 4 +- .../libultraship/Lib/Fast3D/gfx_opengl.cpp | 13 +- libultraship/libultraship/Lib/Fast3D/gfx_pc.h | 5 +- .../libultraship/Lib/Fast3D/gfx_sdl2.cpp | 51 +- .../Lib/ImGui/backends/imgui_impl_opengl3.cpp | 8 +- .../Lib/ImGui/backends/imgui_impl_sdl.cpp | 14 +- .../libultraship/Lib/ImGui/imgui_internal.h | 1 + .../libultraship/Lib/ImGui/imgui_widgets.cpp | 6 +- libultraship/libultraship/SohImGuiImpl.cpp | 11 +- libultraship/libultraship/SwitchImpl.cpp | 147 +++ libultraship/libultraship/SwitchImpl.h | 16 + libultraship/libultraship/Window.cpp | 5 +- soh/Makefile.switch | 964 ++++++++++++++++++ soh/icon.jpg | Bin 0 -> 81663 bytes soh/include/functions.h | 2 + soh/soh/OTRGlobals.cpp | 2 + soh/src/boot/assert.c | 2 + soh/src/code/audio_load.c | 8 +- soh/src/code/fault_drawer.c | 9 +- 27 files changed, 1721 insertions(+), 47 deletions(-) create mode 100644 Makefile create mode 100644 ZAPDTR/ZAPDUtils/Makefile.switch create mode 100644 libultraship/Makefile.switch create mode 100644 libultraship/libultraship/SwitchImpl.cpp create mode 100644 libultraship/libultraship/SwitchImpl.h create mode 100644 soh/Makefile.switch create mode 100644 soh/icon.jpg diff --git a/.gitignore b/.gitignore index 03468a05c..2940b34a7 100644 --- a/.gitignore +++ b/.gitignore @@ -400,4 +400,11 @@ ZAPDUtils/build/ ZAPD/BuildInfo.h DebugObj/* -ReleaseObj/* \ No newline at end of file +ReleaseObj/* + +// Switch Stuff + +*.nro +*.nacp +ZAPDTR/ZAPDUtils/lib/* +!/soh/icon.jpg \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..75929fc48 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- + +export SOH_TOP_DIR := $(CURDIR) + +.PHONY: all clean ZAPDUtils libultraship soh + +all: soh + @echo "Done!" + +ZAPDUtils: + @echo "Building $@..." + @$(MAKE) --no-print-directory -C $(CURDIR)/ZAPDTR/ZAPDUtils -f $(CURDIR)/ZAPDTR/ZAPDUtils/Makefile.switch + +libultraship: 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 + +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 \ No newline at end of file diff --git a/ZAPDTR/ZAPDUtils/Makefile.switch b/ZAPDTR/ZAPDUtils/Makefile.switch new file mode 100644 index 000000000..ed173c44f --- /dev/null +++ b/ZAPDTR/ZAPDUtils/Makefile.switch @@ -0,0 +1,171 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/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): +# - .jpg +# - icon.jpg +# - /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): +# - .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 +#--------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/ZAPDTR/ZAPDUtils/Utils/Directory.h b/ZAPDTR/ZAPDUtils/Utils/Directory.h index 1ced139be..f25df2dc9 100644 --- a/ZAPDTR/ZAPDUtils/Utils/Directory.h +++ b/ZAPDTR/ZAPDUtils/Utils/Directory.h @@ -4,6 +4,10 @@ #include #include +#ifdef __SWITCH__ +long int pathconf (const char *__path, int __name){} +#endif + #if __has_include() #include namespace fs = std::filesystem; diff --git a/libultraship/Makefile.switch b/libultraship/Makefile.switch new file mode 100644 index 000000000..ad4967782 --- /dev/null +++ b/libultraship/Makefile.switch @@ -0,0 +1,256 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/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): +# - .jpg +# - icon.jpg +# - /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): +# - .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 := +DATA := +INCLUDES := \ + ../ZAPDTR/ZAPDUtils \ + libultraship/Lib/Fast3D/U64 \ + libultraship/Lib/spdlog \ + libultraship/Lib/spdlog/include \ + libultraship + +#------------------------------------------------------------------------------- +# source files +#------------------------------------------------------------------------------- +SOURCEFILES_C := \ + libultraship/mixer.c \ + libultraship/Lib/stb/stb_impl.c \ + +SOURCEFILES_CPP := \ + libultraship/Blob.cpp \ + libultraship/Cvar.cpp \ + libultraship/Environment.cpp \ + libultraship/GameSettings.cpp \ + libultraship/luslog.cpp \ + libultraship/ModManager.cpp \ + libultraship/SDLAudioPlayer.cpp \ + libultraship/Factories/AnimationFactory.cpp \ + libultraship/Factories/ArrayFactory.cpp \ + libultraship/Factories/BlobFactory.cpp \ + libultraship/Factories/CutsceneFactory.cpp \ + libultraship/Factories/MtxFactory.cpp \ + libultraship/Factories/PathFactory.cpp \ + libultraship/Animation.cpp \ + libultraship/Factories/TextFactory.cpp \ + libultraship/Factories/TextureFactory.cpp \ + libultraship/Factories/VtxFactory.cpp \ + libultraship/Array.cpp \ + libultraship/ConfigFile.cpp \ + libultraship/Controller.cpp \ + libultraship/SohHooks.cpp \ + libultraship/Factories/CollisionHeaderFactory.cpp \ + libultraship/Factories/DisplayListFactory.cpp \ + libultraship/Factories/MaterialFactory.cpp \ + libultraship/Factories/PlayerAnimationFactory.cpp \ + libultraship/Factories/ResourceLoader.cpp \ + libultraship/Factories/SceneFactory.cpp \ + libultraship/Factories/SkeletonFactory.cpp \ + libultraship/Factories/SkeletonLimbFactory.cpp \ + libultraship/Lib/Fast3D/gfx_cc.cpp \ + libultraship/Lib/Fast3D/gfx_pc.cpp \ + libultraship/Lib/Fast3D/gfx_sdl2.cpp \ + libultraship/Lib/Fast3D/gfx_opengl.cpp \ + libultraship/Lib/StrHash64.cpp \ + libultraship/Lib/tinyxml2/tinyxml2.cpp \ + libultraship/Archive.cpp \ + libultraship/CollisionHeader.cpp \ + libultraship/ControllerAttachment.cpp \ + libultraship/Cutscene.cpp \ + libultraship/DisplayList.cpp \ + libultraship/GlobalCtx2.cpp \ + libultraship/File.cpp \ + libultraship/Material.cpp \ + libultraship/Matrix.cpp \ + libultraship/MemoryPack.cpp \ + libultraship/Model.cpp \ + libultraship/Path.cpp \ + libultraship/PlayerAnimation.cpp \ + libultraship/Resource.cpp \ + libultraship/ResourceMgr.cpp \ + libultraship/RumblePack.cpp \ + libultraship/Scene.cpp \ + libultraship/Skeleton.cpp \ + libultraship/SkeletonLimb.cpp \ + libultraship/Text.cpp \ + libultraship/Texture.cpp \ + libultraship/TextureMod.cpp \ + libultraship/Utils.cpp \ + libultraship/Vertex.cpp \ + libultraship/Window.cpp \ + libultraship/WindowShim.cpp \ + libultraship/stox.cpp \ + libultraship/ \ + libultraship/GameOverlay.cpp \ + libultraship/SwitchImpl.cpp \ + libultraship/SohConsole.cpp \ + libultraship/KeyboardController.cpp \ + libultraship/SDLController.cpp \ + libultraship/SohImGuiImpl.cpp \ + libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \ + libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \ + libultraship/Lib/ImGui/imgui.cpp \ + libultraship/Lib/ImGui/imgui_demo.cpp \ + libultraship/Lib/ImGui/imgui_draw.cpp \ + libultraship/Lib/ImGui/imgui_tables.cpp \ + libultraship/Lib/ImGui/imgui_widgets.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) \ + -DSPDLOG_NO_THREAD_ID -DSPDLOG_NO_TLS \ + -DSTBI_NO_THREAD_LOCALS + +CFLAGS += $(INCLUDE) -D__SWITCH__ -DENABLE_OPENGL -DSDL_BYTEORDER + +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 +#--------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/libultraship/libultraship/Archive.cpp b/libultraship/libultraship/Archive.cpp index 1e8f8d597..4f766ca01 100644 --- a/libultraship/libultraship/Archive.cpp +++ b/libultraship/libultraship/Archive.cpp @@ -311,15 +311,14 @@ namespace Ship { bool Archive::LoadMainMPQ(bool enableWriting, bool genCRCMap) { HANDLE mpqHandle = NULL; #ifdef _WIN32 - std::wstring wfullPath = std::filesystem::absolute(MainPath).wstring(); -#endif - std::string fullPath = std::filesystem::absolute(MainPath).string(); - -#ifdef _WIN32 - if (!SFileOpenArchive(wfullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) { + std::wstring fullPath = std::filesystem::absolute(MainPath).wstring(); +#elif defined(__SWITCH__) + std::string fullPath = MainPath; #else - if (!SFileOpenArchive(fullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) { + std::string fullPath = std::filesystem::absolute(MainPath).string(); #endif + + if (!SFileOpenArchive(fullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) { SPDLOG_ERROR("({}) Failed to open main mpq file {}.", GetLastError(), fullPath.c_str()); return false; } @@ -346,18 +345,20 @@ namespace Ship { bool Archive::LoadPatchMPQ(const std::string& path) { HANDLE patchHandle = NULL; + +#ifdef _WIN32 + std::wstring fullPath = std::filesystem::absolute(path).wstring(); +#elif defined(__SWITCH__) + std::string fullPath = path; +#else std::string fullPath = std::filesystem::absolute(path).string(); +#endif + if (mpqHandles.contains(fullPath)) { return true; } - std::wstring wPath = std::filesystem::absolute(path).wstring(); - -#ifdef _WIN32 - if (!SFileOpenArchive(wPath.c_str(), 0, MPQ_OPEN_READ_ONLY, &patchHandle)) { -#else if (!SFileOpenArchive(fullPath.c_str(), 0, MPQ_OPEN_READ_ONLY, &patchHandle)) { -#endif SPDLOG_ERROR("({}) Failed to open patch mpq file {} while applying to {}.", GetLastError(), path.c_str(), MainPath.c_str()); return false; } diff --git a/libultraship/libultraship/Environment.cpp b/libultraship/libultraship/Environment.cpp index 7f10c8c44..55586c545 100644 --- a/libultraship/libultraship/Environment.cpp +++ b/libultraship/libultraship/Environment.cpp @@ -9,6 +9,11 @@ namespace SohUtils { void saveEnvironmentVar(const std::string& key, const std::string& value) { environmentVars[key] = value; } + + bool hasEnvironmentVar(const std::string& key) { + return environmentVars.find(key) != environmentVars.end(); + } + std::string getEnvironmentVar(const std::string& key) { return environmentVars[key]; } diff --git a/libultraship/libultraship/Environment.h b/libultraship/libultraship/Environment.h index 4d6ab3346..ba3d89c5e 100644 --- a/libultraship/libultraship/Environment.h +++ b/libultraship/libultraship/Environment.h @@ -4,5 +4,6 @@ namespace SohUtils { void saveEnvironmentVar(const std::string& key, const std::string& value); + bool hasEnvironmentVar(const std::string& key); std::string getEnvironmentVar(const std::string& key); } \ No newline at end of file diff --git a/libultraship/libultraship/GlobalCtx2.cpp b/libultraship/libultraship/GlobalCtx2.cpp index 5ce59f5ab..fb6219cb6 100644 --- a/libultraship/libultraship/GlobalCtx2.cpp +++ b/libultraship/libultraship/GlobalCtx2.cpp @@ -47,7 +47,7 @@ namespace Ship { } PatchesPath = (*Config)["ARCHIVE"]["Patches Directory"]; if (PatchesPath.empty()) { - PatchesPath = "./"; + PatchesPath = "./mods"; } ResMan = std::make_shared(GlobalCtx2::GetInstance(), MainPath, PatchesPath); Win = std::make_shared(GlobalCtx2::GetInstance()); @@ -56,6 +56,8 @@ namespace Ship { { #ifdef _WIN32 MessageBox(NULL, 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 diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp index b2db3186a..3e62a142f 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_opengl.cpp @@ -27,11 +27,14 @@ #include "SDL.h" #define GL_GLEXT_PROTOTYPES 1 #include "SDL_opengl.h" +#elif __SWITCH__ +#include +#include "glad/glad.h" #else #include #include #define GL_GLEXT_PROTOTYPES 1 -// #include +#include #endif #include "gfx_cc.h" @@ -562,6 +565,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: @@ -629,9 +636,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); diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_pc.h b/libultraship/libultraship/Lib/Fast3D/gfx_pc.h index 62f80ab3c..73b1c5804 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_pc.h +++ b/libultraship/libultraship/Lib/Fast3D/gfx_pc.h @@ -5,9 +5,12 @@ #include #include #include - #include "U64/PR/ultra64/types.h" +#ifdef __SWITCH__ +#include +#endif + struct GfxRenderingAPI; struct GfxWindowManagerAPI; diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp index e80097c81..6e6733029 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp @@ -13,14 +13,18 @@ #include "SDL.h" #define GL_GLEXT_PROTOTYPES 1 #include "SDL_opengl.h" -#else +#elif !defined(__SWITCH__) #include #define GL_GLEXT_PROTOTYPES 1 #include +#else +#include +#include +#include "glad/glad.h" #endif #include "../../SohImGuiImpl.h" - +#include "../../SwitchImpl.h" #include "gfx_window_manager_api.h" #include "gfx_screen_config.h" #ifdef _WIN32 @@ -37,6 +41,7 @@ static int vsync_enabled = 0; static unsigned int window_width = DESIRED_SCREEN_WIDTH; static unsigned 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); @@ -119,7 +124,7 @@ static void set_fullscreen(bool on, bool call_callback) { } static uint64_t previous_time; -#ifndef __linux__ +#if !defined(__linux__) && !defined(__SWITCH__) static HANDLE timer; #endif @@ -135,12 +140,16 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); -#ifndef __linux +#if !defined(__linux__) && !defined(__SWITCH__) timer = CreateWaitableTimer(nullptr, false, nullptr); #endif - //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); +#ifdef __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); + Ship::Switch::GetDisplaySize(&window_width, &window_height); +#endif char title[512]; int len = sprintf(title, "%s (%s)", game_name, GFX_API_NAME); @@ -148,12 +157,20 @@ static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { wnd = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); +#ifndef __SWITCH__ 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; @@ -194,15 +211,25 @@ 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 } static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { - *width = window_width; +#ifdef __SWITCH__ + Ship::Switch::GetDisplaySize(width, height); +#else + *width = window_width; *height = window_height; +#endif } static int translate_scancode(int scancode) { @@ -228,6 +255,8 @@ static void gfx_sdl_onkeyup(int scancode) { } static void gfx_sdl_handle_events(void) { + + Ship::Switch::Update(); SDL_Event event; while (SDL_PollEvent(&event)) { SohImGui::EventImpl event_impl; @@ -250,7 +279,7 @@ static void gfx_sdl_handle_events(void) { } break; case SDL_QUIT: - exit(0); + is_running = false; } } } @@ -271,7 +300,7 @@ static inline void sync_framerate_with_timer(void) { const int64_t next = qpc_to_100ns(previous_time) + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR; const int64_t left = next - qpc_to_100ns(t); if (left > 0) { -#ifdef __linux__ +#if defined(__linux__) || defined(__SWITCH__) const timespec spec = { 0, left * 100 }; nanosleep(&spec, nullptr); #else diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp index 499798bb0..5a7588629 100644 --- a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp @@ -130,7 +130,10 @@ #else #include // Use GL ES 3 #endif -#elif !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) +#elif defined(__SWITCH__) +#define GL_GLEXT_PROTOTYPES 1 +#include "glad/glad.h" +#else // 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. // In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.). @@ -216,7 +219,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Initialize our loader -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) +#if !defined(__SWITCH__) && !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) if (imgl3wInit() != 0) { fprintf(stderr, "Failed to initialize OpenGL loader!\n"); @@ -319,7 +322,6 @@ void ImGui_ImplOpenGL3_NewFrame() static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) { ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); diff --git a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp index 61e6d99ac..cb8e8dfa0 100644 --- a/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp +++ b/libultraship/libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp @@ -63,11 +63,13 @@ #include "../imgui.h" #include "imgui_impl_sdl.h" - +#include "../../../SwitchImpl.h" // SDL // (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended) #include +#ifndef __SWITCH__ #include +#endif #include #if defined(__APPLE__) #include @@ -618,6 +620,7 @@ static void ImGui_ImplSDL2_UpdateMonitors() { ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); platform_io.Monitors.resize(0); +#ifndef __SWITCH__ int display_count = SDL_GetNumVideoDisplays(); for (int n = 0; n < display_count; n++) { @@ -639,6 +642,15 @@ static void ImGui_ImplSDL2_UpdateMonitors() #endif platform_io.Monitors.push_back(monitor); } +#else + uint32_t width, height; + Ship::Switch::GetDisplaySize(&width, &height); + ImGuiPlatformMonitor monitor; + monitor.MainPos = monitor.WorkPos = ImVec2(.0f, .0f); + monitor.MainSize = monitor.WorkSize = ImVec2((float) width, (float) height); + monitor.DpiScale = Ship::Switch::GetDPI() / 96.0f; + platform_io.Monitors.push_back(monitor); +#endif } void ImGui_ImplSDL2_NewFrame() diff --git a/libultraship/libultraship/Lib/ImGui/imgui_internal.h b/libultraship/libultraship/Lib/ImGui/imgui_internal.h index b8212198b..b5cfba80c 100644 --- a/libultraship/libultraship/Lib/ImGui/imgui_internal.h +++ b/libultraship/libultraship/Lib/ImGui/imgui_internal.h @@ -1021,6 +1021,7 @@ struct IMGUI_API ImGuiInputTextState bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection bool Edited; // edited this frame ImGuiInputTextFlags Flags; // copy of InputText() flags + char* OverwriteData; ImGuiInputTextState() { memset(this, 0, sizeof(*this)); } void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); } diff --git a/libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp b/libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp index 8e4210002..ac09cf85d 100644 --- a/libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp +++ b/libultraship/libultraship/Lib/ImGui/imgui_widgets.cpp @@ -4261,6 +4261,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const bool is_paste = ((is_shortcut_key && IsKeyPressed(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressed(ImGuiKey_Insert))) && !is_readonly; const bool is_undo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Z)) && !is_readonly && is_undoable); const bool is_redo = ((is_shortcut_key && IsKeyPressed(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressed(ImGuiKey_Z))) && !is_readonly && is_undoable; + const bool is_overwrite = state->OverwriteData != NULL; // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful. const bool is_validate_enter = IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_KeypadEnter); @@ -4341,9 +4342,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ stb_textedit_cut(state, &state->Stb); } } - else if (is_paste) + else if (is_paste || is_overwrite) { - if (const char* clipboard = GetClipboardText()) + if (const char* clipboard = is_overwrite ? state->OverwriteData : GetClipboardText()) { // Filter pasted buffer const int clipboard_len = (int)strlen(clipboard); @@ -4365,6 +4366,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ stb_textedit_paste(state, &state->Stb, clipboard_filtered, clipboard_filtered_len); state->CursorFollow = true; } + if(is_overwrite) state->OverwriteData = NULL; MemFree(clipboard_filtered); } } diff --git a/libultraship/libultraship/SohImGuiImpl.cpp b/libultraship/libultraship/SohImGuiImpl.cpp index 8e4becaab..e4636e23f 100644 --- a/libultraship/libultraship/SohImGuiImpl.cpp +++ b/libultraship/libultraship/SohImGuiImpl.cpp @@ -25,6 +25,7 @@ #include "Lib/Fast3D/gfx_rendering_api.h" #include "Lib/spdlog/include/spdlog/common.h" #include "Utils/StringHelper.h" +#include "SwitchImpl.h" #ifdef ENABLE_OPENGL #include "Lib/ImGui/backends/imgui_impl_opengl3.h" @@ -335,6 +336,9 @@ namespace SohImGui { overlay->Init(); ImGuiWMInit(); ImGuiBackendInit(); + #ifdef __SWITCH__ + ImGui::GetStyle().ScaleAllSizes(Ship::Switch::GetDPI() / 96.0f); + #endif ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) { @@ -368,6 +372,11 @@ namespace SohImGui { } void Update(EventImpl event) { + #ifdef __SWITCH__ + int xPos, yPos; + Switch::GetTouchPosition(&xPos, &yPos); + io->MousePos = ImVec2(xPos, yPos); + #endif if (needs_save) { Game::SaveSettings(); needs_save = false; @@ -524,7 +533,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); diff --git a/libultraship/libultraship/SwitchImpl.cpp b/libultraship/libultraship/SwitchImpl.cpp new file mode 100644 index 000000000..c8cef3d10 --- /dev/null +++ b/libultraship/libultraship/SwitchImpl.cpp @@ -0,0 +1,147 @@ +#ifdef __SWITCH__ +#include "SwitchImpl.h" +#include +#include +#include "Lib/ImGui/imgui.h" +#include "Lib/ImGui/imgui_internal.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 int MouseX, MouseY, Prev_TouchCount; +static int WaitFramesToUpdate; +static HidTouchScreenState TouchState = {0}; +static SwkbdConfig kbd; +static PadState pad; + +void InitKeyboard(){ + Result rc = 0; + char tmpoutstr[16] = {0}; + rc = swkbdCreate(&kbd, 0); + if (R_SUCCEEDED(rc)) + swkbdConfigMakePresetDefault(&kbd); +} + +// TODO: Fully Implement Keyboard + +void UpdateKeyboard() { + ImGuiIO* io = &ImGui::GetIO(); + int length = 512; + char* message; + + if(WaitFramesToUpdate > 0) + WaitFramesToUpdate--; + + if(WaitFramesToUpdate){ + ImGui::ClearActiveID(); + free(message); + } + + if(io->WantTextInput && !WaitFramesToUpdate){ + message = (char*)malloc(length); + ImGuiInputTextState* state = ImGui::GetInputTextState(ImGui::GetActiveID()); + if(!state->InitialTextA.empty()){ + swkbdConfigSetInitialText(&kbd, state->InitialTextA.Data); + } + + Result rc = swkbdShow(&kbd, message, length); + + if(R_SUCCEEDED(rc)){ + state->ClearText(); + state->OverwriteData = &message[0]; + } + + WaitFramesToUpdate = 2; + io->WantTextInput = false; + } +} + +void Ship::Switch::Init(){ + appletInitializeGamePlayRecording(); + socketInitializeDefault(); + nxlinkStdio(); + appletSetGamePlayRecordingState(true); + padConfigureInput(1, HidNpadStyleSet_NpadStandard); + padInitializeDefault(&pad); + hidInitializeTouchScreen(); + InitKeyboard(); +} + +void PushSDLEvent(Uint32 type, Uint8 button){ + SDL_Event event; + event.type = type; + event.button.button = button; + SDL_PushEvent(&event); +} + +void Ship::Switch::Update(){ + UpdateKeyboard(); + padUpdate(&pad); + uint64_t kDown = padGetButtonsDown(&pad); + + if (kDown & HidNpadButton_Minus){ + CVar_SetS32("gOpenMenuBar", !CVar_GetS32("gOpenMenuBar", 0)); + } + + if (hidGetTouchScreenStates(&TouchState, 1)) { + if (TouchState.count != Prev_TouchCount) { + Prev_TouchCount = TouchState.count; + PushSDLEvent(SDL_MOUSEBUTTONUP, SDL_BUTTON_LEFT); + PushSDLEvent(SDL_MOUSEBUTTONUP, SDL_BUTTON_RIGHT); + } + + for(s32 i = 0; i < TouchState.count; i++) { + MouseX = TouchState.touches[0].x; + MouseY = TouchState.touches[0].y; + } + + if(TouchState.count == 1) { + PushSDLEvent(SDL_MOUSEBUTTONDOWN, SDL_BUTTON_LEFT); + return; + } + + if(TouchState.count > 1) { + PushSDLEvent(SDL_MOUSEBUTTONDOWN, SDL_BUTTON_RIGHT); + } + } +} + +void Ship::Switch::Exit(){ + socketExit(); + appletSetGamePlayRecordingState(false); +} + +bool Ship::Switch::IsRunning(){ + return appletMainLoop(); +} + +void Ship::Switch::GetDisplaySize(uint32_t *width, uint32_t *height) { + switch (appletGetOperationMode()) { + case DOCKED_MODE: + *width = 1920; + *height = 1080; + break; + case HANDHELD_MODE: + *width = 1280; + *height = 720; + break; + } +} + +void Ship::Switch::GetTouchPosition(int *touchX, int *touchY) { + *touchX = MouseX; + *touchY = MouseY; +} + +float Ship::Switch::GetDPI(){ + switch (appletGetOperationMode()) { + case DOCKED_MODE: + return 56.48480f; + case HANDHELD_MODE: + return 236.8717f; + } +} +#endif \ No newline at end of file diff --git a/libultraship/libultraship/SwitchImpl.h b/libultraship/libultraship/SwitchImpl.h new file mode 100644 index 000000000..3ff2f3749 --- /dev/null +++ b/libultraship/libultraship/SwitchImpl.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace Ship { +class Switch { +public: + static void Init(); + static void Exit(); + static void Update(); + static bool IsRunning(); + static void GetDisplaySize(uint32_t *width, uint32_t *height); + static void GetTouchPosition(int *touchX, int *touchY); + static float GetDPI(); +}; +}; \ No newline at end of file diff --git a/libultraship/libultraship/Window.cpp b/libultraship/libultraship/Window.cpp index 588e3af50..3a22973af 100644 --- a/libultraship/libultraship/Window.cpp +++ b/libultraship/libultraship/Window.cpp @@ -42,6 +42,7 @@ extern "C" { exit(EXIT_FAILURE); } + #ifndef __SWITCH__ const char* controllerDb = "gamecontrollerdb.txt"; int mappingsAdded = SDL_GameControllerAddMappingsFromFile(controllerDb); if (mappingsAdded >= 0) { @@ -49,7 +50,7 @@ extern "C" { } else { SPDLOG_ERROR("Failed add SDL game controller mappings from \"{}\" ({})", controllerDb, SDL_GetError()); } - + #endif // TODO: This for loop is debug. Burn it with fire. for (int i = 0; i < SDL_NumJoysticks(); i++) { if (SDL_IsGameController(i)) { @@ -333,8 +334,6 @@ namespace Ship { GlobalCtx2::GetInstance()->GetWindow()->ToggleFullscreen(); } - - // OTRTODO: Rig with Kirito's console? //if (dwScancode == Ship::stoi(Conf["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"])) { // ToggleConsole(); diff --git a/soh/Makefile.switch b/soh/Makefile.switch new file mode 100644 index 000000000..9344de6d1 --- /dev/null +++ b/soh/Makefile.switch @@ -0,0 +1,964 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/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): +# - .jpg +# - icon.jpg +# - /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): +# - .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 := \ + soh/Enhancements/bootcommands.c \ + soh/Enhancements/gameconsole.c \ + soh/gu_pc.c \ + soh/stubs.c \ + src/boot/assert.c \ + src/boot/boot_main.c \ + src/boot/build.c \ + src/boot/idle.c \ + src/boot/is_debug.c \ + src/boot/logutils.c \ + src/boot/missing_gcc_functions.c \ + src/boot/stackcheck.c \ + src/boot/viconfig.c \ + src/boot/yaz0.c \ + src/boot/z_locale.c \ + src/boot/z_std_dma.c \ + src/buffers/gfxbuffers.c \ + src/buffers/heaps.c \ + src/buffers/zbuffer.c \ + src/code/audioMgr.c \ + src/code/audio_data.c \ + src/code/audio_effects.c \ + src/code/audio_heap.c \ + src/code/audio_init_params.c \ + src/code/audio_load.c \ + src/code/audio_playback.c \ + src/code/audio_seqplayer.c \ + src/code/audio_sound_params.c \ + src/code/audio_synthesis.c \ + src/code/code_800430A0.c \ + src/code/code_80043480.c \ + src/code/code_8006C3A0.c \ + src/code/code_8006C510.c \ + src/code/code_80097A00.c \ + src/code/code_800A9F30.c \ + src/code/code_800ACE70.c \ + src/code/code_800AD920.c \ + src/code/code_800BB0A0.c \ + src/code/code_800C3C20.c \ + src/code/code_800D2E30.c \ + src/code/code_800D31A0.c \ + src/code/code_800E4FE0.c \ + src/code/code_800E6840.c \ + src/code/code_800EC960.c \ + src/code/code_800F7260.c \ + src/code/code_800F9280.c \ + src/code/code_800FBCE0.c \ + src/code/code_800FC620.c \ + src/code/code_800FCE80.c \ + src/code/code_800FD970.c \ + src/code/code_801067F0.c \ + src/code/code_801068B0.c \ + src/code/db_camera.c \ + src/code/debug_malloc.c \ + src/code/fault.c \ + src/code/fault_drawer.c \ + src/code/flg_set.c \ + src/code/game.c \ + src/code/gamealloc.c \ + src/code/gfxprint.c \ + src/code/graph.c \ + src/code/irqmgr.c \ + src/code/jpegdecoder.c \ + src/code/jpegutils.c \ + src/code/listalloc.c \ + src/code/loadfragment2.c \ + src/code/logseverity.c \ + src/code/main.c \ + src/code/mempak.c \ + src/code/mtxuty-cvt.c \ + src/code/padmgr.c \ + src/code/padsetup.c \ + src/code/padutils.c \ + src/code/PreRender.c \ + src/code/printutils.c \ + src/code/relocation.c \ + src/code/sched.c \ + src/code/shrink_window.c \ + src/code/sleep.c \ + src/code/speed_meter.c \ + src/code/system_malloc.c \ + src/code/sys_cfb.c \ + src/code/sys_math.c \ + src/code/sys_math3d.c \ + src/code/sys_math_atan.c \ + src/code/sys_matrix.c \ + src/code/sys_ucode.c \ + src/code/title_setup.c \ + src/code/TwoHeadArena.c \ + src/code/ucode_disas.c \ + src/code/z_actor.c \ + src/code/z_actor_dlftbls.c \ + src/code/z_bgcheck.c \ + src/code/z_camera.c \ + src/code/z_cheap_proc.c \ + src/code/z_collision_btltbls.c \ + src/code/z_collision_check.c \ + src/code/z_common_data.c \ + src/code/z_construct.c \ + src/code/z_debug.c \ + src/code/z_debug_display.c \ + src/code/z_demo.c \ + src/code/z_DLF.c \ + src/code/z_draw.c \ + src/code/z_effect.c \ + src/code/z_effect_soft_sprite.c \ + src/code/z_effect_soft_sprite_dlftbls.c \ + src/code/z_effect_soft_sprite_old_init.c \ + src/code/z_eff_blure.c \ + src/code/z_eff_shield_particle.c \ + src/code/z_eff_spark.c \ + src/code/z_eff_ss_dead.c \ + src/code/z_elf_message.c \ + src/code/z_en_a_keep.c \ + src/code/z_en_item00.c \ + src/code/z_face_reaction.c \ + src/code/z_fbdemo.c \ + src/code/z_fbdemo_circle.c \ + src/code/z_fbdemo_fade.c \ + src/code/z_fbdemo_triforce.c \ + src/code/z_fbdemo_wipe1.c \ + src/code/z_fcurve_data_skelanime.c \ + src/code/z_frame_advance.c \ + src/code/z_game_dlftbls.c \ + src/code/z_game_over.c \ + src/code/z_horse.c \ + src/code/z_jpeg.c \ + src/code/z_kaleido_manager.c \ + src/code/z_kaleido_scope_call.c \ + src/code/z_kaleido_setup.c \ + src/code/z_kanfont.c \ + src/code/z_kankyo.c \ + src/code/z_lib.c \ + src/code/z_lifemeter.c \ + src/code/z_lights.c \ + src/code/z_malloc.c \ + src/code/z_map_data.c \ + src/code/z_map_exp.c \ + src/code/z_map_mark.c \ + src/code/z_message_PAL.c \ + src/code/z_moji.c \ + src/code/z_msgevent.c \ + src/code/z_olib.c \ + src/code/z_onepointdemo.c \ + src/code/z_parameter.c \ + src/code/z_path.c \ + src/code/z_play.c \ + src/code/z_player_call.c \ + src/code/z_player_lib.c \ + src/code/z_prenmi.c \ + src/code/z_prenmi_buff.c \ + src/code/z_quake.c \ + src/code/z_rcp.c \ + src/code/z_room.c \ + src/code/z_sample.c \ + src/code/z_scene.c \ + src/code/z_scene_table.c \ + src/code/z_skelanime.c \ + src/code/z_skin.c \ + src/code/z_skin_awb.c \ + src/code/z_skin_matrix.c \ + src/code/z_sound_source.c \ + src/code/z_sram.c \ + src/code/z_ss_sram.c \ + src/code/z_view.c \ + src/code/z_vimode.c \ + src/code/z_vismono.c \ + src/code/z_vr_box.c \ + src/code/z_vr_box_draw.c \ + src/code/__osMalloc.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 \ + src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c \ + src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c \ + src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c \ + src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c \ + src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c \ + src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c \ + src/overlays/actors/ovl_Bg_Bombwall/z_bg_bombwall.c \ + src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.c \ + src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.c \ + src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c \ + src/overlays/actors/ovl_Bg_Ddan_Jd/z_bg_ddan_jd.c \ + src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c \ + src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c \ + src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c \ + src/overlays/actors/ovl_Bg_Ganon_Otyuka/z_bg_ganon_otyuka.c \ + src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c \ + src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c \ + src/overlays/actors/ovl_Bg_Gnd_Darkmeiro/z_bg_gnd_darkmeiro.c \ + src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c \ + src/overlays/actors/ovl_Bg_Gnd_Iceblock/z_bg_gnd_iceblock.c \ + src/overlays/actors/ovl_Bg_Gnd_Nisekabe/z_bg_gnd_nisekabe.c \ + src/overlays/actors/ovl_Bg_Gnd_Soulmeiro/z_bg_gnd_soulmeiro.c \ + src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c \ + src/overlays/actors/ovl_Bg_Haka_Gate/z_bg_haka_gate.c \ + src/overlays/actors/ovl_Bg_Haka_Huta/z_bg_haka_huta.c \ + src/overlays/actors/ovl_Bg_Haka_MeganeBG/z_bg_haka_meganebg.c \ + src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c \ + src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.c \ + src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c \ + src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c \ + src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c \ + src/overlays/actors/ovl_Bg_Haka_Water/z_bg_haka_water.c \ + src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c \ + src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c \ + src/overlays/actors/ovl_Bg_Hidan_Curtain/z_bg_hidan_curtain.c \ + src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c \ + src/overlays/actors/ovl_Bg_Hidan_Firewall/z_bg_hidan_firewall.c \ + src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c \ + src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c \ + src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c \ + src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c \ + src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.c \ + src/overlays/actors/ovl_Bg_Hidan_Kowarerukabe/z_bg_hidan_kowarerukabe.c \ + src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c \ + src/overlays/actors/ovl_Bg_Hidan_Rsekizou/z_bg_hidan_rsekizou.c \ + src/overlays/actors/ovl_Bg_Hidan_Sekizou/z_bg_hidan_sekizou.c \ + src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c \ + src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c \ + src/overlays/actors/ovl_Bg_Ice_Objects/z_bg_ice_objects.c \ + src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c \ + src/overlays/actors/ovl_Bg_Ice_Shutter/z_bg_ice_shutter.c \ + src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c \ + src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c \ + src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c \ + src/overlays/actors/ovl_Bg_Jya_Amishutter/z_bg_jya_amishutter.c \ + src/overlays/actors/ovl_Bg_Jya_Bigmirror/z_bg_jya_bigmirror.c \ + src/overlays/actors/ovl_Bg_Jya_Block/z_bg_jya_block.c \ + src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.c \ + src/overlays/actors/ovl_Bg_Jya_Bombiwa/z_bg_jya_bombiwa.c \ + src/overlays/actors/ovl_Bg_Jya_Cobra/z_bg_jya_cobra.c \ + src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.c \ + src/overlays/actors/ovl_Bg_Jya_Haheniron/z_bg_jya_haheniron.c \ + src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.c \ + src/overlays/actors/ovl_Bg_Jya_Kanaami/z_bg_jya_kanaami.c \ + src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c \ + src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c \ + src/overlays/actors/ovl_Bg_Jya_Zurerukabe/z_bg_jya_zurerukabe.c \ + src/overlays/actors/ovl_Bg_Menkuri_Eye/z_bg_menkuri_eye.c \ + src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c \ + src/overlays/actors/ovl_Bg_Menkuri_Nisekabe/z_bg_menkuri_nisekabe.c \ + src/overlays/actors/ovl_Bg_Mizu_Bwall/z_bg_mizu_bwall.c \ + src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c \ + src/overlays/actors/ovl_Bg_Mizu_Shutter/z_bg_mizu_shutter.c \ + src/overlays/actors/ovl_Bg_Mizu_Uzu/z_bg_mizu_uzu.c \ + src/overlays/actors/ovl_Bg_Mizu_Water/z_bg_mizu_water.c \ + src/overlays/actors/ovl_Bg_Mjin/z_bg_mjin.c \ + src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c \ + src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c \ + src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c \ + src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.c \ + src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c \ + src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c \ + src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c \ + src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c \ + src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c \ + src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.c \ + src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c \ + src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c \ + src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.c \ + src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c \ + src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.c \ + src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c \ + src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c \ + src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c \ + src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.c \ + src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c \ + src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c \ + src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.c \ + src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c \ + src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.c \ + src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c \ + src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c \ + src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.c \ + src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c \ + src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c \ + src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.c \ + src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c \ + src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c \ + src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.c \ + src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c \ + src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.c \ + src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c \ + src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.c \ + src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c \ + src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.c \ + src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c \ + src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.c \ + src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c \ + src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c \ + src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c \ + src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_1.c \ + src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_2.c \ + src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_3.c \ + src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c \ + src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth_cutscene_data.c \ + src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c \ + src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c \ + src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.c \ + src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c \ + src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c \ + src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c \ + src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c \ + src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo_data.c \ + src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c \ + src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2_colchk.c \ + src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c \ + src/overlays/actors/ovl_Boss_Fd/z_boss_fd_colchk.c \ + src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c \ + src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2_data.c \ + src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c \ + src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c \ + src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c \ + src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c \ + src/overlays/actors/ovl_Boss_Mo/z_boss_mo_colchk.c \ + src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c \ + src/overlays/actors/ovl_Boss_Sst/z_boss_sst_colchk.c \ + src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c \ + src/overlays/actors/ovl_Boss_Va/z_boss_va.c \ + src/overlays/actors/ovl_Demo_6K/z_demo_6k.c \ + src/overlays/actors/ovl_Demo_Du/z_demo_du.c \ + src/overlays/actors/ovl_Demo_Du/z_demo_du_cutscene_data.c \ + src/overlays/actors/ovl_Demo_Ec/z_demo_ec.c \ + src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c \ + src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c \ + src/overlays/actors/ovl_Demo_Geff/z_demo_geff.c \ + src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c \ + src/overlays/actors/ovl_Demo_Go/z_demo_go.c \ + src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c \ + src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c \ + src/overlays/actors/ovl_Demo_Im/z_demo_im.c \ + src/overlays/actors/ovl_Demo_Im/z_demo_im_cutscene_data.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data1.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data2.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data3.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data4.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data5.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data6.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data7.c \ + src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data8.c \ + src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c \ + src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c \ + src/overlays/actors/ovl_Demo_Sa/z_demo_sa_cutscene_data.c \ + src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c \ + src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c \ + src/overlays/actors/ovl_Door_Ana/z_door_ana.c \ + src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c \ + src/overlays/actors/ovl_Door_Killer/z_door_killer.c \ + src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c \ + src/overlays/actors/ovl_Door_Toki/z_door_toki.c \ + src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c \ + src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c \ + src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c \ + src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c \ + src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c \ + src/overlays/actors/ovl_End_Title/z_end_title.c \ + src/overlays/actors/ovl_En_Am/z_en_am.c \ + src/overlays/actors/ovl_En_Ani/z_en_ani.c \ + src/overlays/actors/ovl_En_Anubice/z_en_anubice.c \ + src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c \ + src/overlays/actors/ovl_En_Anubice_Tag/z_en_anubice_tag.c \ + src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.c \ + src/overlays/actors/ovl_En_Arrow/z_en_arrow.c \ + src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c \ + src/overlays/actors/ovl_En_Ba/z_en_ba.c \ + src/overlays/actors/ovl_En_Bb/z_en_bb.c \ + src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c \ + src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c \ + src/overlays/actors/ovl_En_Bili/z_en_bili.c \ + src/overlays/actors/ovl_En_Bird/z_en_bird.c \ + src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.c \ + src/overlays/actors/ovl_En_Bombf/z_en_bombf.c \ + src/overlays/actors/ovl_En_Bom/z_en_bom.c \ + src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c \ + src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c \ + src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c \ + src/overlays/actors/ovl_En_Boom/z_en_boom.c \ + src/overlays/actors/ovl_En_Box/z_en_box.c \ + src/overlays/actors/ovl_En_Brob/z_en_brob.c \ + src/overlays/actors/ovl_En_Bubble/z_en_bubble.c \ + src/overlays/actors/ovl_En_Butte/z_en_butte.c \ + src/overlays/actors/ovl_En_Bw/z_en_bw.c \ + src/overlays/actors/ovl_En_Bx/z_en_bx.c \ + src/overlays/actors/ovl_En_Changer/z_en_changer.c \ + src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c \ + src/overlays/actors/ovl_En_Cow/z_en_cow.c \ + src/overlays/actors/ovl_En_Crow/z_en_crow.c \ + src/overlays/actors/ovl_En_Cs/z_en_cs.c \ + src/overlays/actors/ovl_En_Daiku/z_en_daiku.c \ + src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c \ + src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c \ + src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c \ + src/overlays/actors/ovl_En_Dha/z_en_dha.c \ + src/overlays/actors/ovl_En_Dh/z_en_dh.c \ + src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c \ + src/overlays/actors/ovl_En_Dns/z_en_dns.c \ + src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c \ + src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c \ + src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c \ + src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c \ + src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c \ + src/overlays/actors/ovl_En_Dog/z_en_dog.c \ + src/overlays/actors/ovl_En_Door/z_en_door.c \ + src/overlays/actors/ovl_En_Ds/z_en_ds.c \ + src/overlays/actors/ovl_En_Du/z_en_du.c \ + src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c \ + src/overlays/actors/ovl_En_Eg/z_en_eg.c \ + src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c \ + src/overlays/actors/ovl_En_Elf/z_en_elf.c \ + src/overlays/actors/ovl_En_Encount1/z_en_encount1.c \ + src/overlays/actors/ovl_En_Encount2/z_en_encount2.c \ + src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c \ + src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c \ + src/overlays/actors/ovl_En_Fd/z_en_fd.c \ + src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c \ + src/overlays/actors/ovl_En_fHG/z_en_fhg.c \ + src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c \ + src/overlays/actors/ovl_En_Firefly/z_en_firefly.c \ + src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c \ + src/overlays/actors/ovl_En_Fish/z_en_fish.c \ + src/overlays/actors/ovl_En_Floormas/z_en_floormas.c \ + src/overlays/actors/ovl_En_Fr/z_en_fr.c \ + src/overlays/actors/ovl_En_Fu/z_en_fu.c \ + src/overlays/actors/ovl_En_Fw/z_en_fw.c \ + src/overlays/actors/ovl_En_Fz/z_en_fz.c \ + src/overlays/actors/ovl_En_Ganon_Mant/z_en_ganon_mant.c \ + src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.c \ + src/overlays/actors/ovl_En_Gb/z_en_gb.c \ + src/overlays/actors/ovl_En_Ge1/z_en_ge1.c \ + src/overlays/actors/ovl_En_Ge2/z_en_ge2.c \ + src/overlays/actors/ovl_En_Ge3/z_en_ge3.c \ + src/overlays/actors/ovl_En_GeldB/z_en_geldb.c \ + src/overlays/actors/ovl_En_GirlA/z_en_girla.c \ + src/overlays/actors/ovl_En_Gm/z_en_gm.c \ + src/overlays/actors/ovl_En_Go2/z_en_go2.c \ + src/overlays/actors/ovl_En_Goma/z_en_goma.c \ + src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c \ + src/overlays/actors/ovl_En_Go/z_en_go.c \ + src/overlays/actors/ovl_En_Gs/z_en_gs.c \ + src/overlays/actors/ovl_En_Guest/z_en_guest.c \ + src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c \ + src/overlays/actors/ovl_En_Hata/z_en_hata.c \ + src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c \ + src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c \ + src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c \ + src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c \ + src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c \ + src/overlays/actors/ovl_En_Holl/z_en_holl.c \ + src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c \ + src/overlays/actors/ovl_En_Horse/z_en_horse.c \ + src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c \ + src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c \ + src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c \ + src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c \ + src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c \ + src/overlays/actors/ovl_En_Hs2/z_en_hs2.c \ + src/overlays/actors/ovl_En_Hs/z_en_hs.c \ + src/overlays/actors/ovl_En_Hy/z_en_hy.c \ + src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c \ + src/overlays/actors/ovl_En_Ik/z_en_ik.c \ + src/overlays/actors/ovl_En_Insect/z_en_insect.c \ + src/overlays/actors/ovl_En_In/z_en_in.c \ + src/overlays/actors/ovl_En_Ishi/z_en_ishi.c \ + src/overlays/actors/ovl_En_It/z_en_it.c \ + src/overlays/actors/ovl_En_Jj/z_en_jj.c \ + src/overlays/actors/ovl_En_Jj/z_en_jj_cutscene_data.c \ + src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c \ + src/overlays/actors/ovl_En_Js/z_en_js.c \ + src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c \ + src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c \ + src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c \ + src/overlays/actors/ovl_En_Kanban/z_en_kanban.c \ + src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c \ + src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c \ + src/overlays/actors/ovl_En_Ko/z_en_ko.c \ + src/overlays/actors/ovl_En_Kusa/z_en_kusa.c \ + src/overlays/actors/ovl_En_Kz/z_en_kz.c \ + src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c \ + src/overlays/actors/ovl_En_Light/z_en_light.c \ + src/overlays/actors/ovl_En_Ma1/z_en_ma1.c \ + src/overlays/actors/ovl_En_Ma2/z_en_ma2.c \ + src/overlays/actors/ovl_En_Ma3/z_en_ma3.c \ + src/overlays/actors/ovl_En_Mag/z_en_mag.c \ + src/overlays/actors/ovl_En_Mb/z_en_mb.c \ + src/overlays/actors/ovl_En_Md/z_en_md.c \ + src/overlays/actors/ovl_En_Mk/z_en_mk.c \ + src/overlays/actors/ovl_En_Mm2/z_en_mm2.c \ + src/overlays/actors/ovl_En_Mm/z_en_mm.c \ + src/overlays/actors/ovl_En_Ms/z_en_ms.c \ + src/overlays/actors/ovl_En_Mu/z_en_mu.c \ + src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c \ + src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c \ + src/overlays/actors/ovl_En_Nb/z_en_nb.c \ + src/overlays/actors/ovl_En_Nb/z_en_nb_cutscene_data.c \ + src/overlays/actors/ovl_En_Niw/z_en_niw.c \ + src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c \ + src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c \ + src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c \ + src/overlays/actors/ovl_En_Nwc/z_en_nwc.c \ + src/overlays/actors/ovl_En_Ny/z_en_ny.c \ + src/overlays/actors/ovl_En_OE2/z_en_oe2.c \ + src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c \ + src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c \ + src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag_cutscene_data.c \ + src/overlays/actors/ovl_En_Okuta/z_en_okuta.c \ + src/overlays/actors/ovl_En_Ossan/z_en_ossan.c \ + src/overlays/actors/ovl_En_Owl/z_en_owl.c \ + src/overlays/actors/ovl_En_Part/z_en_part.c \ + src/overlays/actors/ovl_En_Peehat/z_en_peehat.c \ + src/overlays/actors/ovl_En_Poh/z_en_poh.c \ + src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c \ + src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c \ + src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c \ + src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c \ + src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c \ + src/overlays/actors/ovl_En_Rd/z_en_rd.c \ + src/overlays/actors/ovl_En_Reeba/z_en_reeba.c \ + src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c \ + src/overlays/actors/ovl_En_Rl/z_en_rl.c \ + src/overlays/actors/ovl_En_Rr/z_en_rr.c \ + src/overlays/actors/ovl_En_Ru1/z_en_ru1.c \ + src/overlays/actors/ovl_En_Ru1/z_en_ru1_cutscene_data.c \ + src/overlays/actors/ovl_En_Ru2/z_en_ru2.c \ + src/overlays/actors/ovl_En_Ru2/z_en_ru2_cutscene_data.c \ + src/overlays/actors/ovl_En_Sa/z_en_sa.c \ + src/overlays/actors/ovl_En_Sb/z_en_sb.c \ + src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.c \ + src/overlays/actors/ovl_En_Sda/z_en_sda.c \ + src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c \ + src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c \ + src/overlays/actors/ovl_En_Si/z_en_si.c \ + src/overlays/actors/ovl_En_Skb/z_en_skb.c \ + src/overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.c \ + src/overlays/actors/ovl_En_Skj/z_en_skj.c \ + src/overlays/actors/ovl_En_Ssh/z_en_ssh.c \ + src/overlays/actors/ovl_En_Sth/z_en_sth.c \ + src/overlays/actors/ovl_En_Stream/z_en_stream.c \ + src/overlays/actors/ovl_En_St/z_en_st.c \ + src/overlays/actors/ovl_En_Sw/z_en_sw.c \ + src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c \ + src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c \ + src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c \ + src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c \ + src/overlays/actors/ovl_En_Tana/z_en_tana.c \ + src/overlays/actors/ovl_En_Ta/z_en_ta.c \ + src/overlays/actors/ovl_En_Test/z_en_test.c \ + src/overlays/actors/ovl_En_Tg/z_en_tg.c \ + src/overlays/actors/ovl_En_Tite/z_en_tite.c \ + src/overlays/actors/ovl_En_Tk/z_en_tk.c \ + src/overlays/actors/ovl_En_Torch2/z_en_torch2.c \ + src/overlays/actors/ovl_En_Torch/z_en_torch.c \ + src/overlays/actors/ovl_En_Toryo/z_en_toryo.c \ + src/overlays/actors/ovl_En_Tp/z_en_tp.c \ + src/overlays/actors/ovl_En_Trap/z_en_trap.c \ + src/overlays/actors/ovl_En_Tr/z_en_tr.c \ + src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c \ + src/overlays/actors/ovl_En_Vali/z_en_vali.c \ + src/overlays/actors/ovl_En_Vase/z_en_vase.c \ + src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c \ + src/overlays/actors/ovl_En_Viewer/z_en_viewer.c \ + src/overlays/actors/ovl_En_Vm/z_en_vm.c \ + src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c \ + src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c \ + src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c \ + src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c \ + src/overlays/actors/ovl_En_Wf/z_en_wf.c \ + src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c \ + src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c \ + src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c \ + src/overlays/actors/ovl_En_Wood02/z_en_wood02.c \ + src/overlays/actors/ovl_En_Xc/z_en_xc.c \ + src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c \ + src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c \ + src/overlays/actors/ovl_En_Zf/z_en_zf.c \ + src/overlays/actors/ovl_En_Zl1/z_en_zl1.c \ + src/overlays/actors/ovl_En_Zl1/z_en_zl1_camera_data.c \ + src/overlays/actors/ovl_En_Zl1/z_en_zl1_cutscene_data.c \ + src/overlays/actors/ovl_En_Zl2/z_en_zl2.c \ + src/overlays/actors/ovl_En_Zl3/z_en_zl3.c \ + src/overlays/actors/ovl_En_Zl4/z_en_zl4.c \ + src/overlays/actors/ovl_En_Zl4/z_en_zl4_cutscene_data.c \ + src/overlays/actors/ovl_En_Zo/z_en_zo.c \ + src/overlays/actors/ovl_Fishing/z_fishing.c \ + src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c \ + src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c \ + src/overlays/actors/ovl_Item_Inbox/z_item_inbox.c \ + src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c \ + src/overlays/actors/ovl_Item_Shield/z_item_shield.c \ + src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c \ + src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c \ + src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c \ + src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c \ + src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c \ + src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c \ + src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c \ + src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c \ + src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c \ + src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c \ + src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c \ + src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c \ + src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c \ + src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c \ + src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c \ + src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c \ + src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c \ + src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c \ + src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c \ + src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c \ + src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c \ + src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c \ + src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.c \ + src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c \ + src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c \ + src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c \ + src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c \ + src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c \ + src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c \ + src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c \ + src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c \ + src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c \ + src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c \ + src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c \ + src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c \ + src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c \ + src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c \ + src/overlays/actors/ovl_player_actor/z_player.c \ + src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c \ + src/overlays/effects/ovl_Effect_Ss_Blast/z_eff_ss_blast.c \ + src/overlays/effects/ovl_Effect_Ss_Bomb2/z_eff_ss_bomb2.c \ + src/overlays/effects/ovl_Effect_Ss_Bomb/z_eff_ss_bomb.c \ + src/overlays/effects/ovl_Effect_Ss_Bubble/z_eff_ss_bubble.c \ + src/overlays/effects/ovl_Effect_Ss_Dead_Db/z_eff_ss_dead_db.c \ + src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c \ + src/overlays/effects/ovl_Effect_Ss_Dead_Ds/z_eff_ss_dead_ds.c \ + src/overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.c \ + src/overlays/effects/ovl_Effect_Ss_Dt_Bubble/z_eff_ss_dt_bubble.c \ + src/overlays/effects/ovl_Effect_Ss_Dust/z_eff_ss_dust.c \ + src/overlays/effects/ovl_Effect_Ss_D_Fire/z_eff_ss_d_fire.c \ + src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c \ + src/overlays/effects/ovl_Effect_Ss_En_Ice/z_eff_ss_en_ice.c \ + src/overlays/effects/ovl_Effect_Ss_Extra/z_eff_ss_extra.c \ + src/overlays/effects/ovl_Effect_Ss_Fcircle/z_eff_ss_fcircle.c \ + src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c \ + src/overlays/effects/ovl_Effect_Ss_Fire_Tail/z_eff_ss_fire_tail.c \ + src/overlays/effects/ovl_Effect_Ss_G_Fire/z_eff_ss_g_fire.c \ + src/overlays/effects/ovl_Effect_Ss_G_Magma2/z_eff_ss_g_magma2.c \ + src/overlays/effects/ovl_Effect_Ss_G_Magma/z_eff_ss_g_magma.c \ + src/overlays/effects/ovl_Effect_Ss_G_Ripple/z_eff_ss_g_ripple.c \ + src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c \ + src/overlays/effects/ovl_Effect_Ss_G_Splash/z_eff_ss_g_splash.c \ + src/overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.c \ + src/overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.c \ + src/overlays/effects/ovl_Effect_Ss_Ice_Piece/z_eff_ss_ice_piece.c \ + src/overlays/effects/ovl_Effect_Ss_Ice_Smoke/z_eff_ss_ice_smoke.c \ + src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c \ + src/overlays/effects/ovl_Effect_Ss_KiraKira/z_eff_ss_kirakira.c \ + src/overlays/effects/ovl_Effect_Ss_K_Fire/z_eff_ss_k_fire.c \ + src/overlays/effects/ovl_Effect_Ss_Lightning/z_eff_ss_lightning.c \ + src/overlays/effects/ovl_Effect_Ss_Sibuki2/z_eff_ss_sibuki2.c \ + src/overlays/effects/ovl_Effect_Ss_Sibuki/z_eff_ss_sibuki.c \ + src/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/z_eff_ss_solder_srch_ball.c \ + src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c \ + src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.c \ + src/overlays/gamestates/ovl_file_choose/z_file_choose.c \ + src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c \ + src/overlays/gamestates/ovl_file_choose/z_file_nameset_data.c \ + src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c \ + src/overlays/gamestates/ovl_opening/z_opening.c \ + src/overlays/gamestates/ovl_select/z_select.c \ + src/overlays/gamestates/ovl_title/z_title.c \ + src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c \ + src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c \ + src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c \ + src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c \ + src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c \ + src/overlays/misc/ovl_kaleido_scope/z_kaleido_prompt.c \ + src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c \ + src/overlays/misc/ovl_kaleido_scope/z_lmap_mark.c \ + src/overlays/misc/ovl_kaleido_scope/z_lmap_mark_data.c \ + src/overlays/misc/ovl_map_mark_data/z_map_mark_data.c + +SOURCEFILES_CPP := \ + soh/Enhancements/debugconsole.cpp \ + soh/Enhancements/debugger/debugger.cpp \ + soh/Enhancements/debugger/colViewer.cpp \ + soh/Enhancements/debugger/debugSaveEditor.cpp \ + soh/Enhancements/debugger/ImGuiHelpers.cpp \ + soh/GbiWrap.cpp \ + soh/OTRGlobals.cpp \ + soh/z_message_OTR.cpp \ + soh/z_play_otr.cpp \ + soh/z_scene_otr.cpp \ + soh/savestates.cpp \ + soh/frame_interpolation.cpp \ + soh/util.cpp + +#--------------------------------------------------------------------------------- +# app info +#--------------------------------------------------------------------------------- + +APP_TITLE := Ship of Harkinian +APP_AUTHOR := Harbour Masters +APP_VERSION := Roy-Alfa + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE + +CFLAGS := -O2 -ffunction-sections \ + $(ARCH) $(DEFINES) + +CFLAGS += $(INCLUDE) -D__SWITCH__ \ + -DSPDLOG_NO_THREAD_ID -DSPDLOG_NO_TLS \ + -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) + +LIBS := -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)/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) \ + $(SOH_TOP_DIR)/libultraship/lib/libultraship.a \ + $(SOH_TOP_DIR)/ZAPDTR/ZAPDUtils/lib/libZAPDUtils.a + +$(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 +#--------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/soh/icon.jpg b/soh/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..54f76c81a53acc65c16a157b0ebfda2d9d773480 GIT binary patch literal 81663 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 +#include "SwitchImpl.h" #include @@ -60,6 +61,7 @@ extern "C" int AudioPlayer_GetDesiredBuffered(void); // C->C++ Bridge extern "C" void InitOTR() { + Ship::Switch::Init(); OTRGlobals::Instance = new OTRGlobals(); auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version"); diff --git a/soh/src/boot/assert.c b/soh/src/boot/assert.c index b7895dddd..5a44a9308 100644 --- a/soh/src/boot/assert.c +++ b/soh/src/boot/assert.c @@ -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 \ No newline at end of file diff --git a/soh/src/code/audio_load.c b/soh/src/code/audio_load.c index fee03e9ae..74b1a4bff 100644 --- a/soh/src/code/audio_load.c +++ b/soh/src/code/audio_load.c @@ -50,9 +50,9 @@ s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, uintptr_t devAddr OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType); void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue); AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, uintptr_t devAddr, uintptr_t ramAddr, - ptrdiff_t size, s32 medium, + size_t size, s32 medium, s32 nChunks, OSMesgQueue* retQueue, s32 retMsg); -AudioAsyncLoad* AudioLoad_StartAsyncLoad(u32 devAddr, uintptr_t ramAddr, size_t size, s32 medium, s32 nChunks, +AudioAsyncLoad* AudioLoad_StartAsyncLoad(uintptr_t devAddr, uintptr_t ramAddr, size_t size, s32 medium, s32 nChunks, OSMesgQueue* retQueue, s32 retMsg); void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, size_t size); void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, uintptr_t ramAddr, size_t size, s16 arg3); @@ -1499,8 +1499,8 @@ void AudioLoad_InitAsyncLoads(void) { } } -AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, u32 devAddr, uintptr_t ramAddr, size_t size, - s32 medium, +AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, uintptr_t devAddr, uintptr_t ramAddr, + size_t size, s32 medium, s32 nChunks, OSMesgQueue* retQueue, s32 retMsg) { AudioAsyncLoad* asyncLoad; diff --git a/soh/src/code/fault_drawer.c b/soh/src/code/fault_drawer.c index 9759bfe72..d01887b59 100644 --- a/soh/src/code/fault_drawer.c +++ b/soh/src/code/fault_drawer.c @@ -266,15 +266,17 @@ void* FaultDrawer_FormatStringFunc(void* arg, const char* str, u32 count) { } void FaultDrawer_VPrintf(const char* str, char* args) { // va_list +#ifndef __SWITCH__ _Printf(FaultDrawer_FormatStringFunc, (char*)&sFaultDrawerStruct, str, args); +#endif } void FaultDrawer_Printf(const char* fmt, ...) { va_list args; va_start(args, fmt); - +#ifndef __SWITCH__ FaultDrawer_VPrintf(fmt, args); - +#endif va_end(args); } @@ -283,8 +285,9 @@ void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...) { va_start(args, fmt); FaultDrawer_SetCursor(x, y); +#ifndef __SWITCH__ FaultDrawer_VPrintf(fmt, args); - +#endif va_end(args); }