ref: f9ad22ef4a202c657b97e39c04223cae7622dbb8
parent: 3ff9bf7d5d62220a7c8dbe3067dd613b0df56e78
author: KiritoDev <36680385+KiritoDv@users.noreply.github.com>
date: Sun Oct 2 13:29:41 EDT 2022
Added switch support (#133)
--- a/.gitignore
+++ b/.gitignore
@@ -27,4 +27,4 @@
/tables/zelda3_assets.dat
/third_party/tcc/
/third_party/SDL2-2.24.0/
-/SDL2.dll
+/SDL2.dll
\ No newline at end of file
--- a/config.c
+++ b/config.c
@@ -71,7 +71,7 @@
bool KeyMapHash_Add(uint16 key, uint16 cmd) {
if ((keymap_hash_size & 0xff) == 0) {
- if (keymap_hash_size > 10000)
+ if (keymap_hash_size > 10000)
Die("Too many keys");
keymap_hash = realloc(keymap_hash, sizeof(KeyMapHashEnt) * (keymap_hash_size + 256));
}
@@ -232,7 +232,22 @@
}
}
} else if (section == 1) {
- if (StringEqualsNoCase(key, "EnhancedMode7")) {
+ if (StringEqualsNoCase(key, "WindowSize")) {
+ char *s;
+ if (StringEqualsNoCase(value, "Auto")){
+ g_config.window_width = 0;
+ g_config.window_height = 0;
+ return true;
+ }
+ while ((s = NextDelim(&value, 'x')) != NULL) {
+ if(g_config.window_width == 0) {
+ g_config.window_width = atoi(s);
+ } else {
+ g_config.window_height = atoi(s);
+ return true;
+ }
+ }
+ } else if (StringEqualsNoCase(key, "EnhancedMode7")) {
return ParseBool(value, &g_config.enhanced_mode7);
} else if (StringEqualsNoCase(key, "NewRenderer")) {
return ParseBool(value, &g_config.new_renderer);
--- a/config.h
+++ b/config.h
@@ -35,6 +35,8 @@
};
typedef struct Config {
+ int window_width;
+ int window_height;
bool enhanced_mode7;
bool new_renderer;
bool ignore_aspect_ratio;
--- a/main.c
+++ b/main.c
@@ -98,7 +98,7 @@
g_current_window_scale = new_scale;
int w = new_scale * (g_snes_width / kDefaultWindowScale);
int h = new_scale * (g_snes_height / kDefaultWindowScale);
-
+
//SDL_RenderSetLogicalSize(g_renderer, w, h);
SDL_SetWindowSize(g_window, w, h);
if (bt >= 0) {
@@ -115,7 +115,7 @@
static SDL_HitTestResult HitTestCallback(SDL_Window *win, const SDL_Point *area, void *data) {
uint32 flags = SDL_GetWindowFlags(win);
- return ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == 0 || (flags & SDL_WINDOW_FULLSCREEN) == 0) &&
+ return ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == 0 || (flags & SDL_WINDOW_FULLSCREEN) == 0) &&
(SDL_GetModState() & KMOD_CTRL) != 0 ? SDL_HITTEST_DRAGGABLE : SDL_HITTEST_NORMAL;
}
@@ -197,7 +197,6 @@
LoadAssets();
LoadLinkGraphics();
-
ZeldaInitialize();
g_zenv.ppu->extraLeftRight = UintMin(g_config.extended_aspect_ratio, kPpuExtraLeftRight);
g_snes_width = 2 * (g_config.extended_aspect_ratio * 2 + 256);
@@ -224,11 +223,11 @@
// audio_freq: Use common sampling rates (see user config file. values higher than 48000 are not supported.)
if (g_config.audio_freq < 11025 || g_config.audio_freq > 48000)
g_config.audio_freq = kDefaultFreq;
-
- // Currently, the SPC/DSP implementation �only supports up to stereo.
+
+ // Currently, the SPC/DSP implementation only supports up to stereo.
if (g_config.audio_channels < 1 || g_config.audio_channels > 2)
g_config.audio_channels = kDefaultChannels;
-
+
// audio_samples: power of 2
if (g_config.audio_samples <= 0 || ((g_config.audio_samples & (g_config.audio_samples - 1)) != 0))
g_config.audio_samples = kDefaultSamples;
@@ -239,8 +238,10 @@
return 1;
}
- int window_width = g_current_window_scale * (g_snes_width / kDefaultWindowScale);
- int window_height = g_current_window_scale * (g_snes_height / kDefaultWindowScale);
+ bool custom_size = g_config.window_width != 0 && g_config.window_height != 0;
+ int window_width = custom_size ? g_config.window_width : g_current_window_scale * (g_snes_width / kDefaultWindowScale);
+ int window_height = custom_size ? g_config.window_height : g_current_window_scale * (g_snes_height / kDefaultWindowScale);
+
SDL_Window* window = SDL_CreateWindow(kWindowTitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, g_win_flags);
if(window == NULL) {
printf("Failed to create window: %s\n", SDL_GetError());
@@ -544,7 +545,7 @@
ZeldaReset(true);
break;
case kKeys_Pause: g_paused = !g_paused; break;
- case kKeys_PauseDimmed:
+ case kKeys_PauseDimmed:
g_paused = !g_paused;
if (g_paused) {
SDL_SetRenderDrawBlendMode(g_renderer, SDL_BLENDMODE_BLEND);
@@ -719,4 +720,3 @@
offset += size;
}
}
-
--- /dev/null
+++ b/platform/switch/.gitignore
@@ -1,0 +1,4 @@
+/bin
+/*.nacp
+/*.nro
+/*.elf
\ No newline at end of file
--- /dev/null
+++ b/platform/switch/Makefile
@@ -1,0 +1,218 @@
+#---------------------------------------------------------------------------------
+.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.
+#---------------------------------------------------------------------------------
+SRC_DIR := ../..
+TARGET := $(notdir $(CURDIR))
+BUILD := bin
+SOURCES := $(SRC_DIR) $(SRC_DIR)/snes
+INCLUDES := include
+APP_TITLE := The Legend of Zelda: A Link to the Past
+APP_AUTHOR := snesrev & Lywx
+APP_VERSION := $(shell git rev-parse --short HEAD) $(shell git rev-parse --abbrev-ref HEAD)
+
+#---------------------------------------------------------------------------------
+# 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 += -D__SWITCH__ $(INCLUDE) -DSTBI_NO_THREAD_LOCALS `sdl2-config --cflags`
+
+CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
+CFLAGS += -std=gnu11
+
+ASFLAGS := -g $(ARCH)
+LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
+
+LIBS := `$(PREFIX)pkg-config --libs sdl2` -lnx -lm
+
+#---------------------------------------------------------------------------------
+# 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)/$(TARGET)
+export TOPDIR := $(CURDIR)
+
+export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
+ $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+
+export DEPSDIR := $(CURDIR)/$(BUILD)
+
+CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
+CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
+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
+#---------------------------------------------------------------------------------
+export LD := $(CXX)
+#---------------------------------------------------------------------------------
+
+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)
+
+$(info $(OFILES))
+
+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
+
+#---------------------------------------------------------------------------------
+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)
+
+$(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
binary files /dev/null b/platform/switch/icon.jpg differ
--- /dev/null
+++ b/platform/switch/zelda3.ini
@@ -1,0 +1,126 @@
+[General]
+# Automatically save state on quit and reload on start
+Autosave = 0
+DisplayPerfInTitle = 0
+
+# Extended aspect ratio, either 16:9, 16:10, or 18:9. 4:3 means normal aspect ratio.
+# Add ", unchanged_sprites" to avoid changing sprite spawn/die behavior. Without this
+# replays will be incompatible.
+# Add ", no_visual_fixes" to avoid fixing some graphics glitches (for example with Cape).
+# It won't affect replays/game behavior but the memory compare will not work.
+# Add "extend_y, " right before the aspect radio specifier to display 240 lines instead of 224.
+ExtendedAspectRatio = 16:9
+
+
+[Graphics]
+# Window size ( Auto or WidthxHeight )
+WindowSize = 1280x720
+# Fullscreen mode (0=windowed, 1=desktop fullscreen, 2=fullscreen w/mode change)
+Fullscreen = 0
+# Window scale (1=100%, 2=200%, 3=300%, etc.)
+WindowScale = 1
+NewRenderer = 1
+EnhancedMode7 = 1
+IgnoreAspectRatio = 0
+
+# Enable this option to remove the sprite limits per scan line
+NoSpriteLimits = 1
+
+# Change the appearance of Link by loading a ZSPR file
+# See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/
+# Download the files with "git clone https://github.com/snesrev/sprites-gfx.git"
+# LinkGraphics = sprites-gfx/snes/zelda3/link/sheets/megaman-x.2.zspr
+
+
+[Sound]
+EnableAudio = 1
+
+# DSP frequency in samples per second (e.g. 48000, 44100, 32000, 22050, 11025)
+AudioFreq = 44100
+# number of separate sound channels (1=mono, 2=stereo)
+AudioChannels = 2
+# Audio buffer size in samples (power of 2; e.g., 4096, 2048, 1024) [try 1024 if sound is crackly]. The higher the more lag before you hear sounds.
+AudioSamples = 1024
+
+# Enable MSU support for audio. Files need to be in a subfolder, msu/alttp_msu-*.pcm
+# Only works with 44100 hz and 2 channels
+EnableMSU = 0
+
+
+[Features]
+# Item switch on L/R. Also allows reordering of items in inventory by pressing Y+direction
+# Hold X inside of the item selection screen to reassign the X key into a separate item slot.
+# When X is assigned to an item, the Select key is used to enter the map. Press Select inside
+# of the Start menu to see the old select options.
+ItemSwitchLR = 0
+
+# Allow turning while dashing
+TurnWhileDashing = 0
+
+# Allow mirror to be used to warp to the Dark World
+MirrorToDarkworld = 0
+
+# Collect items (like hearts) with sword instead of having to touch them
+CollectItemsWithSword = 0
+
+# Level 2-4 sword can be used to break pots
+BreakPotsWithSword = 0
+
+# Disable the low health beep
+DisableLowHealthBeep = 0
+
+# Avoid waiting too much at the start
+SkipIntroOnKeypress = 0
+
+# Display max rupees/bombs/arrows with orange/yellow color
+ShowMaxItemsInYellow = 0
+
+# Allows up to four bombs active at a time instead of two.
+MoreActiveBombs = 0
+
+# Can carry 9999 rupees instead of 999
+CarryMoreRupees = 0
+
+# Enable various zelda bug fixes
+MiscBugFixes = 0
+
+# Enable some more advanced zelda bugfixes that change game behavior
+GameChangingBugFixes = 0
+
+# Allow bird travel to be cancelled by hitting the X key
+CancelBirdTravel = 0
+
+
+[KeyMap]
+# Change what keyboard keys map to the joypad
+# Order: Up, Down, Left, Right, Select, Start, A, B, X, Y, L, R
+
+# This default is suitable for QWERTY keyboards.
+Controls = Up, Down, Left, Right, Right Shift, Return, x, z, s, a, c, v
+
+# This default is suitable for QWERTZ keyboards.
+#Controls = Up, Down, Left, Right, Right Shift, Return, x, y, s, a, c, v
+
+# This one is suitable for AZERTY keyboards.
+#Controls = Up, Down, Left, Right, Right Shift, Return, x, w, s, q, c, v
+
+CheatLife = w
+CheatKeys = o
+CheatWalkThroughWalls = Ctrl+e
+ClearKeyLog = k
+StopReplay = l
+Fullscreen = Alt+Return
+Reset = Ctrl+r
+Pause = Shift+p
+PauseDimmed = p
+Turbo = Tab
+ReplayTurbo = t
+WindowBigger = Ctrl+Up
+WindowSmaller = Ctrl+Down
+
+Load = F1, F2, F3, F4, F5, F6, F7, F8, F9, F10
+Save = Shift+F1,Shift+F2,Shift+F3,Shift+F4,Shift+F5,Shift+F6,Shift+F7,Shift+F8,Shift+F9,Shift+F10
+Replay= Ctrl+F1,Ctrl+F2,Ctrl+F3,Ctrl+F4,Ctrl+F5,Ctrl+F6,Ctrl+F7,Ctrl+F8,Ctrl+F9,Ctrl+F10
+
+LoadRef = 1,2,3,4,5,6,7,8,9,0,-,=,Backspace
+ReplayRef = Ctrl+1,Ctrl+2,Ctrl+3,Ctrl+4,Ctrl+5,Ctrl+6,Ctrl+7,Ctrl+8,Ctrl+9,Ctrl+0,Ctrl+-,Ctrl+=,Ctrl+Backspace
--- a/zelda3.ini
+++ b/zelda3.ini
@@ -13,6 +13,8 @@
[Graphics]
+# Window size ( Auto or WidthxHeight )
+WindowSize = Auto
# Fullscreen mode (0=windowed, 1=desktop fullscreen, 2=fullscreen w/mode change)
Fullscreen = 0
# Window scale (1=100%, 2=200%, 3=300%, etc.)