From 173c63cd75e83861b1a89f62383f6653b5d358c0 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Sun, 9 Apr 2023 01:27:03 +0200 Subject: [PATCH] Add Nintendo DS build --- .gitignore | 2 + Makefile.arm9 | 277 ++++++++++++++++++++++++++++++++++++ icon.bmp | Bin 0 -> 1142 bytes include/base_include.h | 88 ++++++++++++ include/nds_functions.h | 15 ++ include/optimized_swi.h | 7 +- include/print_system.h | 3 + include/sprite_handler.h | 3 + include/timing_basic.h | 7 +- include/useful_qualifiers.h | 5 + include/vcount_basic.h | 7 - source/animations_handler.c | 2 +- source/bin_table_handler.c | 2 +- source/communicator.c | 27 +++- source/config_settings.c | 4 +- source/gen12_methods.c | 2 +- source/gen3_clock_events.c | 2 +- source/gen3_save.c | 82 ++++++++--- source/gen_converter.c | 2 +- source/graphics_handler.c | 2 +- source/input_handler.c | 37 ++--- source/main.c | 25 +++- source/menu_text_handler.c | 19 +-- source/multiboot_handler.c | 9 +- source/nds_functions.c | 13 ++ source/options_handler.c | 2 +- source/party_handler.c | 2 +- source/pid_iv_tid.c | 2 +- source/print_system.c | 113 ++++++++++++--- source/rng.c | 2 +- source/save.c | 11 +- source/sio.c | 5 +- source/sio_buffers.c | 2 +- source/sprite_handler.c | 99 +++++++++++-- source/text_handler.c | 2 +- source/version_identifier.c | 13 +- source/window_handler.c | 73 ++++++++-- 37 files changed, 825 insertions(+), 143 deletions(-) create mode 100644 Makefile.arm9 create mode 100644 icon.bmp create mode 100644 include/base_include.h create mode 100644 include/nds_functions.h delete mode 100644 include/vcount_basic.h create mode 100644 source/nds_functions.c diff --git a/.gitignore b/.gitignore index af75ca4..39bbd86 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ build/ *.elf +*.nds +*.NDS *.gba *.GBA *.sav diff --git a/Makefile.arm9 b/Makefile.arm9 new file mode 100644 index 0000000..ea75212 --- /dev/null +++ b/Makefile.arm9 @@ -0,0 +1,277 @@ +# SPDX-License-Identifier: CC0-1.0 +# +# SPDX-FileContributor: Antonio Niño Díaz, 2023 + +BLOCKSDS ?= /opt/blocksds/core +BLOCKSDSEXT ?= /opt/blocksds/external + +# User config +# =========== + +NAME := Pokemon_Gen3_to_GenX + +GAME_TITLE := Pokémon Gen 3 to Gen X +GAME_SUBTITLE := Test NDS Port +GAME_AUTHOR := Lorenzooone +GAME_ICON := icon.bmp + +# DLDI and internal SD slot of DSi +# -------------------------------- + +# Root folder of the SD image +SDROOT := sdroot +# Name of the generated image it "DSi-1.sd" for no$gba in DSi mode +SDIMAGE := image.bin + +# Source code paths +# ----------------- + +SOURCEDIRS := source +INCLUDEDIRS := include +GFXDIRS := graphics +BINDIRS := data +AUDIODIRS := audio +NITROFATDIR := + +# Defines passed to all files +# --------------------------- + +DEFINES := + +# Libraries +# --------- + +LIBS := -lmm9 -lnds9 -lc +LIBDIRS := $(BLOCKSDS)/libs/maxmod \ + $(BLOCKSDS)/libs/libnds + +# Build artifacts +# --------------- + +BUILDDIR := build +ELF := build/$(NAME).elf +DUMP := build/$(NAME).dump +NITROFAT_IMG := build/nitrofat.bin +MAP := build/$(NAME).map +SOUNDBANKDIR := $(BUILDDIR)/maxmod +ROM := $(NAME).nds + +# Tools +# ----- + +PREFIX := arm-none-eabi- +CC := $(PREFIX)gcc +CXX := $(PREFIX)g++ +OBJDUMP := $(PREFIX)objdump +MKDIR := mkdir +RM := rm -rf + +# Verbose flag +# ------------ + +ifeq ($(VERBOSE),1) +V := +else +V := @ +endif + +# Source files +# ------------ + +ifneq ($(BINDIRS),) + SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin") + INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS)) +endif +ifneq ($(GFXDIRS),) + SOURCES_PNG := $(shell find -L $(GFXDIRS) -name "*.png") + INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(GFXDIRS)) +endif +ifneq ($(AUDIODIRS),) + SOURCES_AUDIO := $(shell find -L $(AUDIODIRS) -regex '.*\.\(it\|mod\|s3m\|wav\|xm\)') + ifneq ($(SOURCES_AUDIO),) + INCLUDEDIRS += $(SOUNDBANKDIR) + endif +endif + +SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s") +SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c") +SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") + +# Compiler and linker flags +# ------------------------- + +DEFINES += -D__NDS__ -DARM9 + +ARCH := -march=armv5te -mtune=arm946e-s + +WARNFLAGS := -Wall + +ifeq ($(SOURCES_CPP),) + LD := $(CC) +else + LD := $(CXX) +endif + +INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \ + $(foreach path,$(LIBDIRS),-I$(path)/include) + +LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib) + +ASFLAGS += -x assembler-with-cpp $(DEFINES) $(ARCH) \ + -mthumb -mthumb-interwork $(INCLUDEFLAGS) \ + -ffunction-sections -fdata-sections + +CFLAGS += -std=gnu11 $(WARNFLAGS) $(DEFINES) $(ARCH) \ + -mthumb -mthumb-interwork $(INCLUDEFLAGS) -O2 \ + -Wall -Wstrict-overflow=5 -Wextra\ + -Wpointer-arith -Wpedantic -Wcast-qual -Wswitch-default\ + -Wstrict-prototypes -Wmissing-prototypes\ + -Wshadow -Wwrite-strings \ + -ffunction-sections -fdata-sections \ + -fomit-frame-pointer + +CXXFLAGS += -std=gnu++14 $(WARNFLAGS) $(DEFINES) $(ARCH) \ + -mthumb -mthumb-interwork $(INCLUDEFLAGS) -O2 \ + -ffunction-sections -fdata-sections \ + -fno-exceptions -fno-rtti \ + -fomit-frame-pointer + +LDFLAGS := -mthumb -mthumb-interwork $(LIBDIRSFLAGS) \ + -Wl,-Map,$(MAP) -Wl,--gc-sections -nostdlib \ + -T$(BLOCKSDS)/sys/crts/ds_arm9.mem \ + -T$(BLOCKSDS)/sys/crts/ds_arm9.ld \ + -Wl,--no-warn-rwx-segments \ + -Wl,--start-group $(LIBS) -lgcc -Wl,--end-group + +# Intermediate build files +# ------------------------ + +OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ + $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) + +HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ + $(patsubst %.png,%.h,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) + +ifneq ($(SOURCES_AUDIO),) + OBJS_ASSETS += $(SOUNDBANKDIR)/soundbank.c.o + HEADERS_ASSETS += $(SOUNDBANKDIR)/soundbank.h +endif + +OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \ + $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \ + $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP))) + +OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES) + +DEPS := $(OBJS:.o=.d) + +# Targets +# ------- + +.PHONY: all clean dump dldipatch sdimage + +all: $(ROM) + +ifneq ($(strip $(NITROFATDIR)),) +# Additional arguments for ndstool +NDSTOOL_FAT := -F $(NITROFAT_IMG) + +$(NITROFAT_IMG): $(NITROFATDIR) + @echo " MKFATIMG $@ $(NITROFATDIR)" + $(V)$(BLOCKSDS)/tools/mkfatimg/mkfatimg -t $(NITROFATDIR) $@ 0 + +# Make the NDS ROM depend on the filesystem image only if it is needed +$(ROM): $(NITROFAT_IMG) +endif + +# Combine the title strings +ifeq ($(strip $(GAME_SUBTITLE)),) + GAME_FULL_TITLE := $(GAME_TITLE);$(GAME_AUTHOR) +else + GAME_FULL_TITLE := $(GAME_TITLE);$(GAME_SUBTITLE);$(GAME_AUTHOR) +endif + +$(ROM): $(ELF) + @echo " NDSTOOL $@" + $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ + -7 $(BLOCKSDS)/sys/default_arm7/arm7.elf -9 $(ELF) \ + -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ + $(NDSTOOL_FAT) + +$(ELF): $(OBJS) + @echo " LD $@" + $(V)$(LD) -o $@ $(OBJS) $(BLOCKSDS)/sys/crts/ds_arm9_crt0.o $(LDFLAGS) + +$(DUMP): $(ELF) + @echo " OBJDUMP $@" + $(V)$(OBJDUMP) -h -C -S $< > $@ + +dump: $(DUMP) + +clean: + @echo " CLEAN" + $(V)$(RM) $(ROM) $(DUMP) $(BUILDDIR) $(SDIMAGE) + +sdimage: + @echo " MKFATIMG $(SDIMAGE) $(SDROOT)" + $(V)$(BLOCKSDS)/tools/mkfatimg/mkfatimg -t $(SDROOT) $(SDIMAGE) 0 + +dldipatch: $(ROM) + @echo " DLDITOOL $(ROM)" + $(V)$(BLOCKSDS)/tools/dlditool/dlditool \ + $(BLOCKSDS)/tools/dldi/r4tfv2.dldi $(ROM) + +# Rules +# ----- + +$(BUILDDIR)/%.s.o : %.s + @echo " AS $<" + @$(MKDIR) -p $(@D) + $(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $< + +$(BUILDDIR)/%.c.o : %.c + @echo " CC $<" + @$(MKDIR) -p $(@D) + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $< + +$(BUILDDIR)/%.cpp.o : %.cpp + @echo " CXX $<" + @$(MKDIR) -p $(@D) + $(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $< + +$(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin + @echo " BIN2C $<" + @$(MKDIR) -p $(@D) + $(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D) + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c + +$(BUILDDIR)/%.png.o $(BUILDDIR)/%.h : %.png %.grit + @echo " GRIT $<" + @$(MKDIR) -p $(@D) + $(V)$(BLOCKSDS)/tools/grit/grit $< -ftc -W1 -o$(BUILDDIR)/$* + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.c + $(V)touch $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.h + +$(SOUNDBANKDIR)/soundbank.h: $(SOURCES_AUDIO) + @echo " MMUTIL $^" + @$(MKDIR) -p $(@D) + @$(BLOCKSDS)/tools/mmutil/mmutil $^ -d \ + -o$(SOUNDBANKDIR)/soundbank.bin -h$(SOUNDBANKDIR)/soundbank.h + +$(SOUNDBANKDIR)/soundbank.c.o: $(SOUNDBANKDIR)/soundbank.h + @echo " BIN2C soundbank.bin" + $(V)$(BLOCKSDS)/tools/bin2c/bin2c $(SOUNDBANKDIR)/soundbank.bin \ + $(SOUNDBANKDIR) + @echo " CC.9 soundbank_bin.c" + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(SOUNDBANKDIR)/soundbank.c.o \ + $(SOUNDBANKDIR)/soundbank_bin.c + +# All assets must be built before the source code +# ----------------------------------------------- + +$(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS) + +# Include dependency files if they exist +# -------------------------------------- + +-include $(DEPS) diff --git a/icon.bmp b/icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c5a571c41273844de1d8b28c22c88b1e1ca67591 GIT binary patch literal 1142 zcma)4yH3O~5Zv21i9c@Psc9MtAyCK{5%O{od0w(}t}J>r@$G`HU2?Wga zs4ex2)E@$b*9@k|1bo^cGMoyJ`mukRa8VRhRn>A#g_r&W6TP-Md>}y2u|LrtK_2oD zIILi`g44kMAYl-fCnoovz1PAn@yWkq`4c~MW`h*|5C1Kc)A5LY=D!&g{k01M-d5#& za1Qbe_rv_RRpAfy=Kq3T{U7zQzcIi0Z_DHUM*olSX@l5;-VaSM(U1PufARAJw(67n MlNJvC@P85E2SFHJ6aWAK literal 0 HcmV?d00001 diff --git a/include/base_include.h b/include/base_include.h new file mode 100644 index 0000000..1924916 --- /dev/null +++ b/include/base_include.h @@ -0,0 +1,88 @@ +#ifndef BASE_INCLUDE__ +#define BASE_INCLUDE__ + +#ifndef __NDS__ + +// GBA defines and all +#include +#include "useful_qualifiers.h" +#define ROM 0x8000000 +ALWAYS_INLINE MAX_OPTIMIZE void __set_next_vcount_interrupt_gba(int scanline) { + REG_DISPSTAT = (REG_DISPSTAT &0xFF) | (scanline<<8); +} +ALWAYS_INLINE MAX_OPTIMIZE int __get_next_vcount_interrupt(void) { + return REG_DISPSTAT >> 8; +} +#define __set_next_vcount_interrupt(x) __set_next_vcount_interrupt_gba(x) +#define SCANLINE_IRQ_BIT LCDC_VCNT +#define REG_WAITCNT *(vu16*)(REG_BASE + 0x204) // Wait state Control +#define SRAM_READING_VALID_WAITCYCLES 3 +#define NON_SRAM_MASK 0xFFFC +#define BASE_WAITCNT_VAL 0x4314 +#define TIMEOUT_INCREASE 0 +#define OVRAM_START ((uintptr_t)OBJ_BASE_ADR) +#define TILE_1D_MAP 0 +#define ACTIVATE_SCREEN_HW 0 +#define EWRAM_SIZE 0x0003FF40 +#define DIV_SWI_VAL "0x06" +#define VRAM_0 VRAM +#define HAS_SIO +#define CLOCK_SPEED 16777216 +#define SCANLINES 0xE4 +#define SAME_ON_BOTH_SCREENS 0 +#ifndef __GBA__ +#define __GBA__ +#endif +#define CONSOLE_LETTER 'G' + +#else + +// NDS defines and all +#include +#include "useful_qualifiers.h" +#include "nds_functions.h" +#define ROM GBAROM +ALWAYS_INLINE MAX_OPTIMIZE int __get_next_vcount_interrupt(void) { + return (REG_DISPSTAT >> 8) | ((REG_DISPSTAT & 0x80) << 1); +} +#define __set_next_vcount_interrupt(x) SetYtrigger(x) +#define SCANLINE_IRQ_BIT DISP_YTRIGGER_IRQ +#define REG_WAITCNT REG_EXMEMCNT // Wait state Control +#define SRAM_READING_VALID_WAITCYCLES 3 +#define NON_SRAM_MASK 0xFFFC +#define EXMEMCNT_MASK_SLOT2_CLOCKRATE (3<<5) +#define EXMEMCNT_SLOT2_CLOCKRATE_1 (1<<5) +#define BASE_WAITCNT_VAL EXMEMCNT_SLOT2_CLOCKRATE_1 +#define TIMEOUT_INCREASE 2 +#define OVRAM_START ((uintptr_t)SPRITE_GFX) +#define OVRAM_START_SUB ((uintptr_t)SPRITE_GFX_SUB) +#define OBJ_ON DISPLAY_SPR_ACTIVE +#define OBJ_1D_MAP (1<<6) +#define TILE_1D_MAP (1<<4) +#define ACTIVATE_SCREEN_HW (1<<16) +#define EWRAM 0x2000000 +#define EWRAM_SIZE 0x00400000 +#define VRAM_0_SUB BG_GFX_SUB +#define ARM9_CLOCK_SPEED 67108864 +#define ARM7_CLOCK_SPEED 33554432 +#define ARM7_GBA_CLOCK_SPEED 16777216 +#define CLOCK_SPEED ARM9_CLOCK_SPEED +#define SCANLINES 0x107 +#define SAME_ON_BOTH_SCREENS 1 +#define CONSOLE_LETTER 'D' + +// Define SWIs back +#define Div(x, y) swiDivide(x, y) +#define DivMod(x, y) swiRemainder(x, y) +#define Sqrt(x) swiSqrt(x) +#define LZ77UnCompWram(x, y) swiDecompressLZSSWram(x, y) +#define CpuFastSet(x, y, z) swiFastCopy(x, y, z) +#define VBlankIntrWait() swiWaitForVBlank() +#define Halt() Halt_ARM9() +#define DIV_SWI_VAL "0x09" + +#endif + +#define VBLANK_SCANLINES SCREEN_HEIGHT + +#endif diff --git a/include/nds_functions.h b/include/nds_functions.h new file mode 100644 index 0000000..a07cb4c --- /dev/null +++ b/include/nds_functions.h @@ -0,0 +1,15 @@ +#ifndef NDS_FUNCTIONS__ +#define NDS_FUNCTIONS__ + +#ifdef __NDS__ +typedef struct { + u16 attr0; + u16 attr1; + u16 attr2; + u16 dummy; +} ALIGN(4) OBJATTR; + +void Halt_ARM9(void); +#endif + +#endif diff --git a/include/optimized_swi.h b/include/optimized_swi.h index e97fda3..93d4e61 100644 --- a/include/optimized_swi.h +++ b/include/optimized_swi.h @@ -1,6 +1,7 @@ #ifndef OPTIMIZED_SWI__ #define OPTIMIZED_SWI__ +#include "base_include.h" #include "useful_qualifiers.h" static s32 SWI_DivMod(const uint32_t, const uint32_t); @@ -14,7 +15,7 @@ ALWAYS_INLINE MAX_OPTIMIZE s32 SWI_DivMod(const uint32_t dividend, const uint32_ register uint32_t abs_divis_ asm("r3"); asm volatile( - "swi 0x06;" : "=r"(divid_), "=r"(divis_), "=r"(abs_divis_) : + "swi "DIV_SWI_VAL";" : "=r"(divid_), "=r"(divis_), "=r"(abs_divis_) : "r"(divid_), "r"(divis_), "r"(abs_divis_) : ); @@ -28,7 +29,7 @@ ALWAYS_INLINE MAX_OPTIMIZE s32 SWI_Div(const uint32_t dividend, const uint32_t d register uint32_t abs_divis_ asm("r3"); asm volatile( - "swi 0x06;" : "=r"(divid_), "=r"(divis_), "=r"(abs_divis_) : + "swi "DIV_SWI_VAL";" : "=r"(divid_), "=r"(divis_), "=r"(abs_divis_) : "r"(divid_), "r"(divis_), "r"(abs_divis_) : ); @@ -42,7 +43,7 @@ ALWAYS_INLINE MAX_OPTIMIZE s32 SWI_DivDivMod(const uint32_t dividend, const uint register uint32_t abs_divis_ asm("r3"); asm volatile( - "swi 0x06;" : "=r"(divid_), "=r"(divis_), "=r"(abs_divis_) : + "swi "DIV_SWI_VAL";" : "=r"(divid_), "=r"(divis_), "=r"(abs_divis_) : "r"(divid_), "r"(divis_), "r"(abs_divis_) : ); diff --git a/include/print_system.h b/include/print_system.h index 6bda312..662aeb7 100644 --- a/include/print_system.h +++ b/include/print_system.h @@ -46,6 +46,9 @@ void swap_buffer_screen(u8, u8); void disable_all_screens_but_current(void); void set_bg_pos(u8, int, int); screen_t* get_screen(u8 bg_num); +#ifdef __NDS__ +screen_t* get_screen_sub(u8 bg_num); +#endif u8 get_screen_num(void); void set_screen(u8); void init_text_system(void); diff --git a/include/sprite_handler.h b/include/sprite_handler.h index 7133c68..7914ddc 100644 --- a/include/sprite_handler.h +++ b/include/sprite_handler.h @@ -49,10 +49,12 @@ #define BASE_X_CURSOR_MAIN_MENU 2 #define BASE_Y_CURSOR_MAIN_MENU 8 #define BASE_Y_CURSOR_INCREMENT_MAIN_MENU 16 +#define BOTTOM_Y_CURSOR_MAIN_MENU_VALUE ((((Y_LIMIT-1)<<3)-BASE_Y_CURSOR_MAIN_MENU)/BASE_Y_CURSOR_INCREMENT_MAIN_MENU) #define BASE_X_CURSOR_BASE_SETTINGS_MENU 2 #define BASE_Y_CURSOR_BASE_SETTINGS_MENU 8 #define BASE_Y_CURSOR_INCREMENT_BASE_SETTINGS_MENU 16 +#define BOTTOM_Y_CURSOR_BASE_SETTINGS_MENU_VALUE ((((Y_LIMIT-3)<<3)-BASE_Y_CURSOR_BASE_SETTINGS_MENU)/BASE_Y_CURSOR_INCREMENT_BASE_SETTINGS_MENU) #define BASE_X_CURSOR_GEN12_SETTINGS_MENU 2 #define BASE_Y_CURSOR_GEN12_SETTINGS_MENU 8 @@ -65,6 +67,7 @@ #define BASE_X_CURSOR_CLOCK_SETTINGS_MENU 2 #define BASE_Y_CURSOR_CLOCK_SETTINGS_MENU 8 #define BASE_Y_CURSOR_INCREMENT_CLOCK_SETTINGS_MENU 8 +#define BOTTOM_Y_CURSOR_CLOCK_SETTINGS_MENU_VALUE ((((Y_LIMIT-8)<<3)-BASE_Y_CURSOR_CLOCK_SETTINGS_MENU)/BASE_Y_CURSOR_INCREMENT_CLOCK_SETTINGS_MENU) #define BASE_X_CURSOR_CLOCK_WARNING 2 #define BASE_Y_CURSOR_CLOCK_WARNING 64 diff --git a/include/timing_basic.h b/include/timing_basic.h index a175319..31a9f19 100644 --- a/include/timing_basic.h +++ b/include/timing_basic.h @@ -2,11 +2,10 @@ #define TIMING_BASIC__ #define FPS 60 -#define CLOCK_SPEED 16777216 #define NS_PER_SECOND 1000000000 -#define NS_PER_CYCLE ((NS_PER_SECOND/CLOCK_SPEED)+((NS_PER_SECOND%CLOCK_SPEED) == 0 ? 0 : 1)) -#define CYCLES_PER_SCANLINE 1232 -#define NS_PER_SCANLINE (CYCLES_PER_SCANLINE*NS_PER_CYCLE) +#define NS_PER_CYCLE ((NS_PER_SECOND + CLOCK_SPEED - 1)/CLOCK_SPEED) +#define NS_PER_SCANLINE ((NS_PER_SECOND + (FPS*SCANLINES) - 1)/(FPS*SCANLINES)) +#define CYCLES_PER_SCANLINE ((NS_PER_SCANLINE + NS_PER_CYCLE - 1)/NS_PER_CYCLE) #define GBA_CLOCK_SPEED 16777216 diff --git a/include/useful_qualifiers.h b/include/useful_qualifiers.h index c881bef..6db9e2f 100644 --- a/include/useful_qualifiers.h +++ b/include/useful_qualifiers.h @@ -4,7 +4,12 @@ #define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) #define ALWAYS_INLINE __attribute__((always_inline)) static inline #define MAX_OPTIMIZE __attribute__((optimize(3))) +#ifndef PACKED #define PACKED __attribute__((packed)) +#endif +#ifndef IWRAM_CODE +#define IWRAM_CODE +#endif #define ARM_TARGET __attribute__((target("arm"),noinline)) #define ALIGNED(x) __attribute__((aligned(x))) diff --git a/include/vcount_basic.h b/include/vcount_basic.h deleted file mode 100644 index e6fb72c..0000000 --- a/include/vcount_basic.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef VCOUNT_BASIC__ -#define VCOUNT_BASIC__ - -#define SCANLINES 0xE4 -#define VBLANK_SCANLINES SCREEN_HEIGHT - -#endif diff --git a/source/animations_handler.c b/source/animations_handler.c index abc30af..56b42ee 100644 --- a/source/animations_handler.c +++ b/source/animations_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "party_handler.h" #include "sprite_handler.h" #include "animations_handler.h" diff --git a/source/bin_table_handler.c b/source/bin_table_handler.c index b54485b..74f9387 100644 --- a/source/bin_table_handler.c +++ b/source/bin_table_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "bin_table_handler.h" #include diff --git a/source/communicator.c b/source/communicator.c index 411628b..05e3815 100644 --- a/source/communicator.c +++ b/source/communicator.c @@ -1,8 +1,7 @@ -#include +#include "base_include.h" #include "communicator.h" #include "sio.h" #include "sio_buffers.h" -#include "vcount_basic.h" #include "party_handler.h" #include "useful_qualifiers.h" #include @@ -347,7 +346,7 @@ MAX_OPTIMIZE void set_next_vcount_interrupt(void){ int next_stop = REG_VCOUNT + VCOUNT_WAIT_LINES; if(next_stop >= SCANLINES) next_stop -= SCANLINES; - REG_DISPSTAT = (REG_DISPSTAT &0xFF) | (next_stop<<8); + __set_next_vcount_interrupt(next_stop); } IWRAM_CODE int communicate_buffer(u8 data, u8 is_master) { @@ -811,6 +810,7 @@ IWRAM_CODE void process_in_data_gen3(u32 data) { } IWRAM_CODE MAX_OPTIMIZE void slave_routine(void) { + #ifdef HAS_SIO if(!(REG_IF & IRQ_SERIAL)){ REG_IF |= IRQ_SERIAL; int value; @@ -830,10 +830,12 @@ IWRAM_CODE MAX_OPTIMIZE void slave_routine(void) { //PRINT_FUNCTION("0x\x0D - 0x\x0D\n", value, 2, data, 2); //sio_handle_irq_slave(process_data_arrived_gen12(sio_read(SIO_8), 0)); } + #endif } IWRAM_CODE MAX_OPTIMIZE void master_routine_gen3(void) { REG_IF |= IRQ_VCOUNT; + #ifdef HAS_SIO int data; u8 success = 0; @@ -845,11 +847,13 @@ IWRAM_CODE MAX_OPTIMIZE void master_routine_gen3(void) { prepared_value = prepare_out_data_gen3(); } + #endif set_next_vcount_interrupt(); } IWRAM_CODE MAX_OPTIMIZE void master_routine_gen12(void) { REG_IF |= IRQ_VCOUNT; + #ifdef HAS_SIO int data; if(!skip_sends) { @@ -870,6 +874,7 @@ IWRAM_CODE MAX_OPTIMIZE void master_routine_gen12(void) { else skip_sends--; + #endif set_next_vcount_interrupt(); } @@ -891,48 +896,58 @@ void start_transfer(u8 is_master, u8 curr_gen) stored_curr_gen = curr_gen; if(curr_gen != 3) { if(!is_master) { + #ifdef HAS_SIO init_sio_normal(SIO_SLAVE, SIO_8); irqSet(IRQ_SERIAL, slave_routine); irqEnable(IRQ_SERIAL); sio_normal_prepare_irq_slave(SEND_NO_INFO); + #endif } else{ set_next_vcount_interrupt(); + #ifdef HAS_SIO init_sio_normal(SIO_MASTER, SIO_8); + #endif irqSet(IRQ_VCOUNT, master_routine_gen12); prepared_value = ENTER_TRADE_MASTER; irqEnable(IRQ_VCOUNT); - REG_DISPSTAT |= LCDC_VCNT; + REG_DISPSTAT |= SCANLINE_IRQ_BIT; } } else { init_received_gen3(); set_start_state(START_TRADE_PAR); if(!is_master) { + #ifdef HAS_SIO init_sio_normal(SIO_SLAVE, SIO_32); irqSet(IRQ_SERIAL, slave_routine); irqEnable(IRQ_SERIAL); sio_normal_prepare_irq_slave(SEND_0_INFO); + #endif } else { set_next_vcount_interrupt(); + #ifdef HAS_SIO init_sio_normal(SIO_MASTER, SIO_32); + #endif irqSet(IRQ_VCOUNT, master_routine_gen3); prepared_value = SEND_0_INFO; irqEnable(IRQ_VCOUNT); - REG_DISPSTAT |= LCDC_VCNT; + REG_DISPSTAT |= SCANLINE_IRQ_BIT; } } } void base_stop_transfer(u8 is_master) { if(!is_master) { + #ifdef HAS_SIO irqDisable(IRQ_SERIAL); sio_stop_irq_slave(); + #endif } else{ irqDisable(IRQ_VCOUNT); - REG_DISPSTAT &= ~LCDC_VCNT; + REG_DISPSTAT &= ~SCANLINE_IRQ_BIT; } } diff --git a/source/config_settings.c b/source/config_settings.c index c336bae..0cf32fe 100644 --- a/source/config_settings.c +++ b/source/config_settings.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "config_settings.h" #include "version_identifier.h" #include "party_handler.h" @@ -39,7 +39,7 @@ static u16 applied_ball; static u8 egg_met_location; static u8 first_set_egg_met_location; -const struct version_t version = { .main_version = 1, .sub_version = 1, .revision_version = 0, .revision_letter = ' '}; +const struct version_t version = { .main_version = 1, .sub_version = 1, .revision_version = 0, .revision_letter = CONSOLE_LETTER}; const u8* egg_valid_met_locations[NUMBER_OF_GAMES+FIRST_VERSION_ID] = {valid_egg_locations_rs_bin, valid_egg_locations_rs_bin, valid_egg_locations_rs_bin, valid_egg_locations_e_bin, valid_egg_locations_frlg_bin, valid_egg_locations_frlg_bin}; void set_default_settings() { diff --git a/source/gen12_methods.c b/source/gen12_methods.c index 883ed3d..7d0cf7b 100644 --- a/source/gen12_methods.c +++ b/source/gen12_methods.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "gen12_methods.h" #include "party_handler.h" #include "text_handler.h" diff --git a/source/gen3_clock_events.c b/source/gen3_clock_events.c index f46cf0f..65348ff 100644 --- a/source/gen3_clock_events.c +++ b/source/gen3_clock_events.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "gen3_clock_events_t.h" #include "gen3_save.h" #include "party_handler.h" diff --git a/source/gen3_save.c b/source/gen3_save.c index 81aa98b..a2a7287 100644 --- a/source/gen3_save.c +++ b/source/gen3_save.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "save.h" #include "gen3_save.h" #include "gen3_clock_events.h" @@ -77,6 +77,8 @@ static u8 get_next_slot(u8); void replace_party_entry(struct game_data_t*, struct gen3_mon_data_unenc*, u8); void trade_reorder_party_entries(struct game_data_t*, struct gen3_mon_data_unenc*, u8); u32 calc_checksum_save_buffer(u32*, u16); +static void start_gen3_save_data_transfer(void); +static void end_gen3_save_data_transfer(void); const u16 summable_bytes[SECTION_TOTAL] = {3884, MAX_SECTION_SIZE, MAX_SECTION_SIZE, MAX_SECTION_SIZE, 3848, MAX_SECTION_SIZE, MAX_SECTION_SIZE, MAX_SECTION_SIZE, MAX_SECTION_SIZE, MAX_SECTION_SIZE, MAX_SECTION_SIZE, MAX_SECTION_SIZE, MAX_SECTION_SIZE, 2000}; const u16 summable_bytes_section0[NUM_MAIN_GAME_ID] = {0x890, 0xF24, 0xF2C}; @@ -807,48 +809,76 @@ IWRAM_CODE u8 has_cartridge_been_removed(){ return retval; } +ALWAYS_INLINE void start_gen3_save_data_transfer() { + #ifdef __NDS__ + disableSleep(); + #endif +} + +ALWAYS_INLINE void end_gen3_save_data_transfer() { + #ifdef __NDS__ + enableSleep(); + #endif +} + u8 read_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv){ unload_cartridge(); + start_gen3_save_data_transfer(); init_bank(); - + game_data_priv->game_is_suspended = 0; - + u8 slot = get_slot(&game_data->game_identifier); in_use_slot = slot; - if(slot == INVALID_SLOT) + if(slot == INVALID_SLOT) { + end_gen3_save_data_transfer(); return 0; - + } + read_party(slot, game_data, game_data_priv); own_game_data_ptr = game_data; - - if(game_data_priv->game_is_suspended) + + if(game_data_priv->game_is_suspended) { + end_gen3_save_data_transfer(); return 0; - + } + + end_gen3_save_data_transfer(); load_cartridge(); - + return 1; } u8 pre_write_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 is_full){ unload_cartridge(); + start_gen3_save_data_transfer(); init_bank(); u8 base_slot = in_use_slot; - if(base_slot == INVALID_SLOT) + if(base_slot == INVALID_SLOT) { + end_gen3_save_data_transfer(); return 0; + } if(is_full) { - if(!pre_update_save(game_data, game_data_priv, base_slot, FULL_SAVE)) + if(!pre_update_save(game_data, game_data_priv, base_slot, FULL_SAVE)) { + end_gen3_save_data_transfer(); return 0; + } - if(!validate_slot(get_next_slot(base_slot), &game_data->game_identifier)) + if(!validate_slot(get_next_slot(base_slot), &game_data->game_identifier)) { + end_gen3_save_data_transfer(); return 0; + } } else { - if(!pre_update_save(game_data, game_data_priv, base_slot, NON_PARTY_SAVE)) + if(!pre_update_save(game_data, game_data_priv, base_slot, NON_PARTY_SAVE)) { + end_gen3_save_data_transfer(); return 0; + } } + end_gen3_save_data_transfer(); load_cartridge(); return 1; @@ -856,18 +886,26 @@ u8 pre_write_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* u8 pre_write_updated_moves_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv){ unload_cartridge(); + start_gen3_save_data_transfer(); init_bank(); u8 base_slot = in_use_slot; - if(base_slot == INVALID_SLOT) + if(base_slot == INVALID_SLOT) { + end_gen3_save_data_transfer(); return 0; + } - if(!pre_update_save(game_data, game_data_priv, base_slot, PARTY_ONLY_SAVE)) + if(!pre_update_save(game_data, game_data_priv, base_slot, PARTY_ONLY_SAVE)) { + end_gen3_save_data_transfer(); return 0; + } - if(!validate_slot(get_next_slot(base_slot), &game_data->game_identifier)) + if(!validate_slot(get_next_slot(base_slot), &game_data->game_identifier)) { + end_gen3_save_data_transfer(); return 0; + } + end_gen3_save_data_transfer(); load_cartridge(); return 1; @@ -875,17 +913,23 @@ u8 pre_write_updated_moves_gen_3_data(struct game_data_t* game_data, struct game u8 complete_write_gen_3_data(struct game_data_t* game_data){ unload_cartridge(); + start_gen3_save_data_transfer(); init_bank(); u8 base_slot = in_use_slot; - if(base_slot == INVALID_SLOT) + if(base_slot == INVALID_SLOT) { + end_gen3_save_data_transfer(); return 0; + } - if(!complete_save(base_slot, game_data)) + if(!complete_save(base_slot, game_data)) { + end_gen3_save_data_transfer(); return 0; - + } + in_use_slot = get_next_slot(in_use_slot); + end_gen3_save_data_transfer(); load_cartridge(); return 1; diff --git a/source/gen_converter.c b/source/gen_converter.c index 41de205..8f030e4 100644 --- a/source/gen_converter.c +++ b/source/gen_converter.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "party_handler.h" #include "gen12_methods.h" #include "gen_converter.h" diff --git a/source/graphics_handler.c b/source/graphics_handler.c index c79d39d..d79c51f 100644 --- a/source/graphics_handler.c +++ b/source/graphics_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "graphics_handler.h" #include "useful_qualifiers.h" #include "print_system.h" diff --git a/source/input_handler.c b/source/input_handler.c index a1e17d6..4ad06e0 100644 --- a/source/input_handler.c +++ b/source/input_handler.c @@ -1,5 +1,6 @@ -#include +#include "base_include.h" #include "input_handler.h" +#include "sprite_handler.h" #include "options_handler.h" #include "communicator.h" #include "gen3_clock_events.h" @@ -256,7 +257,7 @@ u8 handle_input_main_menu(u8* cursor_y_pos, u16 keys, u8* update, u8* target, u8 (*cursor_y_pos) += 1; } else if(keys & KEY_UP) { - (*cursor_y_pos) = 9; + (*cursor_y_pos) = BOTTOM_Y_CURSOR_MAIN_MENU_VALUE; } break; case 1: @@ -323,15 +324,15 @@ u8 handle_input_main_menu(u8* cursor_y_pos, u16 keys, u8* update, u8* target, u8 if(keys & KEY_A) return START_MULTIBOOT; else if((keys & KEY_DOWN) && (PRINT_INFO_ALWAYS || (!get_is_cartridge_loaded())) && ENABLED_PRINT_INFO) - (*cursor_y_pos) = 6; + (*cursor_y_pos) = (BOTTOM_Y_CURSOR_MAIN_MENU_VALUE - 3); else if(keys & KEY_DOWN) - (*cursor_y_pos) = 7; + (*cursor_y_pos) = (BOTTOM_Y_CURSOR_MAIN_MENU_VALUE - 2); else if((keys & KEY_UP) && get_valid_options_main()) (*cursor_y_pos) -= 1; else if(keys & KEY_UP) - (*cursor_y_pos) = 9; + (*cursor_y_pos) = BOTTOM_Y_CURSOR_MAIN_MENU_VALUE; break; - case 6: + case (BOTTOM_Y_CURSOR_MAIN_MENU_VALUE - 3): if(keys & KEY_A) return START_PRINT_READ_INFO; else if(keys & KEY_DOWN) @@ -339,19 +340,19 @@ u8 handle_input_main_menu(u8* cursor_y_pos, u16 keys, u8* update, u8* target, u8 else if(keys & KEY_UP) (*cursor_y_pos) = 4; break; - case 7: + case (BOTTOM_Y_CURSOR_MAIN_MENU_VALUE - 2): if(keys & KEY_A) return START_SWAP_CARTRIDGE; else if((keys & KEY_DOWN) && get_valid_options_main()) (*cursor_y_pos) += 1; else if(keys & KEY_DOWN) - (*cursor_y_pos) = 9; + (*cursor_y_pos) = BOTTOM_Y_CURSOR_MAIN_MENU_VALUE; else if((keys & KEY_UP) && (PRINT_INFO_ALWAYS || (!get_is_cartridge_loaded())) && ENABLED_PRINT_INFO) (*cursor_y_pos) -= 1; else if(keys & KEY_UP) (*cursor_y_pos) = 4; break; - case 8: + case (BOTTOM_Y_CURSOR_MAIN_MENU_VALUE - 1): if(keys & KEY_A) return VIEW_OWN_PARTY + curr_gen; else if(keys & KEY_DOWN) @@ -359,7 +360,7 @@ u8 handle_input_main_menu(u8* cursor_y_pos, u16 keys, u8* update, u8* target, u8 else if(keys & KEY_UP) (*cursor_y_pos) -= 1; break; - case 9: + case BOTTOM_Y_CURSOR_MAIN_MENU_VALUE: if(keys & KEY_A) return START_SETTINGS_MENU; else if((keys & KEY_DOWN) && get_valid_options_main()) @@ -369,7 +370,7 @@ u8 handle_input_main_menu(u8* cursor_y_pos, u16 keys, u8* update, u8* target, u8 else if((keys & KEY_UP) && get_valid_options_main()) (*cursor_y_pos) -= 1; else if(keys & KEY_UP) - (*cursor_y_pos) = 7; + (*cursor_y_pos) = (BOTTOM_Y_CURSOR_MAIN_MENU_VALUE - 2); break; default: break; @@ -597,7 +598,7 @@ u8 handle_input_base_settings_menu(u16 keys, u8* cursor_y_pos, u8* update, struc switch(*cursor_y_pos) { case 0: if(keys & KEY_UP) - *cursor_y_pos = 8; + *cursor_y_pos = BOTTOM_Y_CURSOR_BASE_SETTINGS_MENU_VALUE; else if(keys & KEY_DOWN) *cursor_y_pos += 1; else if((keys & KEY_RIGHT) || (keys & KEY_A)) { @@ -661,9 +662,9 @@ u8 handle_input_base_settings_menu(u16 keys, u8* cursor_y_pos, u8* update, struc *cursor_y_pos -= 3; } else if(keys & KEY_DOWN) - *cursor_y_pos = 8; + *cursor_y_pos = BOTTOM_Y_CURSOR_BASE_SETTINGS_MENU_VALUE; break; - case 8: + case BOTTOM_Y_CURSOR_BASE_SETTINGS_MENU_VALUE: if(keys & KEY_A) return ENTER_CHEATS_MENU; else if(keys & KEY_UP) @@ -747,7 +748,7 @@ u8 handle_input_clock_menu(u16 keys, struct clock_events_t* clock_events, struct switch(*cursor_y_pos) { case 0: if(keys & KEY_UP) - *cursor_y_pos = 11; + *cursor_y_pos = BOTTOM_Y_CURSOR_CLOCK_SETTINGS_MENU_VALUE; else if(keys & KEY_DOWN) *cursor_y_pos += 2; else if((keys & KEY_RIGHT) || (keys & KEY_A) || (keys & KEY_LEFT)) { @@ -836,7 +837,7 @@ u8 handle_input_clock_menu(u16 keys, struct clock_events_t* clock_events, struct if(keys & KEY_UP) *cursor_y_pos -= 1; else if(keys & KEY_DOWN) - *cursor_y_pos += 2; + *cursor_y_pos = BOTTOM_Y_CURSOR_CLOCK_SETTINGS_MENU_VALUE; else if((keys & KEY_RIGHT) || (keys & KEY_A)) { if(time_change->s < MAX_SECONDS-1) time_change->s += 1; @@ -852,11 +853,11 @@ u8 handle_input_clock_menu(u16 keys, struct clock_events_t* clock_events, struct *update = 1; } break; - case 11: + case BOTTOM_Y_CURSOR_CLOCK_SETTINGS_MENU_VALUE: if(keys & KEY_A) return 1; else if(keys & KEY_UP) - *cursor_y_pos -= 2; + *cursor_y_pos = 9; else if(keys & KEY_DOWN) *cursor_y_pos = 0; break; diff --git a/source/main.c b/source/main.c index c190af8..480e890 100644 --- a/source/main.c +++ b/source/main.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "multiboot_handler.h" #include "graphics_handler.h" #include "party_handler.h" @@ -18,7 +18,6 @@ #include "communicator.h" #include "gen_converter.h" #include "sio.h" -#include "vcount_basic.h" #include "animations_handler.h" #include #include "optimized_swi.h" @@ -130,6 +129,7 @@ IWRAM_CODE void vblank_update_function() { // Handle trading animation if(curr_state == TRADING_ANIMATION) advance_trade_animation(); + #ifdef HAS_SIO // Handle slave communications if((REG_SIOCNT & SIO_IRQ) && (!(REG_SIOCNT & SIO_START))) slave_routine(); @@ -140,12 +140,13 @@ IWRAM_CODE void vblank_update_function() { REG_IF &= ~IRQ_SERIAL; slave_routine(); } + #endif // Handle master communications - if(REG_DISPSTAT & LCDC_VCNT) { - u16 next_vcount_irq = (REG_DISPSTAT >> 8); + if(REG_DISPSTAT & SCANLINE_IRQ_BIT) { + int next_vcount_irq = __get_next_vcount_interrupt(); if(next_vcount_irq < VBLANK_SCANLINES) next_vcount_irq += SCANLINES; - u16 curr_vcount = REG_VCOUNT + 2; + int curr_vcount = REG_VCOUNT + 2; if(curr_vcount < VBLANK_SCANLINES) curr_vcount += SCANLINES; if(next_vcount_irq <= curr_vcount) @@ -154,6 +155,7 @@ IWRAM_CODE void vblank_update_function() { } IWRAM_CODE void find_optimal_ewram_settings() { + #ifdef __GBA__ size_t size = ewram_speed_check_bin_size>>2; const u32* ewram_speed_check = (const u32*)ewram_speed_check_bin; u32 test_data[size]; @@ -184,6 +186,7 @@ IWRAM_CODE void find_optimal_ewram_settings() { if(!failed) return; } + #endif } void disable_all_irqs() { @@ -709,7 +712,7 @@ void crash_on_cartridge_removed() { prepare_crash_screen(CARTRIDGE_REMOVED); base_stop_transfer(0); base_stop_transfer(1); - u8 curr_vcount = REG_VCOUNT + 1 + 1; + int curr_vcount = REG_VCOUNT + 1 + 1; if(curr_vcount >= SCANLINES) curr_vcount -= SCANLINES; while(REG_VCOUNT != curr_vcount); @@ -759,8 +762,10 @@ void complete_cartridge_loading(struct game_data_t* game_data, struct game_data_ int main(void) { + #ifdef __GBA__ RegisterRamReset(RESET_SIO|RESET_SOUND|RESET_OTHER); disable_all_irqs(); + #endif curr_state = MAIN_MENU; counter = 0; input_counter = 0; @@ -770,7 +775,7 @@ int main(void) init_enc_positions(); init_rng(0,0); init_save_data(); - u16 keys; + u32 keys; struct game_data_t game_data[2]; struct game_data_priv_t game_data_priv; struct saved_time_t time_change; @@ -782,8 +787,12 @@ int main(void) init_numbers(); init_unown_tsv(); + #ifdef HAS_SIO sio_stop_irq_slave(); + #endif + #ifdef __GBA__ irqInit(); + #endif irqSet(IRQ_VBLANK, vblank_update_function); irqEnable(IRQ_VBLANK); @@ -990,8 +999,10 @@ int main(void) cursor_update_main_menu(cursor_y_pos); if(returned_val == START_MULTIBOOT) { curr_state = MULTIBOOT; + #ifdef HAS_SIO sio_stop_irq_slave(); irqDisable(IRQ_SERIAL); + #endif disable_cursor(); init_save_data(); print_multiboot(multiboot_normal((u16*)EWRAM, (u16*)(EWRAM + MULTIBOOT_MAX_SIZE))); diff --git a/source/menu_text_handler.c b/source/menu_text_handler.c index 0793b1d..1efa6dc 100644 --- a/source/menu_text_handler.c +++ b/source/menu_text_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "menu_text_handler.h" #include "gen3_clock_events.h" #include "text_handler.h" @@ -16,11 +16,8 @@ #define NUM_LINES 10 #define MAIN_MENU_DISTANCE_FROM_BORDER 2 -#define ROM 0x8000000 #define ROM_SIZE 0x1000000 -#define EWRAM_SIZE 0x3FF40 - #define SUMMARY_LINE_MAX_SIZE 18 #define PRINTABLE_INVALID_STRINGS 3 @@ -150,11 +147,11 @@ void print_game_info(struct game_data_t* game_data, int index) { const char* chosen_str = maingame_strings[game_data[index].game_identifier.game_main_version]; switch(game_data[index].game_identifier.game_main_version) { case RS_MAIN_GAME_CODE: - if(game_data[index].game_identifier.game_sub_version != UNDETERMINED) + if(!game_data[index].game_identifier.game_sub_version_undetermined) chosen_str = subgame_rs_strings[game_data[index].game_identifier.game_sub_version]; break; case FRLG_MAIN_GAME_CODE: - if(game_data[index].game_identifier.game_sub_version != UNDETERMINED) + if(!game_data[index].game_identifier.game_sub_version_undetermined) chosen_str = subgame_frlg_strings[game_data[index].game_identifier.game_sub_version]; break; case E_MAIN_GAME_CODE: @@ -838,8 +835,14 @@ void print_learnable_moves_menu(struct gen3_mon_data_unenc* mon, u16 index) { } } PRINT_FUNCTION("Ability: \x01", get_ability_name_raw(mon)); - PRINT_FUNCTION("\nHidden Power: \x01 \x03", get_hidden_power_type_name_gen3(&mon->misc), get_hidden_power_power_gen3(&mon->misc)); - PRINT_FUNCTION("\nWhich move will be forgotten?\n"); + PRINT_FUNCTION("\nHidden Power: \x01 \x03\n", get_hidden_power_type_name_gen3(&mon->misc), get_hidden_power_power_gen3(&mon->misc)); + base_y = get_text_y(); + u8 offset_text_y = 0; + if(base_y < (((BASE_Y_CURSOR_LEARN_MOVE_MENU)>>3)-(3))) + offset_text_y = 1; + set_text_y(((BASE_Y_CURSOR_LEARN_MOVE_MENU)>>3)-(3 + offset_text_y)); + PRINT_FUNCTION("Which move will be forgotten?"); + set_text_y(((BASE_Y_CURSOR_LEARN_MOVE_MENU)>>3)-2); set_text_x((BASE_X_CURSOR_LEARN_MOVE_MENU>>3)+2); PRINT_FUNCTION("MOVES"); set_text_x(X_LIMIT-11+(BASE_X_CURSOR_LEARN_MOVE_MENU>>3)+2); diff --git a/source/multiboot_handler.c b/source/multiboot_handler.c index 8dd1797..f3842bb 100644 --- a/source/multiboot_handler.c +++ b/source/multiboot_handler.c @@ -1,9 +1,10 @@ -#include +#include "base_include.h" #include "multiboot_handler.h" #include "sio.h" #include "menu_text_handler.h" #include "print_system.h" #include "timing_basic.h" +#include "useful_qualifiers.h" #define MULTIBOOT_WAIT_TIME_NS 36000 #define MULTIBOOT_VCOUNTWAIT (((MULTIBOOT_WAIT_TIME_NS/NS_PER_SCANLINE) + ((MULTIBOOT_WAIT_TIME_NS%NS_PER_SCANLINE) == 0 ? 0 : 1))+1) @@ -16,7 +17,12 @@ int multiboot_normal_send(int data) { return timed_sio_normal_master(data, SIO_32, MULTIBOOT_VCOUNTWAIT) >> 0x10; } +#ifdef HAS_SIO enum MULTIBOOT_RESULTS multiboot_normal (u16* data, u16* end) { +#else +enum MULTIBOOT_RESULTS multiboot_normal (u16* UNUSED(data), u16* UNUSED(end)) { +#endif + #ifdef HAS_SIO int response; u8 clientMask = 0; int attempts, sends, halves; @@ -94,5 +100,6 @@ enum MULTIBOOT_RESULTS multiboot_normal (u16* data, u16* end) { if(MultiBoot(&mp, MODE32_NORMAL)) return MB_SWI_FAILURE; + #endif return MB_SUCCESS; } diff --git a/source/nds_functions.c b/source/nds_functions.c new file mode 100644 index 0000000..96f085d --- /dev/null +++ b/source/nds_functions.c @@ -0,0 +1,13 @@ +#include "base_include.h" +#include "useful_qualifiers.h" +#include "nds_functions.h" + +#ifdef __NDS__ +ARM_TARGET MAX_OPTIMIZE void Halt_ARM9() { + register uint32_t destroyed asm("r0"); + asm volatile( + "mov r0, #0; mcr p15, 0, r0, c7, c0, 4;" : "=r"(destroyed) : + "r"(destroyed) : + ); +} +#endif diff --git a/source/options_handler.c b/source/options_handler.c index c315431..a0dcd5b 100644 --- a/source/options_handler.c +++ b/source/options_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "party_handler.h" #include "options_handler.h" diff --git a/source/party_handler.c b/source/party_handler.c index 0bfe3fa..35b981e 100644 --- a/source/party_handler.c +++ b/source/party_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "party_handler.h" #include "text_handler.h" #include "sprite_handler.h" diff --git a/source/pid_iv_tid.c b/source/pid_iv_tid.c index 899245c..23951ad 100644 --- a/source/pid_iv_tid.c +++ b/source/pid_iv_tid.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "pid_iv_tid.h" #include "rng.h" #include "gen12_methods.h" diff --git a/source/print_system.c b/source/print_system.c index 2768b7f..405aa8d 100644 --- a/source/print_system.c +++ b/source/print_system.c @@ -1,5 +1,5 @@ +#include "base_include.h" #include -#include #include "optimized_swi.h" #include "print_system.h" #include "text_handler.h" @@ -15,17 +15,22 @@ #include "window_graphics_bin.h" #define VRAM_SIZE 0x10000 -#define VRAM_END (VRAM+VRAM_SIZE) +#define VRAM_END (((uintptr_t)VRAM_0)+VRAM_SIZE) #define PALETTE 0xF #define PALETTE_SIZE 0x10 #define PALETTE_BASE 0x5000000 #define FONT_TILES 0x100 #define FONT_SIZE (FONT_TILES*TILE_SIZE) #define FONT_1BPP_SIZE (FONT_SIZE>>2) -#define FONT_POS (VRAM + 0) +#define FONT_POS (((uintptr_t)VRAM_0) + 0) #define JP_FONT_POS (FONT_POS + FONT_SIZE) #define NUMBERS_POS (VRAM_END - (10000*2)) #define ARRANGEMENT_POS (JP_FONT_POS+FONT_SIZE) +#ifdef __NDS__ +#define FONT_POS_SUB (((uintptr_t)VRAM_0_SUB) + 0) +#define JP_FONT_POS_SUB (FONT_POS_SUB + FONT_SIZE) +#define ARRANGEMENT_POS_SUB (JP_FONT_POS_SUB+FONT_SIZE) +#endif #define X_OFFSET_POS 0 #define Y_OFFSET_POS 1 @@ -56,6 +61,9 @@ u8 is_screen_disabled(u8); u8 x_pos; u8 y_pos; screen_t* screen; +#ifdef __NDS__ +screen_t* screen_sub; +#endif u8 screen_num; u8 loaded_screen_num; @@ -68,7 +76,10 @@ u8 screen_positions[TOTAL_BG][2]; IWRAM_CODE void set_arrangements(u8 bg_num){ if(bg_num >= TOTAL_BG) bg_num = TOTAL_BG-1; - BGCTRL[bg_num] = get_bg_priority(bg_num) | ((((uintptr_t)get_screen(bg_num))-VRAM)>>3); + BGCTRL[bg_num] = get_bg_priority(bg_num) | ((((uintptr_t)get_screen(bg_num))-((uintptr_t)VRAM_0))>>3); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + BGCTRL_SUB[bg_num] = get_bg_priority(bg_num) | ((((uintptr_t)get_screen(bg_num))-((uintptr_t)VRAM_0))>>3); + #endif } IWRAM_CODE void process_arrangements() { @@ -84,16 +95,28 @@ IWRAM_CODE void swap_buffer_screen_internal(u8 bg_num) { if(bg_num >= TOTAL_BG) bg_num = TOTAL_BG-1; buffer_screen[bg_num] ^= 1; - if(bg_num == screen_num) + if(bg_num == screen_num) { screen = get_screen(bg_num); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub = get_screen_sub(bg_num); + #endif + } } IWRAM_CODE void enable_screens() { for(int i = 0; i < TOTAL_BG; i++) - if(enabled_screen[i]) + if(enabled_screen[i]) { REG_DISPCNT |= (0x100)<>2); i++) *((u32*)(FONT_POS+(i<<2))) = 0x22222222; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + for(size_t i = 0; i < (TILE_SIZE>>2); i++) + *((u32*)(FONT_POS_SUB+(i<<2))) = 0x22222222; + #endif default_reset_screen(); enable_screen(0); @@ -170,6 +212,9 @@ void init_text_system() { u8 colors[] = {2, 1}; LZ77UnCompWram(amiga_font_c_bin, buffer); convert_1bpp((u8*)buffer, (u32*)FONT_POS, FONT_1BPP_SIZE, colors, 1); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + convert_1bpp((u8*)buffer, (u32*)FONT_POS_SUB, FONT_1BPP_SIZE, colors, 1); + #endif PRINT_FUNCTION("\n Loading..."); base_flush(); @@ -177,14 +222,25 @@ void init_text_system() { // Set empty tile for(size_t i = 0; i < (TILE_SIZE>>2); i++) *((u32*)(FONT_POS+TILE_SIZE+(i<<2))) = 0; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + for(size_t i = 0; i < (TILE_SIZE>>2); i++) + *((u32*)(FONT_POS_SUB+TILE_SIZE+(i<<2))) = 0; + #endif // Load japanese font LZ77UnCompWram(jp_font_c_bin, buffer); convert_1bpp((u8*)buffer, (u32*)JP_FONT_POS, FONT_1BPP_SIZE, colors, 0); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + convert_1bpp((u8*)buffer, (u32*)JP_FONT_POS_SUB, FONT_1BPP_SIZE, colors, 0); + #endif // Set window tiles for(size_t i = 0; i < (window_graphics_bin_size>>2); i++) *((u32*)(FONT_POS+(2*TILE_SIZE)+(i<<2))) = ((const u32*)window_graphics_bin)[i]; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + for(size_t i = 0; i < (window_graphics_bin_size>>2); i++) + *((u32*)(FONT_POS_SUB+(2*TILE_SIZE)+(i<<2))) = ((const u32*)window_graphics_bin)[i]; + #endif } void set_updated_screen() { @@ -266,28 +322,45 @@ void set_bg_pos(u8 bg_num, int x, int y){ } u8 get_screen_num(){ - return screen_num; + return screen_num; } screen_t* get_screen(u8 bg_num){ if(bg_num >= TOTAL_BG) bg_num = TOTAL_BG-1; - return (screen_t*)(ARRANGEMENT_POS+(SCREEN_SIZE*(bg_num+(TOTAL_BG*buffer_screen[bg_num])))); + return (screen_t*)(ARRANGEMENT_POS+(SCREEN_SIZE*(bg_num+(TOTAL_BG*buffer_screen[bg_num])))); } +#ifdef __NDS__ +screen_t* get_screen_sub(u8 bg_num){ + if(bg_num >= TOTAL_BG) + bg_num = TOTAL_BG-1; + return (screen_t*)(ARRANGEMENT_POS_SUB+(SCREEN_SIZE*(bg_num+(TOTAL_BG*buffer_screen[bg_num])))); +} +#endif + void set_screen(u8 bg_num){ if(bg_num >= TOTAL_BG) bg_num = TOTAL_BG-1; screen_num = bg_num; screen = get_screen(bg_num); + #ifdef __NDS__ + screen_sub = get_screen_sub(bg_num); + #endif } void reset_screen(u8 blank_fill){ set_updated_screen(); *((u32*)screen) = (PALETTE<<28) | (PALETTE<<12) | 0; if(blank_fill) - *((u32*)screen) =(PALETTE<<28) | (PALETTE<<12) | 0x00010001; + *((u32*)screen) = (PALETTE<<28) | (PALETTE<<12) | 0x00010001; CpuFastSet(screen, screen, CPUFASTSET_FILL | (SCREEN_SIZE>>2)); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + *((u32*)screen_sub) = (PALETTE<<28) | (PALETTE<<12) | 0; + if(blank_fill) + *((u32*)screen_sub) = (PALETTE<<28) | (PALETTE<<12) | 0x00010001; + CpuFastSet(screen_sub, screen_sub, CPUFASTSET_FILL | (SCREEN_SIZE>>2)); + #endif x_pos = 0; y_pos = 0; } @@ -327,6 +400,9 @@ void new_line(){ u8 write_char(u16 character) { screen[x_pos+(y_pos*X_SIZE)] = character | (PALETTE << 12); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[x_pos+(y_pos*X_SIZE)] = character | (PALETTE << 12); + #endif x_pos++; if(x_pos >= X_LIMIT) { new_line(); @@ -340,6 +416,9 @@ void write_above_char(u16 character) { if(!y_pos) y_pos_altered = Y_SIZE-1; screen[x_pos+(y_pos_altered*X_SIZE)] = character | (PALETTE << 12); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[x_pos+(y_pos_altered*X_SIZE)] = character | (PALETTE << 12); + #endif } int sub_printf(u8* string) { diff --git a/source/rng.c b/source/rng.c index b7c8c09..623b765 100644 --- a/source/rng.c +++ b/source/rng.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "rng.h" #include "useful_qualifiers.h" diff --git a/source/save.c b/source/save.c index 1aad403..d3d6875 100644 --- a/source/save.c +++ b/source/save.c @@ -1,11 +1,9 @@ -#include +#include "base_include.h" #include "save.h" #include #include "useful_qualifiers.h" #include "timing_basic.h" -#define REG_WAITCNT *(vu16*)(REG_BASE + 0x204) // Wait state Control - #define IS_FLASH 1 #define SAVE_POS SRAM @@ -16,7 +14,7 @@ #define FLASH_TERM_CMD *((vu8*)(SAVE_POS+0x5555)) = 0xF0; #define FLASH_ENTER_MAN_CMD BASE_FLASH_CMD *((vu8*)(SAVE_POS+0x5555)) = 0x90; #define FLASH_EXIT_MAN_CMD BASE_FLASH_CMD FLASH_TERM_CMD FLASH_TERM_CMD -#define TIMEOUT (50000*((CLOCK_SPEED/GBA_CLOCK_SPEED) + ((CLOCK_SPEED%GBA_CLOCK_SPEED) == 0 ? 0 : 1))) +#define TIMEOUT (50000*(((CLOCK_SPEED + GBA_CLOCK_SPEED - 1)/GBA_CLOCK_SPEED) + TIMEOUT_INCREASE)) #define ERASE_TIMEOUT (TIMEOUT) #define ERASED_BYTE 0xFF #define BANK_SIZE 0x10000 @@ -41,7 +39,8 @@ u8 current_bank; u8 is_macronix; IWRAM_CODE void init_bank(){ - REG_WAITCNT |= 3; + REG_WAITCNT &= NON_SRAM_MASK; + REG_WAITCNT |= SRAM_READING_VALID_WAITCYCLES; current_bank = NUM_BANKS; is_macronix = 0; #if IS_FLASH @@ -76,7 +75,7 @@ IWRAM_CODE void erase_sector(uintptr_t address) { address <<= SECTOR_SIZE_BITS; u8 failed = 1; vu8* save_data = (vu8*)SAVE_POS; - for(int i = 0; failed && (i < 3); i++) { + for(size_t i = 0; failed && (i < 3); i++) { #if IS_FLASH FLASH_ERASE_SECTOR_BASE_CMD save_data[address] = ERASE_SECTOR_FINAL_CMD; diff --git a/source/sio.c b/source/sio.c index 09fcbce..70df9a3 100644 --- a/source/sio.c +++ b/source/sio.c @@ -1,6 +1,5 @@ -#include +#include "base_include.h" #include "sio.h" -#include "vcount_basic.h" #include "useful_qualifiers.h" #define BLANK_LINES_WAIT 13 @@ -8,6 +7,7 @@ void sio_normal_inner_slave(void); u8 sio_normal_inner_master(void); +#ifdef HAS_SIO IWRAM_CODE int timed_sio_normal_master(int data, int is_32, int vCountWait) { u8 curr_vcount, target_vcount; @@ -175,3 +175,4 @@ IWRAM_CODE int sio_normal(int data, int is_master, int is_32, u8* success) { else return (REG_SIODATA8 & 0xFF); } +#endif diff --git a/source/sio_buffers.c b/source/sio_buffers.c index 1062fb1..fbf0981 100644 --- a/source/sio_buffers.c +++ b/source/sio_buffers.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "sio_buffers.h" #include "text_handler.h" #include "options_handler.h" diff --git a/source/sprite_handler.c b/source/sprite_handler.c index a64f4b5..3af4881 100644 --- a/source/sprite_handler.c +++ b/source/sprite_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "sprite_handler.h" #include "graphics_handler.h" #include "print_system.h" @@ -22,18 +22,27 @@ #define CURSOR_SPRITE_PALETTE_INDEX 9 #define SPRITE_SIZE (SPRITE_BASE_SIZE_MULTIPLIER*SPRITE_ALT_DISTANCE) -#define OVRAM_START ((uintptr_t)OBJ_BASE_ADR) #define OVRAM_SIZE 0x8000 #define OVRAM_END (OVRAM_START+OVRAM_SIZE) +#ifdef __NDS__ +#define OVRAM_END_SUB (OVRAM_START_SUB+OVRAM_SIZE) +#endif #define POSSIBLE_SPRITES (OVRAM_SIZE/SPRITE_SIZE) #define OAM_ENTITIES 0x80 +#define OAM_DATA ((OBJATTR *)OAM) +#ifdef __NDS__ +#define OAM_DATA_SUB ((OBJATTR *)OAM_SUB) +#endif #define DISABLE_SPRITE (1<<9) #define OFF_SCREEN_SPRITE SCREEN_HEIGHT u8 check_for_same_address(const u8*); uintptr_t get_vram_pos(void); +#ifdef __NDS__ +uintptr_t get_vram_pos_sub(void); +#endif void set_updated_shadow_oam(void); void inc_inner_sprite_counter(void); u8 get_sprite_counter(void); @@ -81,10 +90,17 @@ void set_updated_shadow_oam() { IWRAM_CODE void update_normal_oam() { if(updated_shadow_oam) { - u32* oam_ptr = (u32*)OAM; + u32* oam_ptr = (u32*)OAM_DATA; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + u32* oam_ptr_sub = (u32*)OAM_DATA_SUB; + #endif u32* shadow_oam_ptr = (u32*)shadow_oam; - for(size_t i = 0; i < ((sizeof(OBJATTR)*OAM_ENTITIES)>>2); i++) + for(size_t i = 0; i < ((sizeof(OBJATTR)*OAM_ENTITIES)>>2); i++) { oam_ptr[i] = shadow_oam_ptr[i]; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + oam_ptr_sub[i] = shadow_oam_ptr[i]; + #endif + } updated_shadow_oam = 0; } loaded_inner_sprite_counter = __inner_sprite_counter; @@ -98,10 +114,16 @@ void set_party_sprite_counter(){ void enable_sprites_rendering(){ REG_DISPCNT |= OBJ_ON | OBJ_1D_MAP; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + REG_DISPCNT_SUB |= OBJ_ON | OBJ_1D_MAP; + #endif } void disable_sprites_rendering(){ REG_DISPCNT &= ~(OBJ_ON); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + REG_DISPCNT_SUB &= ~(OBJ_ON); + #endif } void init_sprites(){ @@ -137,6 +159,15 @@ uintptr_t get_vram_pos(){ return vram_pos; } +#ifdef __NDS__ +uintptr_t get_vram_pos_sub(){ + uintptr_t vram_pos = OVRAM_START_SUB+(__sprite_counter*SPRITE_SIZE); + if(vram_pos >= OVRAM_END_SUB) + vram_pos = OVRAM_END_SUB - SPRITE_SIZE; + return vram_pos; +} +#endif + u8 get_3bpp_palette(int index) { return (index>>1) + get_first_variable_palette(); } @@ -151,6 +182,12 @@ void set_palette_3bpp(u8* colors, int index, int palette) { SPRITE_PALETTE[base+i+(new_palette<<4)] = SPRITE_PALETTE[colors[i]+(palette<<4)]; else SPRITE_PALETTE[i+(new_palette<<4)] = SPRITE_PALETTE[colors[i]+(palette<<4)]; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + if(i) + SPRITE_PALETTE_SUB[base+i+(new_palette<<4)] = SPRITE_PALETTE_SUB[colors[i]+(palette<<4)]; + else + SPRITE_PALETTE_SUB[i+(new_palette<<4)] = SPRITE_PALETTE_SUB[colors[i]+(palette<<4)]; + #endif } } @@ -160,6 +197,11 @@ void init_cursor(){ u16* vram_pos = (u16*)(get_vram_pos() + (SPRITE_ALT_DISTANCE*i)); for(size_t j = 0; j < (sprite_cursor_bin_size>>1); j++) vram_pos[j] = sprite_cursor_gfx[j]; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + vram_pos = (u16*)(get_vram_pos_sub() + (SPRITE_ALT_DISTANCE*i)); + for(size_t j = 0; j < (sprite_cursor_bin_size>>1); j++) + vram_pos[j] = sprite_cursor_gfx[j]; + #endif } for(int i = 0; i < TOTAL_BG; i++) { set_attributes(OFF_SCREEN_SPRITE, 0, (SPRITE_TILE_SIZE*__sprite_counter) | ((3-i)<<10) | ((sprite_palettes_bin_size>>5)<<12)); @@ -174,6 +216,9 @@ void init_cursor(){ void set_cursor_palette() { SPRITE_PALETTE[(sprite_palettes_bin_size>>1)+CURSOR_SPRITE_PALETTE_INDEX] = get_full_colour(SPRITE_COLOUR_POS); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + SPRITE_PALETTE_SUB[(sprite_palettes_bin_size>>1)+CURSOR_SPRITE_PALETTE_INDEX] = get_full_colour(SPRITE_COLOUR_POS); + #endif } void init_oam_palette(){ @@ -181,6 +226,12 @@ void init_oam_palette(){ SPRITE_PALETTE[i] = sprite_palettes_bin_16[i]; for(size_t i = 0; i < (item_icon_palette_bin_size>>1); i++) SPRITE_PALETTE[i+(sprite_palettes_bin_size>>1)] = item_icon_palette_bin_16[i]; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + for(size_t i = 0; i < (sprite_palettes_bin_size>>1); i++) + SPRITE_PALETTE_SUB[i] = sprite_palettes_bin_16[i]; + for(size_t i = 0; i < (item_icon_palette_bin_size>>1); i++) + SPRITE_PALETTE_SUB[i+(sprite_palettes_bin_size>>1)] = item_icon_palette_bin_16[i]; + #endif set_cursor_palette(); } @@ -189,6 +240,11 @@ void init_item_icon(){ u16* vram_pos = (u16*)(get_vram_pos() + sprite_cursor_bin_size + (SPRITE_ALT_DISTANCE*i)); for(size_t j = 0; j < (item_icon_bin_size>>1); j++) vram_pos[j] = item_icon_gfx[j]; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + vram_pos = (u16*)(get_vram_pos_sub() + sprite_cursor_bin_size + (SPRITE_ALT_DISTANCE*i)); + for(size_t j = 0; j < (item_icon_bin_size>>1); j++) + vram_pos[j] = item_icon_gfx[j]; + #endif } } @@ -232,6 +288,9 @@ void set_pokemon_sprite(const u8* address, u8 palette, u8 info, u8 display_item, if(position == POSSIBLE_SPRITES) { u8 colors[8]; load_pokemon_sprite_gfx((const u32*)address, (u32*)get_vram_pos(), is_3bpp, zero_fill, __sprite_counter-(cursor_sprite+1), colors); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + load_pokemon_sprite_gfx((const u32*)address, (u32*)get_vram_pos_sub(), is_3bpp, zero_fill, __sprite_counter-(cursor_sprite+1), colors); + #endif if(is_3bpp) set_palette_3bpp(colors, __sprite_counter-(cursor_sprite+1), palette); position = __sprite_counter; @@ -251,15 +310,22 @@ void update_cursor_y(u16 cursor_y){ } IWRAM_CODE void raw_update_cursor_x(u16 cursor_x){ - OAM[inner_cursor_sprite-get_loaded_priority()].attr1 = cursor_x; + OAM_DATA[inner_cursor_sprite-get_loaded_priority()].attr1 = cursor_x; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + OAM_DATA_SUB[inner_cursor_sprite-get_loaded_priority()].attr1 = cursor_x; + #endif shadow_oam[inner_cursor_sprite-get_loaded_priority()].attr1 = cursor_x; } IWRAM_CODE void raw_update_sprite_y(u8 index, u8 new_y){ if(index >= OAM_ENTITIES) index = OAM_ENTITIES-1; - OAM[index].attr0 &= ~0xFF; - OAM[index].attr0 |= new_y; + OAM_DATA[index].attr0 &= ~0xFF; + OAM_DATA[index].attr0 |= new_y; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + OAM_DATA_SUB[index].attr0 &= ~0xFF; + OAM_DATA_SUB[index].attr0 |= new_y; + #endif shadow_oam[index].attr0 &= ~0xFF; shadow_oam[index].attr0 |= new_y; } @@ -268,11 +334,20 @@ IWRAM_CODE void fade_all_sprites_to_white(u16 fading_fraction){ REG_BLDCNT &= ~(3<<6); REG_BLDCNT |= (1<<4) | (2<<6); REG_BLDY = fading_fraction; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + REG_BLDCNT_SUB &= ~(3<<6); + REG_BLDCNT_SUB |= (1<<4) | (2<<6); + REG_BLDY_SUB = fading_fraction; + #endif } IWRAM_CODE void remove_fade_all_sprites(){ REG_BLDCNT &= ~((1<<4) | (2<<6)); REG_BLDY = 0; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + REG_BLDCNT_SUB &= ~((1<<4) | (2<<6)); + REG_BLDY_SUB = 0; + #endif } void update_cursor_base_x(u16 cursor_x){ @@ -342,10 +417,16 @@ IWRAM_CODE void move_sprites(u8 counter){ if(loaded_inner_sprite_counter > OAM_ENTITIES) limit = OAM_ENTITIES; for(int i = inner_cursor_sprite+1; i < limit; i++) { - u16 obj_attr_2 = OAM[i].attr2 & ~SPRITE_BASE_TILE_SIZE; + u16 obj_attr_2 = OAM_DATA[i].attr2 & ~SPRITE_BASE_TILE_SIZE; if(counter_kind) obj_attr_2 |= SPRITE_BASE_TILE_SIZE; - OAM[i].attr2 = obj_attr_2; + OAM_DATA[i].attr2 = obj_attr_2; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + obj_attr_2 = OAM_DATA_SUB[i].attr2 & ~SPRITE_BASE_TILE_SIZE; + if(counter_kind) + obj_attr_2 |= SPRITE_BASE_TILE_SIZE; + OAM_DATA_SUB[i].attr2 = obj_attr_2; + #endif } } diff --git a/source/text_handler.c b/source/text_handler.c index a2e25ee..22ba89a 100644 --- a/source/text_handler.c +++ b/source/text_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "text_handler.h" #include "bin_table_handler.h" #include "useful_qualifiers.h" diff --git a/source/version_identifier.c b/source/version_identifier.c index 5541a55..4db9f91 100644 --- a/source/version_identifier.c +++ b/source/version_identifier.c @@ -1,17 +1,13 @@ -#include +#include "base_include.h" #include "version_identifier.h" #include "save.h" #include "text_handler.h" #include "party_handler.h" #include "gen3_save.h" -#define REG_WAITCNT *(vu16*)(REG_BASE + 0x204) // Wait state Control - -#define ROM 0x8000000 - -#define GAME_STRING_POS (ROM+0xA0) +#define GAME_STRING_POS (((uintptr_t)ROM)+0xA0) #define GAME_STRING_SIZE 0xC -#define LANGUAGE_ID_POS (ROM+0xAF) +#define LANGUAGE_ID_POS (((uintptr_t)ROM)+0xAF) #define JAPANESE_ID 0x4A #define ENGLISH_ID_0 0x45 #define ENGLISH_ID_1 0x50 @@ -48,10 +44,9 @@ u8 is_trainer_name_japanese(u8* buffer) { void get_game_id(struct game_identity* identifier) { u8 tmp_buffer[GAME_STRING_SIZE+1]; - REG_WAITCNT = 0x4314; + REG_WAITCNT = BASE_WAITCNT_VAL; text_generic_copy((u8*)GAME_STRING_POS, tmp_buffer, GAME_STRING_SIZE, GAME_STRING_SIZE+1); u8 language_char = *((u8*)LANGUAGE_ID_POS); - REG_WAITCNT = 0; for(int i = 0; i < NUMBER_OF_GAMES; i++) if(text_generic_is_same((const u8*)game_identifier_strings[i], tmp_buffer, GAME_STRING_SIZE, GAME_STRING_SIZE)) { identifier->game_main_version = main_identifiers[i]; diff --git a/source/window_handler.c b/source/window_handler.c index cbacd70..1512ecd 100644 --- a/source/window_handler.c +++ b/source/window_handler.c @@ -1,4 +1,4 @@ -#include +#include "base_include.h" #include "print_system.h" #include "window_handler.h" @@ -132,11 +132,16 @@ void clear_offer_options_window() { void create_window(u8 x, u8 y, u8 x_size, u8 y_size, u8 screen_num) { set_updated_screen(); screen_t* screen = get_screen(screen_num); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_t* screen_sub = get_screen_sub(screen_num); + #endif + u8 fill_x = x_size == TOTAL_X_SIZE; + u8 fill_y = y_size == TOTAL_Y_SIZE; if(2+x+x_size > X_SIZE) - x_size = 0; + x_size = X_SIZE - (x + 1); if(2+y+y_size > Y_SIZE) - y_size = 0; + y_size = Y_SIZE - (y + 1); if((!x_size) || (!y_size)) return; @@ -155,25 +160,64 @@ void create_window(u8 x, u8 y, u8 x_size, u8 y_size, u8 screen_num) { if(end_y >= Y_SIZE) end_y -= Y_SIZE; - for(int i = 0; i < x_size; i++) { - screen[x+(start_y*X_SIZE)+i] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE; - screen[x+(end_y*X_SIZE)+i] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE | VSWAP_TILE; + if(!fill_y) { + for(int i = 0; i < x_size; i++) { + screen[x+(start_y*X_SIZE)+i] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE; + screen[x+(end_y*X_SIZE)+i] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE | VSWAP_TILE; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[x+(start_y*X_SIZE)+i] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE; + screen_sub[x+(end_y*X_SIZE)+i] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE | VSWAP_TILE; + #endif + } + if(fill_x) { + screen[x+(start_y*X_SIZE)+x_size] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE; + screen[x+(end_y*X_SIZE)+x_size] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE | VSWAP_TILE; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[x+(start_y*X_SIZE)+x_size] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE; + screen_sub[x+(end_y*X_SIZE)+x_size] = (PALETTE<<12) | HORIZONTAL_WINDOW_TILE | VSWAP_TILE; + #endif + } } - for(int i = 0; i < y_size; i++) { - screen[start_x+((y+i)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE; - screen[end_x+((y+i)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE | HSWAP_TILE; + if(!fill_x) { + for(int i = 0; i < y_size; i++) { + screen[start_x+((y+i)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE; + screen[end_x+((y+i)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE | HSWAP_TILE; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[start_x+((y+i)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE; + screen_sub[end_x+((y+i)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE | HSWAP_TILE; + #endif + } + if(fill_y) { + screen[start_x+((y+y_size)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE; + screen[end_x+((y+y_size)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE | HSWAP_TILE; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[start_x+((y+y_size)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE; + screen_sub[end_x+((y+y_size)*X_SIZE)] = (PALETTE<<12) | VERTICAL_WINDOW_TILE | HSWAP_TILE; + #endif + } } - screen[start_x+(start_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE; - screen[end_x+(start_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | HSWAP_TILE; - screen[start_x+(end_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | VSWAP_TILE; - screen[end_x+(end_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | HSWAP_TILE | VSWAP_TILE; + if((!fill_x) && (!fill_y)) { + screen[start_x+(start_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE; + screen[end_x+(start_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | HSWAP_TILE; + screen[start_x+(end_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | VSWAP_TILE; + screen[end_x+(end_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | HSWAP_TILE | VSWAP_TILE; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[start_x+(start_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE; + screen_sub[end_x+(start_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | HSWAP_TILE; + screen_sub[start_x+(end_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | VSWAP_TILE; + screen_sub[end_x+(end_y*X_SIZE)] = (PALETTE<<12) | ANGLE_WINDOW_TILE | HSWAP_TILE | VSWAP_TILE; + #endif + } } void reset_window(u8 x, u8 y, u8 x_size, u8 y_size, u8 screen_num){ set_updated_screen(); screen_t* screen = get_screen(screen_num); + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_t* screen_sub = get_screen_sub(screen_num); + #endif for(int i = 0; i < y_size; i++) { u8 inside_y = y + i; @@ -184,6 +228,9 @@ void reset_window(u8 x, u8 y, u8 x_size, u8 y_size, u8 screen_num){ if(inside_x >= X_SIZE) inside_x -= X_SIZE; screen[inside_x+(inside_y*X_SIZE)] = (PALETTE<<12) | 0; + #if defined (__NDS__) && (SAME_ON_BOTH_SCREENS) + screen_sub[inside_x+(inside_y*X_SIZE)] = (PALETTE<<12) | 0; + #endif } } }