From be25e05f4aab3cd91ec13ce45f3f18ad7ff9cd5f Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sat, 24 Dec 2022 17:01:39 -0500 Subject: [PATCH 01/14] ascii from hackersm64, builds us_pc, missing stuff --- .gitignore | 6 + Makefile | 114 +- Makefile.split | 14 +- assets.json | 6 - bin/eu/translation_de.c | 15 - bin/eu/translation_en.c | 15 - bin/eu/translation_fr.c | 15 - bin/segment2.c | 1408 +++++-- bin/translation_de.c | 17 + bin/translation_en.c | 17 + bin/translation_fr.c | 17 + bin/translation_jp.c | 17 + charmap.txt | 356 -- charmap_menu.txt | 30 - defines.mk | 6 +- include/config.h | 1 + include/config/config_language.h | 33 + include/eu_translation.h | 24 - include/qol_defines.h | 2 +- include/segment_symbols.h | 11 +- include/text_cheats_strings.h.in | 78 - include/text_debug_strings.h.in | 42 - include/text_menu_strings.h.in | 18 - include/text_options_strings.h.in | 181 - include/text_strings.h.in | 502 --- include/types.h | 2 + .../menu/custom/main_menu_seg7.acute.ia8.png | Bin 0 -> 4602 bytes .../custom/main_menu_seg7.cedilla.ia8.png | Bin 0 -> 4693 bytes .../custom/main_menu_seg7.circumflex.ia8.png | Bin 0 -> 4605 bytes .../menu/custom/main_menu_seg7.grave.ia8.png | Bin 0 -> 4600 bytes ...enu_seg7.inverted_exclamation_mark.ia8.png | Bin 0 -> 4699 bytes ...n_menu_seg7.inverted_question_mark.ia8.png | Bin 0 -> 4682 bytes .../main_menu_seg7.missing_character.ia8.png | Bin 0 -> 4696 bytes .../main_menu_seg7.tilde_diacritic.ia8.png | Bin 0 -> 4598 bytes levels/menu/header.h | 31 +- levels/menu/leveldata.c | 826 ++-- .../predone/main_menu_seg7_eu.0B840.ia8.png | Bin 0 -> 76 bytes .../predone/main_menu_seg7_eu.0B8C0.ia8.png | Bin 0 -> 78 bytes sm64.ld | 30 +- src/extras/draw_util.c | 161 +- src/extras/draw_util.h | 21 - src/extras/redone/title_screen.inc.c | 22 +- src/game/area.c | 21 +- src/game/hud.c | 5 +- src/game/ingame_menu.c | 3373 ++++++----------- src/game/ingame_menu.h | 279 +- src/game/level_update.c | 34 +- src/game/mario_actions_cutscene.c | 52 +- src/game/print.c | 385 +- src/game/print.h | 30 +- src/game/save_file.c | 12 +- src/game/save_file.h | 27 +- src/game/segment2.h | 12 +- src/game/segment7.h | 23 +- src/menu/file_select.c | 2505 ++++-------- src/menu/file_select.h | 26 +- src/menu/star_select.c | 196 +- src/menu/star_select.h | 4 - text/define_courses.inc.c | 21 +- text/define_text.inc.c | 75 +- .../custom/font_graphics.acute.ia4.png | Bin 0 -> 4584 bytes .../custom/font_graphics.backslash.ia4.png | Bin 0 -> 5716 bytes .../custom/font_graphics.cedilla.ia4.png | Bin 0 -> 4620 bytes .../custom/font_graphics.circumflex.ia4.png | Bin 0 -> 80 bytes .../font_graphics.double_low_quote.ia4.png | Bin 0 -> 4607 bytes .../custom/font_graphics.eszett.ia4.png | Bin 0 -> 115 bytes .../custom/font_graphics.grave.ia4.png | Bin 0 -> 4586 bytes .../custom/font_graphics.i_no_dot.ia4.png | Bin 0 -> 4606 bytes ...graphics.inverted_exclamation_mark.ia4.png | Bin 0 -> 4598 bytes ...nt_graphics.inverted_question_mark.ia4.png | Bin 0 -> 4628 bytes .../font_graphics.missing_character.ia4.png | Bin 0 -> 4664 bytes .../custom/font_graphics.plus.ia4.png | Bin 0 -> 5553 bytes .../custom/font_graphics.slash.ia4.png | Bin 0 -> 5501 bytes .../font_graphics.tilde_diacritic.ia4.png | Bin 0 -> 4591 bytes .../custom/font_graphics.umlaut.ia4.png | Bin 0 -> 75 bytes .../custom/tex_decimal_point.rgba16.png | Bin 0 -> 4782 bytes textures/segment2/custom/tex_minus.rgba16.png | Bin 0 -> 169 bytes .../segment2.02600.rgba16.png | Bin .../segment2.03400.rgba16.png | Bin .../segment2.03E00.rgba16.png | Bin .../segment2.04200.rgba16.png | Bin .../segment2.04600.rgba16.png | Bin .../segment2.04C00.rgba16.png | Bin .../segment2.04E00.rgba16.png | Bin .../segment2.05000.rgba16.png | Bin .../segment2.05200.rgba16.png | Bin .../segment2.05400.rgba16.png | Bin .../predone/segment2.05E00.rgba16.png | Bin 0 -> 233 bytes .../predone/segment2.06000.rgba16.png | Bin 0 -> 210 bytes .../predone/segment2.umlaut.rgba16.png | Bin 0 -> 156 bytes tools/Makefile | 4 +- 91 files changed, 4025 insertions(+), 7097 deletions(-) delete mode 100644 bin/eu/translation_de.c delete mode 100644 bin/eu/translation_en.c delete mode 100644 bin/eu/translation_fr.c create mode 100644 bin/translation_de.c create mode 100644 bin/translation_en.c create mode 100644 bin/translation_fr.c create mode 100644 bin/translation_jp.c delete mode 100644 charmap.txt delete mode 100644 charmap_menu.txt create mode 100644 include/config/config_language.h delete mode 100644 include/eu_translation.h delete mode 100644 include/text_cheats_strings.h.in delete mode 100644 include/text_debug_strings.h.in delete mode 100644 include/text_menu_strings.h.in delete mode 100644 include/text_options_strings.h.in delete mode 100644 include/text_strings.h.in create mode 100644 levels/menu/custom/main_menu_seg7.acute.ia8.png create mode 100644 levels/menu/custom/main_menu_seg7.cedilla.ia8.png create mode 100644 levels/menu/custom/main_menu_seg7.circumflex.ia8.png create mode 100644 levels/menu/custom/main_menu_seg7.grave.ia8.png create mode 100644 levels/menu/custom/main_menu_seg7.inverted_exclamation_mark.ia8.png create mode 100644 levels/menu/custom/main_menu_seg7.inverted_question_mark.ia8.png create mode 100644 levels/menu/custom/main_menu_seg7.missing_character.ia8.png create mode 100644 levels/menu/custom/main_menu_seg7.tilde_diacritic.ia8.png create mode 100644 levels/menu/predone/main_menu_seg7_eu.0B840.ia8.png create mode 100644 levels/menu/predone/main_menu_seg7_eu.0B8C0.ia8.png create mode 100644 textures/segment2/custom/font_graphics.acute.ia4.png create mode 100644 textures/segment2/custom/font_graphics.backslash.ia4.png create mode 100644 textures/segment2/custom/font_graphics.cedilla.ia4.png create mode 100644 textures/segment2/custom/font_graphics.circumflex.ia4.png create mode 100644 textures/segment2/custom/font_graphics.double_low_quote.ia4.png create mode 100644 textures/segment2/custom/font_graphics.eszett.ia4.png create mode 100644 textures/segment2/custom/font_graphics.grave.ia4.png create mode 100644 textures/segment2/custom/font_graphics.i_no_dot.ia4.png create mode 100644 textures/segment2/custom/font_graphics.inverted_exclamation_mark.ia4.png create mode 100644 textures/segment2/custom/font_graphics.inverted_question_mark.ia4.png create mode 100644 textures/segment2/custom/font_graphics.missing_character.ia4.png create mode 100644 textures/segment2/custom/font_graphics.plus.ia4.png create mode 100644 textures/segment2/custom/font_graphics.slash.ia4.png create mode 100644 textures/segment2/custom/font_graphics.tilde_diacritic.ia4.png create mode 100644 textures/segment2/custom/font_graphics.umlaut.ia4.png create mode 100644 textures/segment2/custom/tex_decimal_point.rgba16.png create mode 100644 textures/segment2/custom/tex_minus.rgba16.png rename textures/segment2/{custom => predone}/segment2.02600.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.03400.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.03E00.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.04200.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.04600.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.04C00.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.04E00.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.05000.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.05200.rgba16.png (100%) rename textures/segment2/{custom => predone}/segment2.05400.rgba16.png (100%) create mode 100644 textures/segment2/predone/segment2.05E00.rgba16.png create mode 100644 textures/segment2/predone/segment2.06000.rgba16.png create mode 100644 textures/segment2/predone/segment2.umlaut.rgba16.png diff --git a/.gitignore b/.gitignore index d80817a7f..0dffd5cdf 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,12 @@ sm64config.txt !/assets/**/*custom*.bin !/assets/**/*custom*/**/*.bin +# Pre-extracted files, to use between game versions +!/levels/**/*predone*.png +!/levels/**/*predone*/**/*.png +!/textures/**/*predone*.png +!/textures/**/*predone*/**/*.png + # Android files !/textures/touchcontrols/*.png platform/android/SDL/include diff --git a/Makefile b/Makefile index bc02a53e9..2c9c1f725 100644 --- a/Makefile +++ b/Makefile @@ -1058,7 +1058,6 @@ MIO0TOOL := $(TOOLS_DIR)/mio0$(EXT_PREFIX) N64CKSUM := $(TOOLS_DIR)/n64cksum$(EXT_PREFIX) N64GRAPHICS := $(TOOLS_DIR)/n64graphics$(EXT_PREFIX) N64GRAPHICS_CI := $(TOOLS_DIR)/n64graphics_ci$(EXT_PREFIX) -TEXTCONV := $(TOOLS_DIR)/textconv$(EXT_PREFIX) AIFF_EXTRACT_CODEBOOK := $(TOOLS_DIR)/aiff_extract_codebook$(EXT_PREFIX) VADPCM_ENC := $(TOOLS_DIR)/vadpcm_enc$(EXT_PREFIX) EXTRACT_DATA_FOR_MIO := $(TOOLS_DIR)/extract_data_for_mio$(EXT_PREFIX) @@ -1092,7 +1091,7 @@ YELLOW := \033[0;33m BLINK := \033[32;5m endif -EXTRACT_DATA_FOR_MIO := $(OBJCOPY) -O binary --only-section=.data +EXTRACT_DATA_FOR_MIO := $(OBJCOPY) -O binary --only-section=.data --only-section=.rodata # Common build print status function define print @@ -1221,28 +1220,6 @@ endif $(SOUND_BIN_DIR)/sound_data.o: $(SOUND_FILES) $(BUILD_DIR)/levels/scripts.o: $(BUILD_DIR)/include/level_headers.h -ifeq ($(VERSION),eu) - TEXT_DIRS := text/de text/us text/fr - - # EU encoded text inserted into individual segment 0x19 files, - # and course data also duplicated in leveldata.c - $(BUILD_DIR)/bin/eu/translation_en.o: $(BUILD_DIR)/text/us/define_text.inc.c - $(BUILD_DIR)/bin/eu/translation_de.o: $(BUILD_DIR)/text/de/define_text.inc.c - $(BUILD_DIR)/bin/eu/translation_fr.o: $(BUILD_DIR)/text/fr/define_text.inc.c - $(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/us/define_courses.inc.c - $(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/de/define_courses.inc.c - $(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/fr/define_courses.inc.c -else - ifeq ($(VERSION),sh) - TEXT_DIRS := text/jp - $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/jp/define_text.inc.c - else - TEXT_DIRS := text/$(VERSION) - # non-EU encoded text inserted into segment 0x02 - $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/$(VERSION)/define_text.inc.c - endif -endif - # File specific opt flags for N64 # TODO: I need help with this, they don't get set even though they were copy-pasted from HackerSM64 # If someone with more Makefile knowledge can fix it, i would really appreciate it @@ -1264,7 +1241,7 @@ ifeq ($(TARGET_N64),1) endif endif -ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) +ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) ifeq ($(TARGET_N64),1) ALL_DIRS += $(RSP_DIR) @@ -1282,57 +1259,6 @@ endif # Make sure build directory exists before compiling anything DUMMY != mkdir -p $(ALL_DIRS) -$(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h - -ifeq ($(EXT_OPTIONS_MENU),1) - $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_options_strings.h -endif - -ifeq ($(CHEATS_ACTIONS),1) - $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_cheats_strings.h -endif - -ifeq ($(EXT_DEBUG_MENU),1) - $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_debug_strings.h -endif - -ifeq ($(VERSION),eu) - LANG_O_FILES := $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o -else - LANG_O_FILES := -endif - -$(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) -$(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) -$(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) - -ifeq ($(TARGET_N64),1) - $(BUILD_DIR)/src/extras/n64/ext_mem_screen.o: $(BUILD_DIR)/include/text_strings.h -endif - -ifeq ($(EXT_OPTIONS_MENU),1) - - ifeq ($(BETTERCAMERA),1) - $(BUILD_DIR)/src/extras/bettercamera.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) - endif - - ifeq ($(CHEATS_ACTIONS),1) - $(BUILD_DIR)/src/extras/cheats.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) - endif - - ifeq ($(EXT_DEBUG_MENU),1) - $(BUILD_DIR)/src/extras/debug_menu.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) - endif - - $(BUILD_DIR)/src/extras/options_menu.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) -endif - -ifeq ($(TARGET_PORT_CONSOLE),0) - ifeq ($(DISCORDRPC),1) - $(BUILD_DIR)/src/pc/discord/discordrpc.o: $(BUILD_DIR)/include/text_strings.h $(LANG_O_FILES) - endif -endif - #==============================================================================# # Texture Generation # #==============================================================================# @@ -1470,42 +1396,6 @@ $(BUILD_DIR)/assets/demo_data.c: assets/demo_data.json $(wildcard assets/demos/* @$(PRINT) "$(GREEN)Generating demo data $(NO_COL)\n" $(V)$(PYTHON) tools/demo_data_converter.py assets/demo_data.json $(DEF_INC_CFLAGS) > $@ -# Encode in-game text strings -$(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in - $(call print,Encoding:,$<,$@) - $(V)$(TEXTCONV) charmap.txt $< $@ - -$(BUILD_DIR)/include/text_menu_strings.h: include/text_menu_strings.h.in - $(call print,Encoding:,$<,$@) - $(V)$(TEXTCONV) charmap_menu.txt $< $@ - -$(BUILD_DIR)/text/%/define_courses.inc.c: text/define_courses.inc.c text/%/courses.h - @$(PRINT) "$(GREEN)Preprocessing: $(BLUE)$@ $(NO_COL)\n" - $(V)$(CPP) $(CPPFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@ - -$(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h text/%/dialogs.h - @$(PRINT) "$(GREEN)Preprocessing: $(BLUE)$@ $(NO_COL)\n" - $(V)$(CPP) $(CPPFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@ - -ifeq ($(EXT_OPTIONS_MENU),1) -$(BUILD_DIR)/include/text_options_strings.h: include/text_options_strings.h.in - $(call print,Encoding:,$<,$@) - $(V)$(TEXTCONV) charmap.txt $< $@ - -ifeq ($(CHEATS_ACTIONS),1) -$(BUILD_DIR)/include/text_cheats_strings.h: include/text_cheats_strings.h.in - $(call print,Encoding:,$<,$@) - $(V)$(TEXTCONV) charmap.txt $< $@ -endif - -ifeq ($(EXT_DEBUG_MENU),1) -$(BUILD_DIR)/include/text_debug_strings.h: include/text_debug_strings.h.in - $(call print,Encoding:,$<,$@) - $(V)$(TEXTCONV) charmap.txt $< $@ -endif - -endif - # Level headers $(BUILD_DIR)/include/level_headers.h: levels/level_headers.h.in $(call print,Preprocessing level headers:,$<,$@) diff --git a/Makefile.split b/Makefile.split index cba4b5dfd..953f767bd 100644 --- a/Makefile.split +++ b/Makefile.split @@ -11,7 +11,10 @@ SEGMENTS := \ # Directories containing PNG files TEXTURE_DIRS := \ $(wildcard textures/*/) \ + $(wildcard levels/*/custom/) \ + $(wildcard levels/*/predone/) \ $(wildcard textures/*/custom/) \ + $(wildcard textures/*/predone/) \ $(filter %/,$(wildcard actors/*/)) ifeq ($(PORT_MOP_OBJS),1) @@ -193,6 +196,9 @@ endif $(eval $(call level_rules,intro,generic)) # Intro (Super Mario 64 Logo) $(eval $(call level_rules,menu,generic)) # Menu (File Select) +CUSTOM_MENU_SEG7_FILES := $(wildcard levels/menu/custom/*.png) $(wildcard levels/menu/predone/*.png) +$(BUILD_DIR)/levels/menu/leveldata.o: $(addprefix $(BUILD_DIR)/,$(patsubst %.png,%.inc.c,$(CUSTOM_MENU_SEG7_FILES))) + # -------------------------------------- # Cake Texture Rules # -------------------------------------- @@ -210,7 +216,7 @@ $(BUILD_DIR)/levels/ending/cake.inc.c: levels/ending/cake.png # -------------------------------------- # Others -SEGMENT2_TEXTURES := $(wildcard $(TEXTURE_DIR)/segment2/*.png) $(wildcard $(TEXTURE_DIR)/segment2/custom/*.png) +SEGMENT2_TEXTURES := $(wildcard $(TEXTURE_DIR)/segment2/*.png) $(wildcard $(TEXTURE_DIR)/segment2/custom/*.png) $(wildcard $(TEXTURE_DIR)/segment2/predone/*.png) TITLE_SCREEN_BG_TEXTURES := $(wildcard $(TEXTURE_DIR)/title_screen_bg/*.png) SPOOKY_TEXTURES := $(wildcard $(TEXTURE_DIR)/spooky/*.png) GENERIC_TEXTURES := $(wildcard $(TEXTURE_DIR)/generic/*.png) @@ -268,9 +274,9 @@ $(BUILD_DIR)/bin/mountain.elf: SEGMENT_ADDRESS := 0x09000000 $(BUILD_DIR)/bin/grass.elf: SEGMENT_ADDRESS := 0x09000000 # EU segment 19 translations -$(BUILD_DIR)/bin/eu/translation_de.elf: SEGMENT_ADDRESS := 0x19000000 -$(BUILD_DIR)/bin/eu/translation_en.elf: SEGMENT_ADDRESS := 0x19000000 -$(BUILD_DIR)/bin/eu/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000 +$(BUILD_DIR)/bin/translation_de.elf: SEGMENT_ADDRESS := 0x19000000 +$(BUILD_DIR)/bin/translation_en.elf: SEGMENT_ADDRESS := 0x19000000 +$(BUILD_DIR)/bin/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000 # -------------------------------------- # Skybox Rules diff --git a/assets.json b/assets.json index 177c3cb2b..b058b974d 100644 --- a/assets.json +++ b/assets.json @@ -868,9 +868,6 @@ "levels/menu/main_menu_seg7_eu.0AF80.ia8.png": [8,8,64,{"eu":[2647072,44928]}], "levels/menu/main_menu_seg7_eu.0B640.ia8.png": [8,8,64,{"eu":[2647072,46656]}], "levels/menu/main_menu_seg7_eu.0B680.ia8.png": [8,8,64,{"eu":[2647072,46720]}], -"levels/menu/main_menu_seg7_eu.0B840.ia8.png": [8,8,64,{"eu":[2647072,47168]}], -"levels/menu/main_menu_seg7_eu.0B880.ia8.png": [8,8,64,{"eu":[2647072,47232]}], -"levels/menu/main_menu_seg7_eu.0B8C0.ia8.png": [8,8,64,{"eu":[2647072,47296]}], "levels/menu/main_menu_seg7_eu.0BDA0.rgba16.png": [64,32,4096,{"eu":[2647072,48544]}], "levels/menu/main_menu_seg7_eu.0CDA0.rgba16.png": [64,32,4096,{"eu":[2647072,52640]}], "levels/menu/main_menu_seg7_eu.0DDA0.rgba16.png": [64,32,4096,{"eu":[2647072,56736]}], @@ -1561,8 +1558,6 @@ "textures/segment2/segment2.05800.rgba16.png": [16,16,512,{"jp":[1078992,22528],"us":[1083968,17408],"eu":[909712,18944],"sh":[934640,22528]}], "textures/segment2/segment2.05A00.rgba16.png": [16,16,512,{"jp":[1078992,23040],"us":[1083968,17920],"eu":[909712,19456],"sh":[934640,23040]}], "textures/segment2/segment2.05C00.rgba16.png": [16,16,512,{"jp":[1078992,23552],"us":[1083968,18432],"eu":[909712,19968],"sh":[934640,23552]}], -"textures/segment2/segment2.05E00.rgba16.png": [16,16,512,{"jp":[1078992,24064],"sh":[934640,24064]}], -"textures/segment2/segment2.06000.rgba16.png": [16,16,512,{"jp":[1078992,24576],"sh":[934640,24576]}], "textures/segment2/segment2.06200.rgba16.png": [8,8,128,{"jp":[1078992,25088],"us":[1083968,18944],"eu":[909712,20480],"sh":[934640,25088]}], "textures/segment2/segment2.06280.rgba16.png": [8,8,128,{"jp":[1078992,25216],"us":[1083968,19072],"eu":[909712,20608],"sh":[934640,25216]}], "textures/segment2/segment2.06300.rgba16.png": [8,8,128,{"jp":[1078992,25344],"us":[1083968,19200],"eu":[909712,20736],"sh":[934640,25344]}], @@ -1773,7 +1768,6 @@ "textures/segment2/segment2.13458.ia16.png": [32,32,2048,{"jp":[1078992,78936],"us":[1083968,90808],"eu":[909712,47480],"sh":[934640,78936]}], "textures/segment2/segment2.13C58.rgba16.png": [32,32,2048,{"jp":[1078992,80984],"us":[1083968,92856],"eu":[909712,49528],"sh":[934640,80984]}], "textures/segment2/segment2.14838.ia8.png": [8,8,64,{"jp":[1078992,84024],"us":[1083968,95896],"eu":[909712,52568],"sh":[934640,84024]}], -"textures/segment2/segment2.umlaut.rgba16.png": [16,16,512,{"eu":[909712,17920]}], "textures/segment2/shadow_quarter_circle.ia8.png": [16,16,256,{"jp":[1078992,62040],"us":[1083968,73912],"eu":[909712,30584],"sh":[934640,62040]}], "textures/segment2/shadow_quarter_square.ia8.png": [16,16,256,{"jp":[1078992,62296],"us":[1083968,74168],"eu":[909712,30840],"sh":[934640,62296]}], "textures/sky/metal_hole.rgba16.png": [32,32,2048,{"jp":[3390640,26624],"us":[3397392,26624],"eu":[3270992,26624],"sh":[3245360,26624]}], diff --git a/bin/eu/translation_de.c b/bin/eu/translation_de.c deleted file mode 100644 index d7c1f5970..000000000 --- a/bin/eu/translation_de.c +++ /dev/null @@ -1,15 +0,0 @@ -// SM64 (EU) Segment 19 - Deutsch - -#include "macros.h" - -#include "game/ingame_menu.h" - -#include "make_const_nonconst.h" - -// Include text/define_text.inc.c, preprocessed with -I text/de/ to get the -// right translation strings, with symbols renamed as below. -#define seg2_course_name_table course_name_table_eu_de -#define seg2_act_name_table act_name_table_eu_de -#define seg2_dialog_table dialog_table_eu_de - -#include "text/de/define_text.inc.c" diff --git a/bin/eu/translation_en.c b/bin/eu/translation_en.c deleted file mode 100644 index 9817bc5a0..000000000 --- a/bin/eu/translation_en.c +++ /dev/null @@ -1,15 +0,0 @@ -// SM64 (EU) Segment 19 - English - -#include "macros.h" - -#include "game/ingame_menu.h" - -#include "make_const_nonconst.h" - -// Include text/define_text.inc.c, preprocessed with -I text/us/ to get the -// right translation strings, with symbols renamed as below. -#define seg2_course_name_table course_name_table_eu_en -#define seg2_act_name_table act_name_table_eu_en -#define seg2_dialog_table dialog_table_eu_en - -#include "text/us/define_text.inc.c" diff --git a/bin/eu/translation_fr.c b/bin/eu/translation_fr.c deleted file mode 100644 index 119839c93..000000000 --- a/bin/eu/translation_fr.c +++ /dev/null @@ -1,15 +0,0 @@ -// SM64 (EU) Segment 19 - Français - -#include "macros.h" - -#include "game/ingame_menu.h" - -#include "make_const_nonconst.h" - -// Include text/define_text.inc.c, preprocessed with -I text/fr/ to get the -// right translation strings, with symbols renamed as below. -#define seg2_course_name_table course_name_table_eu_fr -#define seg2_act_name_table act_name_table_eu_fr -#define seg2_dialog_table dialog_table_eu_fr - -#include "text/fr/define_text.inc.c" diff --git a/bin/segment2.c b/bin/segment2.c index 1a9527855..8e69bc4c2 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -87,7 +87,7 @@ ALIGNED8 static const Texture texture_hud_char_I[] = { }; ALIGNED8 static const Texture texture_hud_char_J[] = { -#include "textures/segment2/custom/segment2.02600.rgba16.inc.c" +#include "textures/segment2/predone/segment2.02600.rgba16.inc.c" }; ALIGNED8 static const Texture texture_hud_char_K[] = { @@ -115,7 +115,7 @@ ALIGNED8 static const Texture texture_hud_char_P[] = { }; ALIGNED8 static const Texture texture_hud_char_Q[] = { -#include "textures/segment2/custom/segment2.03400.rgba16.inc.c" +#include "textures/segment2/predone/segment2.03400.rgba16.inc.c" }; ALIGNED8 static const Texture texture_hud_char_R[] = { @@ -135,7 +135,7 @@ ALIGNED8 static const Texture texture_hud_char_U[] = { }; ALIGNED8 static const Texture texture_hud_char_V[] = { -#include "textures/segment2/custom/segment2.03E00.rgba16.inc.c" +#include "textures/segment2/predone/segment2.03E00.rgba16.inc.c" }; ALIGNED8 static const Texture texture_hud_char_W[] = { @@ -143,7 +143,7 @@ ALIGNED8 static const Texture texture_hud_char_W[] = { }; ALIGNED8 static const Texture texture_hud_char_X[] = { -#include "textures/segment2/custom/segment2.04200.rgba16.inc.c" +#include "textures/segment2/predone/segment2.04200.rgba16.inc.c" }; ALIGNED8 static const Texture texture_hud_char_Y[] = { @@ -151,7 +151,7 @@ ALIGNED8 static const Texture texture_hud_char_Y[] = { }; ALIGNED8 static const Texture texture_hud_char_Z[] = { -#include "textures/segment2/custom/segment2.04600.rgba16.inc.c" +#include "textures/segment2/predone/segment2.04600.rgba16.inc.c" }; ALIGNED8 static const Texture texture_hud_char_apostrophe[] = { @@ -162,30 +162,28 @@ ALIGNED8 static const Texture texture_hud_char_double_quote[] = { #include "textures/segment2/segment2.04A00.rgba16.inc.c" }; -#ifdef VERSION_EU -ALIGNED8 static const Texture texture_hud_char_umlaut[] = { -#include "textures/segment2/segment2.umlaut.rgba16.inc.c"// EU ¨ +ALIGNED8 const Texture texture_hud_char_umlaut[] = { +#include "textures/segment2/predone/segment2.umlaut.rgba16.inc.c"// EU ¨ }; -#endif ALIGNED8 static const Texture texture_hud_char_exclamation[] = { -#include "textures/segment2/custom/segment2.04C00.rgba16.inc.c"// JP ! +#include "textures/segment2/predone/segment2.04C00.rgba16.inc.c"// JP ! }; ALIGNED8 static const Texture texture_hud_char_double_exclamation[] = { -#include "textures/segment2/custom/segment2.04E00.rgba16.inc.c"// JP !! +#include "textures/segment2/predone/segment2.04E00.rgba16.inc.c"// JP !! }; ALIGNED8 static const Texture texture_hud_char_question[] = { -#include "textures/segment2/custom/segment2.05000.rgba16.inc.c"// JP ? +#include "textures/segment2/predone/segment2.05000.rgba16.inc.c"// JP ? }; ALIGNED8 static const Texture texture_hud_char_ampersand[] = { -#include "textures/segment2/custom/segment2.05200.rgba16.inc.c"// JP & +#include "textures/segment2/predone/segment2.05200.rgba16.inc.c"// JP & }; ALIGNED8 static const Texture texture_hud_char_percent[] = { -#include "textures/segment2/custom/segment2.05400.rgba16.inc.c"// JP % +#include "textures/segment2/predone/segment2.05400.rgba16.inc.c"// JP % }; ALIGNED8 static const Texture texture_hud_char_multiply[] = { @@ -204,23 +202,23 @@ ALIGNED8 static const Texture texture_hud_char_star[] = { #include "textures/segment2/segment2.05C00.rgba16.inc.c" }; -#if defined(VERSION_JP) || defined(VERSION_SH) -ALIGNED8 static const Texture texture_hud_char_decimal_point[] = { -#include "textures/segment2/segment2.05E00.rgba16.inc.c" +ALIGNED8 static const Texture texture_hud_char_circle_fill[] = { +#include "textures/segment2/predone/segment2.05E00.rgba16.inc.c" }; -#endif -#if defined(VERSION_JP) || defined(VERSION_SH) ALIGNED8 static const Texture texture_hud_char_beta_key[] = { -#include "textures/segment2/segment2.06000.rgba16.inc.c" +#include "textures/segment2/predone/segment2.06000.rgba16.inc.c" }; -#endif -#ifdef BETTERCAMERA -ALIGNED8 const Texture texture_hud_char_puppycam[] = { -#include "textures/segment2/custom/tex_puppycam_icon.rgba16.inc.c" +// Custom fonts + +ALIGNED8 static const Texture texture_hud_char_decimal_point[] = { +#include "textures/segment2/custom/tex_decimal_point.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_minus[] = { +#include "textures/segment2/custom/tex_minus.rgba16.inc.c" }; -#endif #if !CREDITS_TEXT_STRING_FONT ALIGNED8 static const Texture texture_credits_char_3[] = { @@ -345,7 +343,7 @@ ALIGNED8 static const Texture texture_credits_char_period[] = { #endif // JP Small Font -#if defined(VERSION_JP) || defined(VERSION_SH) +#ifdef JAPANESE_CHARACTERS ALIGNED8 static const Texture texture_font_char_jp_0[] = { #include "textures/segment2/segment2.07100.ia1.inc.c" }; @@ -502,7 +500,7 @@ ALIGNED8 static const Texture texture_font_char_jp_dakuten[] = { #include "textures/segment2/segment2.07360.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_handakuten[] = { +ALIGNED8 static const Texture texture_font_char_jp_period[] = { #include "textures/segment2/segment2.07370.ia1.inc.c" }; @@ -514,37 +512,37 @@ ALIGNED8 static const Texture texture_font_char_jp_question[] = { #include "textures/segment2/segment2.07390.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_left_right_arrow[] = { -#include "textures/segment2/segment2.073A0.ia1.inc.c" -}; +//ALIGNED8 static const Texture texture_font_char_jp_left_right_arrow[] = { +//#include "textures/segment2/segment2.073A0.ia1.inc.c" +//}; ALIGNED8 static const Texture texture_font_char_jp_open_parentheses[] = { #include "textures/segment2/segment2.073B0.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_close_open_parentheses[] = { -#include "textures/segment2/segment2.073C0.ia1.inc.c" -}; +//ALIGNED8 static const Texture texture_font_char_jp_close_open_parentheses[] = { +//#include "textures/segment2/segment2.073C0.ia1.inc.c" +//}; ALIGNED8 static const Texture texture_font_char_jp_close_parentheses[] = { #include "textures/segment2/segment2.073D0.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_coin[] = { -#include "textures/segment2/segment2.073E0.ia1.inc.c" -}; +//ALIGNED8 static const Texture texture_font_char_jp_coin[] = { +//#include "textures/segment2/segment2.073E0.ia1.inc.c" +//}; ALIGNED8 static const Texture texture_font_char_jp_multiply[] = { #include "textures/segment2/segment2.073F0.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_star_filled[] = { -#include "textures/segment2/segment2.07400.ia1.inc.c" -}; +//ALIGNED8 static const Texture texture_font_char_jp_star_filled[] = { +//#include "textures/segment2/segment2.07400.ia1.inc.c" +//}; -ALIGNED8 static const Texture texture_font_char_jp_star_hollow[] = { -#include "textures/segment2/segment2.07410.ia1.inc.c" -}; +//ALIGNED8 static const Texture texture_font_char_jp_star_hollow[] = { +//#include "textures/segment2/segment2.07410.ia1.inc.c" +//}; ALIGNED8 static const Texture texture_font_char_jp_hiragana_a[] = { #include "textures/segment2/segment2.07420.ia1.inc.c" @@ -558,7 +556,7 @@ ALIGNED8 static const Texture texture_font_char_jp_hiragana_u[] = { #include "textures/segment2/segment2.07440.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_hiragana_c[] = { +ALIGNED8 static const Texture texture_font_char_jp_hiragana_e[] = { #include "textures/segment2/segment2.07450.ia1.inc.c" }; @@ -654,7 +652,7 @@ ALIGNED8 static const Texture texture_font_char_jp_hiragana_hi[] = { #include "textures/segment2/segment2.075C0.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_hiragana_hu[] = { +ALIGNED8 static const Texture texture_font_char_jp_hiragana_fu[] = { #include "textures/segment2/segment2.075D0.ia1.inc.c" }; @@ -882,7 +880,7 @@ ALIGNED8 static const Texture texture_font_char_jp_katakana_hi[] = { #include "textures/segment2/segment2.07950.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_katakana_hu[] = { +ALIGNED8 static const Texture texture_font_char_jp_katakana_fu[] = { #include "textures/segment2/segment2.07960.ia1.inc.c" }; @@ -998,15 +996,17 @@ ALIGNED8 static const Texture texture_font_char_jp_double_quotation_close[] = { #include "textures/segment2/segment2.07B20.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_wave_dash[] = { +ALIGNED8 static const Texture texture_font_char_jp_tilde[] = { #include "textures/segment2/segment2.07B30.ia1.inc.c" }; -ALIGNED8 static const Texture texture_font_char_jp_ellipsis[] = { -#include "textures/segment2/segment2.07B40.ia1.inc.c" -}; +//ALIGNED8 static const Texture texture_font_char_jp_ellipsis[] = { +//#include "textures/segment2/segment2.07B40.ia1.inc.c" +//}; +#endif // EU Small Font +/** #elif defined(VERSION_EU) ALIGNED8 static const Texture texture_font_char_eu_0[] = { @@ -1408,9 +1408,9 @@ ALIGNED8 static const Texture texture_font_char_eu_Cedilla[] = { ALIGNED8 static const Texture texture_font_char_eu_eszeet[] = { #include "textures/segment2/font_graphics.06530.ia1.inc.c" }; - + */ // US Small Font -#else +//#else ALIGNED8 static const Texture texture_font_char_us_0[] = { #include "textures/segment2/font_graphics.05900.ia4.inc.c" }; @@ -1679,9 +1679,9 @@ ALIGNED8 static const Texture texture_font_char_us_open_parentheses[] = { #include "textures/segment2/font_graphics.06980.ia4.inc.c" }; -ALIGNED8 static const Texture texture_font_char_us_close_open_parentheses[] = { -#include "textures/segment2/font_graphics.069C0.ia4.inc.c" -}; +//ALIGNED8 static const Texture texture_font_char_us_close_open_parentheses[] = { +//#include "textures/segment2/font_graphics.069C0.ia4.inc.c" +//}; ALIGNED8 static const Texture texture_font_char_us_close_parentheses[] = { #include "textures/segment2/font_graphics.06A00.ia4.inc.c" @@ -1731,11 +1731,11 @@ ALIGNED8 static const Texture texture_font_char_us_double_quote_close[] = { #include "textures/segment2/font_graphics.06CC0.ia4.inc.c" }; -ALIGNED8 static const Texture texture_font_char_us_ellipsis[] = { +ALIGNED8 static const Texture texture_font_char_us_colon[] = { #include "textures/segment2/font_graphics.06D00.ia4.inc.c" }; -ALIGNED8 static const Texture texture_font_char_us_slash[] = { +ALIGNED8 static const Texture texture_font_char_us_hyphen[] = { #include "textures/segment2/font_graphics.06D40.ia4.inc.c" }; @@ -1778,7 +1778,68 @@ ALIGNED8 static const Texture texture_font_char_us_button_C_left[] = { ALIGNED8 static const Texture texture_font_char_us_button_C_right[] = { #include "textures/segment2/font_graphics.06FC0.ia4.inc.c" }; -#endif +//#endif + +// Custom Font +ALIGNED8 static const Texture texture_font_char_plus[] = { +#include "textures/segment2/custom/font_graphics.plus.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_slash[] = { +#include "textures/segment2/custom/font_graphics.slash.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_backslash[] = { +#include "textures/segment2/custom/font_graphics.backslash.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_inverted_exclamation_mark[] = { +#include "textures/segment2/custom/font_graphics.inverted_exclamation_mark.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_inverted_question_mark[] = { +#include "textures/segment2/custom/font_graphics.inverted_question_mark.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_us_double_low_quote[] = { +#include "textures/segment2/custom/font_graphics.double_low_quote.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_eszett[] = { +#include "textures/segment2/custom/font_graphics.eszett.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_diacritic_grave[] = { +#include "textures/segment2/custom/font_graphics.grave.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_diacritic_acute[] = { +#include "textures/segment2/custom/font_graphics.acute.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_diacritic_circumflex[] = { +#include "textures/segment2/custom/font_graphics.circumflex.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_diacritic_tilde[] = { +#include "textures/segment2/custom/font_graphics.tilde_diacritic.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_diacritic_umlaut[] = { +#include "textures/segment2/custom/font_graphics.umlaut.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_diacritic_cedilla[] = { +#include "textures/segment2/custom/font_graphics.cedilla.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_us_i_no_dot[] = { +#include "textures/segment2/custom/font_graphics.i_no_dot.ia4.inc.c" +}; + +ALIGNED8 static const Texture texture_font_missing_character[] = { +#include "textures/segment2/custom/font_graphics.missing_character.ia4.inc.c" +}; ALIGNED8 static const Texture texture_hud_char_camera[] = { #include "textures/segment2/segment2.07B50.rgba16.inc.c" @@ -1800,274 +1861,874 @@ ALIGNED8 static const Texture texture_hud_char_arrow_down[] = { #include "textures/segment2/segment2.081D0.rgba16.inc.c" }; -// Main HUD print table 0x02008250-0x02008337 -const Texture *const main_hud_lut[] = { -#ifdef VERSION_EU - texture_hud_char_0, texture_hud_char_1, texture_hud_char_2, texture_hud_char_3, - texture_hud_char_4, texture_hud_char_5, texture_hud_char_6, texture_hud_char_7, - texture_hud_char_8, texture_hud_char_9, texture_hud_char_A, texture_hud_char_B, - texture_hud_char_C, texture_hud_char_D, texture_hud_char_E, texture_hud_char_F, - texture_hud_char_G, texture_hud_char_H, texture_hud_char_I, texture_hud_char_J, - texture_hud_char_K, texture_hud_char_L, texture_hud_char_M, texture_hud_char_N, - texture_hud_char_O, texture_hud_char_P, texture_hud_char_Q, texture_hud_char_R, - texture_hud_char_S, texture_hud_char_T, texture_hud_char_U, texture_hud_char_V, - texture_hud_char_W, texture_hud_char_X, texture_hud_char_Y, texture_hud_char_Z, - texture_hud_char_exclamation, texture_hud_char_double_exclamation, texture_hud_char_question, texture_hud_char_ampersand, - texture_hud_char_percent, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, texture_hud_char_multiply, texture_hud_char_coin, - texture_hud_char_mario_head, texture_hud_char_star, 0x0, 0x0, - texture_hud_char_apostrophe, texture_hud_char_double_quote, texture_hud_char_umlaut, -#elif defined(VERSION_US) - texture_hud_char_0, texture_hud_char_1, texture_hud_char_2, texture_hud_char_3, - texture_hud_char_4, texture_hud_char_5, texture_hud_char_6, texture_hud_char_7, - texture_hud_char_8, texture_hud_char_9, texture_hud_char_A, texture_hud_char_B, - texture_hud_char_C, texture_hud_char_D, texture_hud_char_E, texture_hud_char_F, - texture_hud_char_G, texture_hud_char_H, texture_hud_char_I, texture_hud_char_J, - texture_hud_char_K, texture_hud_char_L, texture_hud_char_M, texture_hud_char_N, - texture_hud_char_O, texture_hud_char_P, texture_hud_char_Q, texture_hud_char_R, - texture_hud_char_S, texture_hud_char_T, texture_hud_char_U, texture_hud_char_V, - texture_hud_char_W, texture_hud_char_X, texture_hud_char_Y, texture_hud_char_Z, - texture_hud_char_exclamation, texture_hud_char_double_exclamation, texture_hud_char_question, texture_hud_char_ampersand, - texture_hud_char_percent, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, texture_hud_char_multiply, texture_hud_char_coin, - texture_hud_char_mario_head, texture_hud_char_star, 0x0, 0x0, - texture_hud_char_apostrophe, texture_hud_char_double_quote, -#else - texture_hud_char_0, texture_hud_char_1, texture_hud_char_2, texture_hud_char_3, - texture_hud_char_4, texture_hud_char_5, texture_hud_char_6, texture_hud_char_7, - texture_hud_char_8, texture_hud_char_9, texture_hud_char_A, texture_hud_char_B, - texture_hud_char_C, texture_hud_char_D, texture_hud_char_E, texture_hud_char_F, - texture_hud_char_G, texture_hud_char_H, texture_hud_char_I, texture_hud_char_J, - texture_hud_char_K, texture_hud_char_L, texture_hud_char_M, texture_hud_char_N, - texture_hud_char_O, texture_hud_char_P, texture_hud_char_Q, texture_hud_char_R, - texture_hud_char_S, texture_hud_char_T, texture_hud_char_U, texture_hud_char_V, - texture_hud_char_W, texture_hud_char_X, texture_hud_char_Y, texture_hud_char_Z, - texture_hud_char_exclamation, texture_hud_char_double_exclamation, texture_hud_char_question, texture_hud_char_ampersand, - texture_hud_char_percent, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, texture_hud_char_multiply, texture_hud_char_coin, - texture_hud_char_mario_head, texture_hud_char_star, texture_hud_char_decimal_point, texture_hud_char_beta_key, - texture_hud_char_apostrophe, texture_hud_char_double_quote, +#ifdef BETTERCAMERA +ALIGNED8 const Texture texture_hud_char_puppycam[] = { +#include "textures/segment2/custom/tex_puppycam_icon.rgba16.inc.c" +}; #endif + +// Moved from menu segment 7 to segment 2 to be unified with rest of HUD font +#ifdef JAPANESE_CHARACTERS +ALIGNED8 static const Texture texture_hud_char_katakana_fu[] = { +#include "levels/menu/main_menu_seg7.073D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_small_a[] = { +#include "levels/menu/main_menu_seg7.075D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_i[] = { +#include "levels/menu/main_menu_seg7.077D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_ru[] = { +#include "levels/menu/main_menu_seg7.079D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_se[] = { +#include "levels/menu/main_menu_seg7.07BD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_re[] = { +#include "levels/menu/main_menu_seg7.07DD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_ku[] = { +#include "levels/menu/main_menu_seg7.07FD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_to[] = { +#include "levels/menu/main_menu_seg7.081D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_hiragana_wo[] = { +#include "levels/menu/main_menu_seg7.083D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_ko[] = { +#include "levels/menu/main_menu_seg7.085D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_kana_handakuten_pi[] = { +#include "levels/menu/main_menu_seg7.087D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_long_vowel[] = { +#include "levels/menu/main_menu_seg7.089D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_hiragana_su[] = { +#include "levels/menu/main_menu_seg7.08BD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_hiragana_ru[] = { +#include "levels/menu/main_menu_seg7.08DD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_hiragana_ke[] = { +#include "levels/menu/main_menu_seg7.08FD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_ma[] = { +#include "levels/menu/main_menu_seg7.091D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_ri[] = { +#include "levels/menu/main_menu_seg7.093D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_o[] = { +#include "levels/menu/main_menu_seg7.095D0.rgba16.inc.c" }; -// Main small font print table 0x02008338-0x02008737 -const Texture *const main_font_lut[] = { -#ifdef VERSION_EU // EU Font Table - texture_font_char_eu_0, texture_font_char_eu_1, texture_font_char_eu_2, texture_font_char_eu_3, - texture_font_char_eu_4, texture_font_char_eu_5, texture_font_char_eu_6, texture_font_char_eu_7, - texture_font_char_eu_8, texture_font_char_eu_9, texture_font_char_eu_A, texture_font_char_eu_B, - texture_font_char_eu_C, texture_font_char_eu_D, texture_font_char_eu_E, texture_font_char_eu_F, - texture_font_char_eu_G, texture_font_char_eu_H, texture_font_char_eu_I, texture_font_char_eu_J, - texture_font_char_eu_K, texture_font_char_eu_L, texture_font_char_eu_M, texture_font_char_eu_N, - texture_font_char_eu_O, texture_font_char_eu_P, texture_font_char_eu_Q, texture_font_char_eu_R, - texture_font_char_eu_S, texture_font_char_eu_T, texture_font_char_eu_U, texture_font_char_eu_V, - texture_font_char_eu_W, texture_font_char_eu_X, texture_font_char_eu_Y, texture_font_char_eu_Z, - texture_font_char_eu_a, texture_font_char_eu_b, texture_font_char_eu_c, texture_font_char_eu_d, - texture_font_char_eu_e, texture_font_char_eu_f, texture_font_char_eu_g, texture_font_char_eu_h, - texture_font_char_eu_i, texture_font_char_eu_j, texture_font_char_eu_k, texture_font_char_eu_l, - texture_font_char_eu_m, texture_font_char_eu_n, texture_font_char_eu_o, texture_font_char_eu_p, - texture_font_char_eu_q, texture_font_char_eu_r, texture_font_char_eu_s, texture_font_char_eu_t, - texture_font_char_eu_u, texture_font_char_eu_v, texture_font_char_eu_w, texture_font_char_eu_x, - texture_font_char_eu_y, texture_font_char_eu_z, texture_font_char_eu_apostrophe, texture_font_char_eu_period, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - texture_font_char_eu_button_C_up, - texture_font_char_eu_button_C_down, - texture_font_char_eu_button_C_left, - texture_font_char_eu_button_C_right, - texture_font_char_eu_button_A, - texture_font_char_eu_button_B, - texture_font_char_eu_button_C, - texture_font_char_eu_button_Z, - texture_font_char_eu_button_R, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - texture_font_char_eu_comma, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - texture_font_char_EU_slash, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - texture_font_char_eu_open_parentheses, - texture_font_char_eu_close_open_parentheses, - texture_font_char_eu_close_parentheses, - texture_font_char_eu_left_right_arrow, - texture_font_char_eu_ampersand, - texture_font_char_eu_colon, - texture_font_char_eu_acute, - texture_font_char_eu_circumflex, - texture_font_char_eu_umlaut, - texture_font_char_eu_grave, - texture_font_char_eu_unknown, - texture_font_char_eu_eszeet, - texture_font_char_eu_Cedilla, - texture_font_char_eu_cedilla, - 0x0, 0x0, 0x0, - texture_font_char_eu_exclamation, - texture_font_char_eu_percent, - texture_font_char_eu_question, - texture_font_char_eu_double_quote_open, - texture_font_char_eu_double_quote_close, - texture_font_char_eu_tilde, - 0x0, - texture_font_char_eu_coin, - texture_font_char_eu_star_filled, - texture_font_char_eu_multiply, - texture_font_char_eu_interpunct, - texture_font_char_eu_star_hollow, - 0x0, 0x0, -#elif defined(VERSION_US) // US Font Table - texture_font_char_us_0, texture_font_char_us_1, texture_font_char_us_2, texture_font_char_us_3, - texture_font_char_us_4, texture_font_char_us_5, texture_font_char_us_6, texture_font_char_us_7, - texture_font_char_us_8, texture_font_char_us_9, texture_font_char_us_A, texture_font_char_us_B, - texture_font_char_us_C, texture_font_char_us_D, texture_font_char_us_E, texture_font_char_us_F, - texture_font_char_us_G, texture_font_char_us_H, texture_font_char_us_I, texture_font_char_us_J, - texture_font_char_us_K, texture_font_char_us_L, texture_font_char_us_M, texture_font_char_us_N, - texture_font_char_us_O, texture_font_char_us_P, texture_font_char_us_Q, texture_font_char_us_R, - texture_font_char_us_S, texture_font_char_us_T, texture_font_char_us_U, texture_font_char_us_V, - texture_font_char_us_W, texture_font_char_us_X, texture_font_char_us_Y, texture_font_char_us_Z, - texture_font_char_us_a, texture_font_char_us_b, texture_font_char_us_c, texture_font_char_us_d, - texture_font_char_us_e, texture_font_char_us_f, texture_font_char_us_g, texture_font_char_us_h, - texture_font_char_us_i, texture_font_char_us_j, texture_font_char_us_k, texture_font_char_us_l, - texture_font_char_us_m, texture_font_char_us_n, texture_font_char_us_o, texture_font_char_us_p, - texture_font_char_us_q, texture_font_char_us_r, texture_font_char_us_s, texture_font_char_us_t, - texture_font_char_us_u, texture_font_char_us_v, texture_font_char_us_w, texture_font_char_us_x, - texture_font_char_us_y, texture_font_char_us_z, texture_font_char_us_apostrophe, texture_font_char_us_period, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - texture_font_char_us_button_C_up, texture_font_char_us_button_C_down, texture_font_char_us_button_C_left, texture_font_char_us_button_C_right, - texture_font_char_us_button_A, texture_font_char_us_button_B, texture_font_char_us_button_C, texture_font_char_us_button_Z, - texture_font_char_us_button_R, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, texture_font_char_us_comma, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, texture_font_char_us_slash, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, texture_font_char_us_open_parentheses, texture_font_char_us_close_open_parentheses, texture_font_char_us_close_parentheses, - texture_font_char_us_left_right_arrow, texture_font_char_us_ampersand, texture_font_char_us_ellipsis, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, texture_font_char_us_exclamation, texture_font_char_us_percent, - texture_font_char_us_question, texture_font_char_us_double_quote_open, texture_font_char_us_double_quote_close, texture_font_char_us_tilde, - 0x0, texture_font_char_us_coin, texture_font_char_us_star_filled, texture_font_char_us_multiply, - texture_font_char_us_interpunct, texture_font_char_us_star_hollow, 0x0, 0x0, -#elif defined(VERSION_JP) || defined(VERSION_SH) - texture_font_char_jp_0, texture_font_char_jp_1, texture_font_char_jp_2, texture_font_char_jp_3, - texture_font_char_jp_4, texture_font_char_jp_5, texture_font_char_jp_6, texture_font_char_jp_7, - texture_font_char_jp_8, texture_font_char_jp_9, texture_font_char_jp_A, texture_font_char_jp_B, - texture_font_char_jp_C, texture_font_char_jp_D, texture_font_char_jp_E, texture_font_char_jp_F, - texture_font_char_jp_G, texture_font_char_jp_H, texture_font_char_jp_I, texture_font_char_jp_J, - texture_font_char_jp_K, texture_font_char_jp_L, texture_font_char_jp_M, texture_font_char_jp_N, - texture_font_char_jp_O, texture_font_char_jp_P, texture_font_char_jp_Q, texture_font_char_jp_R, - texture_font_char_jp_S, texture_font_char_jp_T, texture_font_char_jp_U, texture_font_char_jp_V, - texture_font_char_jp_W, texture_font_char_jp_X, texture_font_char_jp_Y, texture_font_char_jp_Z, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - texture_font_char_jp_hiragana_a, texture_font_char_jp_hiragana_i, texture_font_char_jp_hiragana_u, texture_font_char_jp_hiragana_c, - texture_font_char_jp_hiragana_o, texture_font_char_jp_hiragana_ka, texture_font_char_jp_hiragana_ki, texture_font_char_jp_hiragana_ku, - texture_font_char_jp_hiragana_ke, texture_font_char_jp_hiragana_ko, texture_font_char_jp_hiragana_sa, texture_font_char_jp_hiragana_shi, - texture_font_char_jp_hiragana_su, texture_font_char_jp_hiragana_se, texture_font_char_jp_hiragana_so, texture_font_char_jp_hiragana_ta, - texture_font_char_jp_hiragana_chi, texture_font_char_jp_hiragana_tsu, texture_font_char_jp_hiragana_te, texture_font_char_jp_hiragana_to, - texture_font_char_jp_hiragana_na, texture_font_char_jp_hiragana_ni, texture_font_char_jp_hiragana_nu, texture_font_char_jp_hiragana_ne, - texture_font_char_jp_hiragana_no, texture_font_char_jp_hiragana_ha, texture_font_char_jp_hiragana_hi, texture_font_char_jp_hiragana_hu, - texture_font_char_jp_hiragana_he, texture_font_char_jp_hiragana_ho, texture_font_char_jp_hiragana_ma, texture_font_char_jp_hiragana_mi, - texture_font_char_jp_hiragana_mu, texture_font_char_jp_hiragana_me, texture_font_char_jp_hiragana_mo, texture_font_char_jp_hiragana_ya, - texture_font_char_jp_hiragana_yu, texture_font_char_jp_hiragana_yo, texture_font_char_jp_hiragana_ra, texture_font_char_jp_hiragana_ri, - texture_font_char_jp_hiragana_ru, texture_font_char_jp_hiragana_re, texture_font_char_jp_hiragana_ro, texture_font_char_jp_hiragana_wa, - texture_font_char_jp_hiragana_wo, texture_font_char_jp_hiragana_n, 0x0, texture_font_char_jp_comma, - texture_font_char_jp_katakana_a, texture_font_char_jp_katakana_i, texture_font_char_jp_katakana_u, texture_font_char_jp_katakana_e, - texture_font_char_jp_katakana_o, texture_font_char_jp_katakana_ka, texture_font_char_jp_katakana_ki, texture_font_char_jp_katakana_ku, - texture_font_char_jp_katakana_ke, texture_font_char_jp_katakana_ko, texture_font_char_jp_katakana_sa, texture_font_char_jp_katakana_shi, - texture_font_char_jp_katakana_su, texture_font_char_jp_katakana_se, texture_font_char_jp_katakana_so, texture_font_char_jp_katakana_ta, - texture_font_char_jp_katakana_chi, texture_font_char_jp_katakana_tsu, texture_font_char_jp_katakana_te, texture_font_char_jp_katakana_to, - texture_font_char_jp_katakana_na, texture_font_char_jp_katakana_ni, texture_font_char_jp_katakana_nu, texture_font_char_jp_katakana_ne, - texture_font_char_jp_katakana_no, texture_font_char_jp_katakana_ha, texture_font_char_jp_katakana_hi, texture_font_char_jp_katakana_hu, - texture_font_char_jp_katakana_he, texture_font_char_jp_katakana_ho, texture_font_char_jp_katakana_ma, texture_font_char_jp_katakana_mi, - texture_font_char_jp_katakana_mu, texture_font_char_jp_katakana_me, texture_font_char_jp_katakana_mo, texture_font_char_jp_katakana_ya, - texture_font_char_jp_katakana_yu, texture_font_char_jp_katakana_yo, texture_font_char_jp_katakana_ra, texture_font_char_jp_katakana_ri, - texture_font_char_jp_katakana_ru, texture_font_char_jp_katakana_re, texture_font_char_jp_katakana_ro, texture_font_char_jp_katakana_wa, - 0x0, texture_font_char_jp_katakana_n, 0x0, texture_font_char_jp_long_vowel, - texture_font_char_jp_hiragana_small_e, texture_font_char_jp_hiragana_small_tsu, texture_font_char_jp_hiragana_small_ya, texture_font_char_jp_hiragana_small_yu, - texture_font_char_jp_hiragana_small_yo, texture_font_char_jp_hiragana_small_a, texture_font_char_jp_hiragana_small_i, texture_font_char_jp_hiragana_small_u, - texture_font_char_jp_hiragana_small_o, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - texture_font_char_jp_katakana_small_e, texture_font_char_jp_katakana_small_tsu, texture_font_char_jp_katakana_small_ya, texture_font_char_jp_katakana_small_yu, - texture_font_char_jp_katakana_small_yo, texture_font_char_jp_katakana_small_a, texture_font_char_jp_katakana_small_i, texture_font_char_jp_katakana_small_u, - texture_font_char_jp_katakana_small_o, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, texture_font_char_jp_open_parentheses, texture_font_char_jp_close_open_parentheses, texture_font_char_jp_close_parentheses, - texture_font_char_jp_left_right_arrow, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - texture_font_char_jp_dakuten, texture_font_char_jp_handakuten, texture_font_char_jp_exclamation, texture_font_char_jp_percent, - texture_font_char_jp_question, texture_font_char_jp_double_quotation_open, texture_font_char_jp_double_quotation_close, texture_font_char_jp_wave_dash, - texture_font_char_jp_ellipsis, texture_font_char_jp_coin, texture_font_char_jp_star_filled, texture_font_char_jp_multiply, - texture_font_char_jp_interpunct, texture_font_char_jp_star_hollow, 0x0, 0x0, +ALIGNED8 static const Texture texture_hud_char_katakana_su[] = { +#include "levels/menu/main_menu_seg7.097D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_a[] = { +#include "levels/menu/main_menu_seg7.099D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_hiragana_mi[] = { +#include "levels/menu/main_menu_seg7.09BD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_hira_dakuten_do[] = { +#include "levels/menu/main_menu_seg7.09DD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_hiragana_no[] = { +#include "levels/menu/main_menu_seg7.09FD0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_sa[] = { +#include "levels/menu/main_menu_seg7.0A3D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_u[] = { +#include "levels/menu/main_menu_seg7.0A5D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_n[] = { +#include "levels/menu/main_menu_seg7.0A7D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_kana_dakuten_do[] = { +#include "levels/menu/main_menu_seg7.0A9D0.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_katakana_ra[] = { +#include "levels/menu/main_menu_seg7.katakana_ra.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_kana_dakuten_ge[] = { +#include "levels/menu/main_menu_seg7.kana_dakuten_ge.rgba16.inc.c" +}; + +ALIGNED8 static const Texture texture_hud_char_kana_dakuten_ji[] = { +#include "levels/menu/main_menu_seg7.kana_dakuten_ji.rgba16.inc.c" +}; +#endif + +// ASCII lookup table for the colorful HUD font +const struct AsciiCharLUTEntry main_hud_lut[] = { + {NULL, 8}, // 32 " " + {texture_hud_char_exclamation, 12}, // 33 "!" + {texture_hud_char_double_quote, 10}, // 34 "\"" + {NULL, 0}, // 35 "#" (Unimplemented) + {NULL, 0}, // 36 "$" (Unimplemented) + {texture_hud_char_percent, 12}, // 37 "%" + {texture_hud_char_ampersand, 12}, // 38 "&" + {texture_hud_char_apostrophe, 8}, // 39 "'" + {NULL, 0}, // 40 "(" (Unimplemented) + {NULL, 0}, // 41 ")" (Unimplemented) + {NULL, 0}, // 42 "*" (Unimplemented) + {NULL, 0}, // 43 "+" (Unimplemented) + {texture_hud_char_apostrophe, 8}, // 44 "," + {texture_hud_char_minus, 16}, // 45 "-" + {texture_hud_char_decimal_point, 8}, // 46 "." + {NULL, 0}, // 47 "/" (Unimplemented) + {texture_hud_char_0, 12}, // 48 "0" + {texture_hud_char_1, 12}, // 49 "1" + {texture_hud_char_2, 12}, // 50 "2" + {texture_hud_char_3, 12}, // 51 "3" + {texture_hud_char_4, 12}, // 52 "4" + {texture_hud_char_5, 12}, // 53 "5" + {texture_hud_char_6, 12}, // 54 "6" + {texture_hud_char_7, 12}, // 55 "7" + {texture_hud_char_8, 12}, // 56 "8" + {texture_hud_char_9, 12}, // 57 "9" + {NULL, 0}, // 58 ":" (Unimplemented) + {NULL, 0}, // 59 ";" (Unimplemented) + {NULL, 0}, // 60 "<" (Unimplemented) + {NULL, 0}, // 61 "=" (Unimplemented) + {NULL, 0}, // 62 ">" (Unimplemented) + {texture_hud_char_question, 12}, // 63 "?" + {NULL, 0}, // 64 "@" (Unimplemented) + {texture_hud_char_A, 12}, // 65 "A" + {texture_hud_char_B, 12}, // 66 "B" + {texture_hud_char_C, 12}, // 67 "C" + {texture_hud_char_D, 12}, // 68 "D" + {texture_hud_char_E, 12}, // 69 "E" + {texture_hud_char_F, 12}, // 70 "F" + {texture_hud_char_G, 12}, // 71 "G" + {texture_hud_char_H, 12}, // 72 "H" + {texture_hud_char_I, 12}, // 73 "I" + {texture_hud_char_J, 12}, // 74 "J" + {texture_hud_char_K, 12}, // 75 "K" + {texture_hud_char_L, 12}, // 76 "L" + {texture_hud_char_M, 12}, // 77 "M" + {texture_hud_char_N, 12}, // 78 "N" + {texture_hud_char_O, 12}, // 79 "O" + {texture_hud_char_P, 12}, // 80 "P" + {texture_hud_char_Q, 12}, // 81 "Q" + {texture_hud_char_R, 12}, // 82 "R" + {texture_hud_char_S, 12}, // 83 "S" + {texture_hud_char_T, 12}, // 84 "T" + {texture_hud_char_U, 12}, // 85 "U" + {texture_hud_char_V, 12}, // 86 "V" + {texture_hud_char_W, 12}, // 87 "W" + {texture_hud_char_X, 12}, // 88 "X" + {texture_hud_char_Y, 12}, // 89 "Y" + {texture_hud_char_Z, 12}, // 90 "Z" + {NULL, 0}, // 91 "[" (Unimplemented) + {NULL, 0}, // 92 "\\" (Unimplemented) + {NULL, 0}, // 93 "]" (Unimplemented) + {NULL, 0}, // 94 "^" (Unimplemented) + {NULL, 0}, // 95 "_" (Unimplemented) + {NULL, 0}, // 96 "`" (Unimplemented) + {texture_hud_char_A, 12}, // 97 "a" + {texture_hud_char_B, 12}, // 98 "b" + {texture_hud_char_C, 12}, // 99 "c" + {texture_hud_char_D, 12}, // 100 "d" + {texture_hud_char_E, 12}, // 101 "e" + {texture_hud_char_F, 12}, // 102 "f" + {texture_hud_char_G, 12}, // 103 "g" + {texture_hud_char_H, 12}, // 104 "h" + {texture_hud_char_I, 12}, // 105 "i" + {texture_hud_char_J, 12}, // 106 "j" + {texture_hud_char_K, 12}, // 107 "k" + {texture_hud_char_L, 12}, // 108 "l" + {texture_hud_char_M, 12}, // 109 "m" + {texture_hud_char_N, 12}, // 110 "n" + {texture_hud_char_O, 12}, // 111 "o" + {texture_hud_char_P, 12}, // 112 "p" + {texture_hud_char_Q, 12}, // 113 "q" + {texture_hud_char_R, 12}, // 114 "r" + {texture_hud_char_S, 12}, // 115 "s" + {texture_hud_char_T, 12}, // 116 "t" + {texture_hud_char_U, 12}, // 117 "u" + {texture_hud_char_V, 12}, // 118 "v" + {texture_hud_char_W, 12}, // 119 "w" + {texture_hud_char_X, 12}, // 120 "x" + {texture_hud_char_Y, 12}, // 121 "y" + {texture_hud_char_Z, 12}, // 122 "z" + {NULL, 0}, // 123 "{" (Unimplemented) + {NULL, 0}, // 124 "|" (Unimplemented) + {NULL, 0}, // 125 "}" (Unimplemented) + {NULL, 0}, // 126 "~" (Unimplemented) +}; + +// UTF-8 lookup tables for the colorful HUD font +const struct Utf8CharLUTEntry main_hud_utf8_2byte_lut[] = { + {0x00C4, 12, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_hud_char_A}, // Ä + {0x00CB, 12, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_hud_char_E}, // Ë + {0x00CF, 12, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_hud_char_I}, // Ï + {0x00D6, 12, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_hud_char_O}, // Ö + {0x00D7, 15, 0, texture_hud_char_multiply}, // × + {0x00DC, 12, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_hud_char_U}, // Ü +}; + +const struct Utf8CharLUTEntry main_hud_utf8_3byte_lut[] = { + {0x203C, 12, 0, texture_hud_char_double_exclamation}, // ‼ + {0x25CD, 16, 0, texture_hud_char_circle_fill}, // ◍ + {0x2605, 16, 0, texture_hud_char_star}, // ★ + {0x263A, 16, 0, texture_hud_char_mario_head}, // ☺ + {0x26BF, 16, 0, texture_hud_char_beta_key}, // ⚿ + {0x272A, 16, 0, texture_hud_char_coin}, // ✪ + +#ifdef JAPANESE_CHARACTERS + {0x3000, 16, 0, NULL}, // " " (ideographic space) + + {0x3051, 16, 0, texture_hud_char_hiragana_ke}, // け + {0x3059, 16, 0, texture_hud_char_hiragana_su}, // す + {0x3069, 16, 0, texture_hud_char_hira_dakuten_do}, // ど + {0x306E, 16, 0, texture_hud_char_hiragana_no}, // の + {0x307F, 16, 0, texture_hud_char_hiragana_mi}, // み + {0x308B, 16, 0, texture_hud_char_hiragana_ru}, // る + {0x3092, 16, 0, texture_hud_char_hiragana_wo}, // を + + {0x30A1, 16, 0, texture_hud_char_katakana_small_a}, // ァ + {0x30A2, 16, 0, texture_hud_char_katakana_a}, // ア + {0x30A4, 16, 0, texture_hud_char_katakana_i}, // イ + {0x30A6, 16, 0, texture_hud_char_katakana_u}, // ウ + {0x30AA, 16, 0, texture_hud_char_katakana_o}, // オ + {0x30AF, 16, 0, texture_hud_char_katakana_ku}, // ク + {0x30B2, 16, 0, texture_hud_char_kana_dakuten_ge}, // ゲ + {0x30B3, 16, 0, texture_hud_char_katakana_ko}, // コ + {0x30B5, 16, 0, texture_hud_char_katakana_sa}, // サ + {0x30B8, 16, 0, texture_hud_char_kana_dakuten_ji}, // ジ + {0x30B9, 16, 0, texture_hud_char_katakana_su}, // ス + {0x30BB, 16, 0, texture_hud_char_katakana_se}, // セ + {0x30C8, 16, 0, texture_hud_char_katakana_to}, // ト + {0x30C9, 16, 0, texture_hud_char_kana_dakuten_do}, // ド + {0x30D4, 16, 0, texture_hud_char_kana_handakuten_pi}, // ピ + {0x30D5, 16, 0, texture_hud_char_katakana_fu}, // フ + {0x30DE, 16, 0, texture_hud_char_katakana_ma}, // マ + {0x30E9, 16, 0, texture_hud_char_katakana_ra}, // ラ + {0x30EA, 16, 0, texture_hud_char_katakana_ri}, // リ + {0x30EB, 16, 0, texture_hud_char_katakana_ru}, // ル + {0x30EC, 16, 0, texture_hud_char_katakana_re}, // レ + {0x30F3, 16, 0, texture_hud_char_katakana_n}, // ン + + {0x30FC, 16, 0, texture_hud_char_long_vowel}, // ー + {0xFF1F, 16, 0, texture_hud_char_question}, // ? +#endif +}; + +const struct Utf8CharLUTEntry main_hud_utf8_4byte_lut[] = { +}; + +const struct Utf8CharLUTEntry main_hud_utf8_missing_char = {0, 16, 0, texture_hud_char_question}; + +const struct Utf8LUT main_hud_utf8_lut = { + main_hud_utf8_2byte_lut, + main_hud_utf8_3byte_lut, + main_hud_utf8_4byte_lut, + ARRAY_COUNT(main_hud_utf8_2byte_lut), + ARRAY_COUNT(main_hud_utf8_3byte_lut), + ARRAY_COUNT(main_hud_utf8_4byte_lut), + &main_hud_utf8_missing_char, +}; + +// Diacritics for the generic white font +const struct DiacriticLUTEntry main_font_diacritic_lut[] = { + [TEXT_DIACRITIC_CIRCUMFLEX] = { 0, 0, "ˆ"}, + [TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE] = { 1, 4, "ˆ"}, + [TEXT_DIACRITIC_ACUTE] = {-1, 0, "ˊ"}, + [TEXT_DIACRITIC_ACUTE_UPPERCASE] = { 0, 4, "ˊ"}, + [TEXT_DIACRITIC_GRAVE] = {-1, 0, "ˋ"}, + [TEXT_DIACRITIC_GRAVE_UPPERCASE] = { 0, 4, "ˋ"}, + [TEXT_DIACRITIC_TILDE] = {-1, 0, "˜"}, + [TEXT_DIACRITIC_TILDE_UPPERCASE] = { 1, 4, "˜"}, + [TEXT_DIACRITIC_UMLAUT] = { 0, 0, "¨"}, + [TEXT_DIACRITIC_UMLAUT_UPPERCASE] = { 1, 4, "¨"}, + [TEXT_DIACRITIC_CEDILLA] = { 0, 0, "¸"}, +#ifdef JAPANESE_CHARACTERS + [TEXT_DIACRITIC_DAKUTEN] = { 4, 6, "゛"}, + [TEXT_DIACRITIC_HANDAKUTEN] = { 7, 10, "゜"}, +#endif +}; + +// ASCII lookup table for the generic white font +const struct AsciiCharLUTEntry main_font_lut[] = { + {NULL, 5}, // 32 " " + {texture_font_char_us_exclamation, 5}, // 33 "!" + {texture_font_char_us_double_quote_open, 6}, // 34 "\"" + {NULL, 0}, // 35 "#" (Unimplemented) + {NULL, 0}, // 36 "$" (Unimplemented) + {texture_font_char_us_percent, 7}, // 37 "%" + {texture_font_char_us_ampersand, 8}, // 38 "&" + {texture_font_char_us_apostrophe, 4}, // 39 "'" + {texture_font_char_us_open_parentheses, 5}, // 40 "(" + {texture_font_char_us_close_parentheses, 5}, // 41 ")" + {NULL, 0}, // 42 "*" (Unimplemented) + {texture_font_char_plus, 7}, // 43 "+" + {texture_font_char_us_comma, 4}, // 44 "," + {texture_font_char_us_hyphen, 6}, // 45 "-" + {texture_font_char_us_period, 4}, // 46 "." + {texture_font_char_slash, 5}, // 47 "/" + {texture_font_char_us_0, 7}, // 48 "0" + {texture_font_char_us_1, 7}, // 49 "1" + {texture_font_char_us_2, 7}, // 50 "2" + {texture_font_char_us_3, 7}, // 51 "3" + {texture_font_char_us_4, 7}, // 52 "4" + {texture_font_char_us_5, 7}, // 53 "5" + {texture_font_char_us_6, 7}, // 54 "6" + {texture_font_char_us_7, 7}, // 55 "7" + {texture_font_char_us_8, 7}, // 56 "8" + {texture_font_char_us_9, 7}, // 57 "9" + {texture_font_char_us_colon, 4}, // 58 ":" + {NULL, 0}, // 59 ";" (Unimplemented) + {NULL, 0}, // 60 "<" (Unimplemented) + {NULL, 0}, // 61 "=" (Unimplemented) + {NULL, 0}, // 62 ">" (Unimplemented) + {texture_font_char_us_question, 7}, // 63 "?" + {NULL, 0}, // 64 "@" (Unimplemented, used for color codes by default) + {texture_font_char_us_A, 6}, // 65 "A" + {texture_font_char_us_B, 6}, // 66 "B" + {texture_font_char_us_C, 6}, // 67 "C" + {texture_font_char_us_D, 6}, // 68 "D" + {texture_font_char_us_E, 6}, // 69 "E" + {texture_font_char_us_F, 6}, // 70 "F" + {texture_font_char_us_G, 6}, // 71 "G" + {texture_font_char_us_H, 6}, // 72 "H" + {texture_font_char_us_I, 5}, // 73 "I" + {texture_font_char_us_J, 6}, // 74 "J" + {texture_font_char_us_K, 6}, // 75 "K" + {texture_font_char_us_L, 5}, // 76 "L" + {texture_font_char_us_M, 8}, // 77 "M" + {texture_font_char_us_N, 8}, // 78 "N" + {texture_font_char_us_O, 6}, // 79 "O" + {texture_font_char_us_P, 6}, // 80 "P" + {texture_font_char_us_Q, 6}, // 81 "Q" + {texture_font_char_us_R, 6}, // 82 "R" + {texture_font_char_us_S, 6}, // 83 "S" + {texture_font_char_us_T, 5}, // 84 "T" + {texture_font_char_us_U, 6}, // 85 "U" + {texture_font_char_us_V, 6}, // 86 "V" + {texture_font_char_us_W, 8}, // 87 "W" + {texture_font_char_us_X, 7}, // 88 "X" + {texture_font_char_us_Y, 6}, // 89 "Y" + {texture_font_char_us_Z, 6}, // 90 "Z" + {NULL, 0}, // 91 "[" (Unimplemented) + {texture_font_char_backslash, 6}, // 92 "\\" + {NULL, 0}, // 93 "]" (Unimplemented) + {NULL, 0}, // 94 "^" (Unimplemented) + {NULL, 0}, // 95 "_" (Unimplemented) + {NULL, 0}, // 96 "`" (Unimplemented) + {texture_font_char_us_a, 6}, // 97 "a" + {texture_font_char_us_b, 5}, // 98 "b" + {texture_font_char_us_c, 5}, // 99 "c" + {texture_font_char_us_d, 6}, // 100 "d" + {texture_font_char_us_e, 5}, // 101 "e" + {texture_font_char_us_f, 5}, // 102 "f" + {texture_font_char_us_g, 6}, // 103 "g" + {texture_font_char_us_h, 5}, // 104 "h" + {texture_font_char_us_i, 4}, // 105 "i" + {texture_font_char_us_j, 5}, // 106 "j" + {texture_font_char_us_k, 5}, // 107 "k" + {texture_font_char_us_l, 3}, // 108 "l" + {texture_font_char_us_m, 7}, // 109 "m" + {texture_font_char_us_n, 5}, // 110 "n" + {texture_font_char_us_o, 5}, // 111 "o" + {texture_font_char_us_p, 5}, // 112 "p" + {texture_font_char_us_q, 6}, // 113 "q" + {texture_font_char_us_r, 5}, // 114 "r" + {texture_font_char_us_s, 5}, // 115 "s" + {texture_font_char_us_t, 5}, // 116 "t" + {texture_font_char_us_u, 5}, // 117 "u" + {texture_font_char_us_v, 5}, // 118 "v" + {texture_font_char_us_w, 7}, // 119 "w" + {texture_font_char_us_x, 7}, // 120 "x" + {texture_font_char_us_y, 5}, // 121 "y" + {texture_font_char_us_z, 5}, // 122 "z" + {NULL, 0}, // 123 "{" (Unimplemented) + {NULL, 0}, // 124 "|" (Unimplemented) + {NULL, 0}, // 125 "}" (Unimplemented) + {texture_font_char_us_tilde, 8}, // 126 "~" +}; + +/* + * This struct defines the UTF-8 characters supported by the main white font! + * There are also similar tables for colorful HUD font and the smaller white font. + * Adding new characters to the font is very easy! + * + * Look up the UTF-8 codepoint for your character. If the character is U+0D9E, the codepoint is 0x0D9E. + * Determine which table the character belongs to, depending on if it takes up 2, 3 or 4 bytes. + * Between U+0080 and U+07FF: 2 bytes + * Between U+0800 and U+FFFF: 3 bytes + * Between U+10000 and U+10FFFF: 4 bytes + * + * Add the texture with the other textures above, and add an entry for your new character in the corresponding table. + * The format of the entry is: {, , , }. + * (flags will likely be 0). + * + * MUST NOTE: You must place your entry in EXACTLY the right spot! The table is sorted by codepoint. + * The tables will not work if they are not sorted properly. + */ + +// UTF-8 lookup table for the generic white font +const struct Utf8CharLUTEntry main_font_utf8_2byte_lut[] = { + {0x00A1, 5, 0, texture_font_char_inverted_exclamation_mark}, // ¡ + {0x00A8, 0, 0, texture_font_char_diacritic_umlaut}, // ¨ + {0x00B7, 4, 0, texture_font_char_us_interpunct}, // · + {0x00B8, 0, 0, texture_font_char_diacritic_cedilla}, // ¸ + {0x00BF, 7, 0, texture_font_char_inverted_question_mark}, // ¿ + + {0x00C0, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_font_char_us_A}, // À + {0x00C1, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_font_char_us_A}, // Á + {0x00C2, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_font_char_us_A}, // Â + {0x00C3, 6, TEXT_DIACRITIC_TILDE_UPPERCASE, texture_font_char_us_A}, // Ã + {0x00C4, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_font_char_us_A}, // Ä + + {0x00C7, 6, TEXT_DIACRITIC_CEDILLA, texture_font_char_us_C}, // Ç + {0x00C8, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_font_char_us_E}, // È + {0x00C9, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_font_char_us_E}, // É + {0x00CA, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_font_char_us_E}, // Ê + {0x00CB, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_font_char_us_E}, // Ë + + {0x00CC, 5, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_font_char_us_I}, // Ì + {0x00CD, 5, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_font_char_us_I}, // Í + {0x00CE, 5, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_font_char_us_I}, // Î + {0x00CF, 5, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_font_char_us_I}, // Ï + + {0x00D1, 6, TEXT_DIACRITIC_TILDE_UPPERCASE, texture_font_char_us_N}, // Ñ + {0x00D2, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_font_char_us_O}, // Ò + {0x00D3, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_font_char_us_O}, // Ó + {0x00D4, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_font_char_us_O}, // Ô + {0x00D5, 6, TEXT_DIACRITIC_TILDE_UPPERCASE, texture_font_char_us_O}, // Õ + {0x00D6, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_font_char_us_O}, // Ö + + {0x00D7, 6, 0, texture_font_char_us_multiply}, // × + + {0x00D9, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_font_char_us_U}, // Ù + {0x00DA, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_font_char_us_U}, // Ú + {0x00DB, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_font_char_us_U}, // Û + {0x00DC, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_font_char_us_U}, // Ü + + {0x00DF, 6, 0, texture_font_char_eszett}, // ß + + {0x00E0, 6, TEXT_DIACRITIC_GRAVE, texture_font_char_us_a}, // à + {0x00E1, 6, TEXT_DIACRITIC_ACUTE, texture_font_char_us_a}, // á + {0x00E2, 6, TEXT_DIACRITIC_CIRCUMFLEX, texture_font_char_us_a}, // â + {0x00E3, 6, TEXT_DIACRITIC_TILDE, texture_font_char_us_a}, // ã + {0x00E4, 6, TEXT_DIACRITIC_UMLAUT, texture_font_char_us_a}, // ä + + {0x00E7, 5, TEXT_DIACRITIC_CEDILLA, texture_font_char_us_c}, // ç + {0x00E8, 5, TEXT_DIACRITIC_GRAVE, texture_font_char_us_e}, // è + {0x00E9, 5, TEXT_DIACRITIC_ACUTE, texture_font_char_us_e}, // é + {0x00EA, 5, TEXT_DIACRITIC_CIRCUMFLEX, texture_font_char_us_e}, // ê + {0x00EB, 5, TEXT_DIACRITIC_UMLAUT, texture_font_char_us_e}, // ë + + {0x00EC, 4, TEXT_DIACRITIC_GRAVE, texture_font_char_us_i_no_dot}, // ì + {0x00ED, 4, TEXT_DIACRITIC_ACUTE, texture_font_char_us_i_no_dot}, // í + {0x00EE, 4, TEXT_DIACRITIC_CIRCUMFLEX, texture_font_char_us_i_no_dot}, // î + {0x00EF, 4, TEXT_DIACRITIC_UMLAUT, texture_font_char_us_i_no_dot}, // ï + + {0x00F1, 5, TEXT_DIACRITIC_TILDE, texture_font_char_us_n}, // ñ + {0x00F2, 5, TEXT_DIACRITIC_GRAVE, texture_font_char_us_o}, // ò + {0x00F3, 5, TEXT_DIACRITIC_ACUTE, texture_font_char_us_o}, // ó + {0x00F4, 5, TEXT_DIACRITIC_CIRCUMFLEX, texture_font_char_us_o}, // ô + {0x00F5, 5, TEXT_DIACRITIC_TILDE, texture_font_char_us_o}, // õ + {0x00F6, 5, TEXT_DIACRITIC_UMLAUT, texture_font_char_us_o}, // ö + + {0x00F9, 5, TEXT_DIACRITIC_GRAVE, texture_font_char_us_u}, // ù + {0x00FA, 5, TEXT_DIACRITIC_ACUTE, texture_font_char_us_u}, // ú + {0x00FB, 5, TEXT_DIACRITIC_CIRCUMFLEX, texture_font_char_us_u}, // û + {0x00FC, 5, TEXT_DIACRITIC_UMLAUT, texture_font_char_us_u}, // ü + + {0x02C6, 0, 0, texture_font_char_diacritic_circumflex}, // ˆ + {0x02CA, 0, 0, texture_font_char_diacritic_acute}, // ˊ + {0x02CB, 0, 0, texture_font_char_diacritic_grave}, // ˋ + {0x02DC, 0, 0, texture_font_char_diacritic_tilde}, // ˜ +}; + +const struct Utf8CharLUTEntry main_font_utf8_3byte_lut[] = { + {0x201C, 6, 0, texture_font_char_us_double_quote_open}, // “ + {0x201D, 6, 0, texture_font_char_us_double_quote_close}, // ” + {0x201E, 6, 0, texture_font_char_us_double_low_quote}, // „ + {0x2194, 9, 0, texture_font_char_us_left_right_arrow}, // ↔ + + {0x24B6, 7, 0, texture_font_char_us_button_A}, // Ⓐ + {0x24B7, 7, 0, texture_font_char_us_button_B}, // Ⓑ + {0x24B8, 6, 0, texture_font_char_us_button_C}, // Ⓒ + {0x24C7, 7, 0, texture_font_char_us_button_R}, // Ⓡ + {0x24CF, 7, 0, texture_font_char_us_button_Z}, // Ⓩ + + {0x25B2, 8, 0, texture_font_char_us_button_C_up}, // ▲ + {0x25B6, 8, 0, texture_font_char_us_button_C_right}, // ▶ + {0x25BC, 8, 0, texture_font_char_us_button_C_down}, // ▼ + {0x25C0, 8, 0, texture_font_char_us_button_C_left}, // ◀ + + {0x2605, 10, 0, texture_font_char_us_star_filled}, // ★ + {0x2606, 10, 0, texture_font_char_us_star_hollow}, // ☆ + {0x272A, 8, 0, texture_font_char_us_coin}, // ✪ + +#ifdef JAPANESE_CHARACTERS + {0x3000, 10, 0, NULL}, // " " (ideographic space) + {0x3001, 10, TEXT_FLAG_PACKED, texture_font_char_jp_comma}, // 、 + {0x3002, 10, TEXT_FLAG_PACKED, texture_font_char_jp_period}, // 。 + {0x300E, 10, TEXT_FLAG_PACKED, texture_font_char_jp_double_quotation_open}, // 『 + {0x300F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_double_quotation_close}, // 』 + + {0x3041, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_a}, // ぁ + {0x3042, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_a}, // あ + {0x3043, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_i}, // ぃ + {0x3044, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_i}, // い + {0x3045, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_u}, // ぅ + {0x3046, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_u}, // う + {0x3047, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_e}, // ぇ + {0x3048, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_e}, // え + {0x3049, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_o}, // ぉ + {0x304A, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_o}, // お + {0x304B, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ka}, // か + {0x304C, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ka}, // が + {0x304D, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ki}, // き + {0x304E, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ki}, // ぎ + {0x304F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ku}, // く + {0x3050, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ku}, // ぐ + {0x3051, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ke}, // け + {0x3052, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ke}, // げ + {0x3053, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ko}, // こ + {0x3054, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ko}, // ご + {0x3055, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_sa}, // さ + {0x3056, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_sa}, // ざ + {0x3057, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_shi}, // し + {0x3058, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_shi}, // じ + {0x3059, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_su}, // す + {0x305A, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_su}, // ず + {0x305B, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_se}, // せ + {0x305C, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_se}, // ぜ + {0x305D, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_so}, // そ + {0x305E, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_so}, // ぞ + {0x305F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ta}, // た + {0x3060, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ta}, // だ + {0x3061, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_chi}, // ち + {0x3062, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_chi}, // ぢ + {0x3063, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_tsu}, // っ + {0x3064, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_tsu}, // つ + {0x3065, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_tsu}, // づ + {0x3066, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_te}, // て + {0x3067, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_te}, // で + {0x3068, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_to}, // と + {0x3069, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_to}, // ど + {0x306A, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_na}, // な + {0x306B, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ni}, // に + {0x306C, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_nu}, // ぬ + {0x306D, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ne}, // ね + {0x306E, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_no}, // の + {0x306F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ha}, // は + {0x3070, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ha}, // ば + {0x3071, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_hiragana_ha}, // ぱ + {0x3072, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_hi}, // ひ + {0x3073, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_hi}, // び + {0x3074, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_hiragana_hi}, // ぴ + {0x3075, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_fu}, // ふ + {0x3076, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_fu}, // ぶ + {0x3077, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_hiragana_fu}, // ぷ + {0x3078, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_he}, // へ + {0x3079, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_he}, // べ + {0x307A, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_hiragana_he}, // ぺ + {0x307B, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ho}, // ほ + {0x307C, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_hiragana_ho}, // ぼ + {0x307D, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_hiragana_ho}, // ぽ + {0x307E, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ma}, // ま + {0x307F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_mi}, // み + {0x3080, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_mu}, // む + {0x3081, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_me}, // め + {0x3082, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_mo}, // も + {0x3083, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_ya}, // ゃ + {0x3084, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ya}, // や + {0x3085, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_yu}, // ゅ + {0x3086, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_yu}, // ゆ + {0x3087, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_small_yo}, // ょ + {0x3088, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_yo}, // よ + {0x3089, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ra}, // ら + {0x308A, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ri}, // り + {0x308B, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ru}, // る + {0x308C, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_re}, // れ + {0x308D, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_ro}, // ろ + {0x308F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_wa}, // わ + {0x3092, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_wo}, // を + {0x3093, 10, TEXT_FLAG_PACKED, texture_font_char_jp_hiragana_n}, // ん + + {0x309B, 0, TEXT_FLAG_PACKED, texture_font_char_jp_dakuten}, // ゛ + {0x309C, 0, TEXT_FLAG_PACKED, texture_font_char_jp_period}, // ゜ + + {0x30A1, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_a}, // ァ + {0x30A2, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_a}, // ア + {0x30A3, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_i}, // ィ + {0x30A4, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_i}, // イ + {0x30A5, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_u}, // ゥ + {0x30A6, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_u}, // ウ + {0x30A7, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_e}, // ェ + {0x30A8, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_e}, // エ + {0x30A9, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_o}, // ォ + {0x30AA, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_o}, // オ + {0x30AB, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ka}, // カ + {0x30AC, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ka}, // ガ + {0x30AD, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ki}, // キ + {0x30AE, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ki}, // ギ + {0x30AF, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ku}, // ク + {0x30B0, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ku}, // グ + {0x30B1, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ke}, // ケ + {0x30B2, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ke}, // ゲ + {0x30B3, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ko}, // コ + {0x30B4, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ko}, // ゴ + {0x30B5, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_sa}, // サ + {0x30B6, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_sa}, // ザ + {0x30B7, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_shi}, // シ + {0x30B8, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_shi}, // ジ + {0x30B9, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_su}, // ス + {0x30BA, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_su}, // ズ + {0x30BB, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_se}, // セ + {0x30BC, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_se}, // ゼ + {0x30BD, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_so}, // ソ + {0x30BE, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_so}, // ゾ + {0x30BF, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ta}, // タ + {0x30C0, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ta}, // ダ + {0x30C1, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_chi}, // チ + {0x30C2, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_chi}, // ヂ + {0x30C3, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_tsu}, // ッ + {0x30C4, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_tsu}, // ツ + {0x30C5, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_tsu}, // ヅ + {0x30C6, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_te}, // テ + {0x30C7, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_te}, // デ + {0x30C8, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_to}, // ト + {0x30C9, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_to}, // ド + {0x30CA, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_na}, // ナ + {0x30CB, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ni}, // ニ + {0x30CC, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_nu}, // ヌ + {0x30CD, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ne}, // ネ + {0x30CE, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_no}, // ノ + {0x30CF, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ha}, // ハ + {0x30D0, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ha}, // バ + {0x30D1, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_katakana_ha}, // パ + {0x30D2, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_hi}, // ヒ + {0x30D3, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_hi}, // ビ + {0x30D4, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_katakana_hi}, // ピ + {0x30D5, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_fu}, // フ + {0x30D6, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_fu}, // ブ + {0x30D7, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_katakana_fu}, // プ + {0x30D8, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_he}, // ヘ + {0x30D9, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_he}, // ベ + {0x30DA, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_katakana_he}, // ペ + {0x30DB, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ho}, // ホ + {0x30DC, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_DAKUTEN, texture_font_char_jp_katakana_ho}, // ボ + {0x30DD, 10, TEXT_FLAG_PACKED | TEXT_DIACRITIC_HANDAKUTEN, texture_font_char_jp_katakana_ho}, // ポ + {0x30DE, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ma}, // マ + {0x30DF, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_mi}, // ミ + {0x30E0, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_mu}, // ム + {0x30E1, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_me}, // メ + {0x30E2, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_mo}, // モ + {0x30E3, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_ya}, // ャ + {0x30E4, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ya}, // ヤ + {0x30E5, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_yu}, // ュ + {0x30E6, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_yu}, // ユ + {0x30E7, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_small_yo}, // ョ + {0x30E8, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_yo}, // ヨ + {0x30E9, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ra}, // ラ + {0x30EA, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ri}, // リ + {0x30EB, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ru}, // ル + {0x30EC, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_re}, // レ + {0x30ED, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_ro}, // ロ + {0x30EF, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_wa}, // ワ + {0x30F3, 10, TEXT_FLAG_PACKED, texture_font_char_jp_katakana_n}, // ン + {0x30FB, 10, TEXT_FLAG_PACKED, texture_font_char_jp_interpunct}, // ・ + {0x30FC, 10, TEXT_FLAG_PACKED, texture_font_char_jp_long_vowel}, // ー + + {0xFF01, 10, TEXT_FLAG_PACKED, texture_font_char_jp_exclamation}, // ! + {0xFF05, 10, TEXT_FLAG_PACKED, texture_font_char_jp_percent}, // % + {0xFF08, 10, TEXT_FLAG_PACKED, texture_font_char_jp_open_parentheses}, // ( + {0xFF09, 10, TEXT_FLAG_PACKED, texture_font_char_jp_close_parentheses}, // ) + {0xFF10, 10, TEXT_FLAG_PACKED, texture_font_char_jp_0}, // 0 + {0xFF11, 10, TEXT_FLAG_PACKED, texture_font_char_jp_1}, // 1 + {0xFF12, 10, TEXT_FLAG_PACKED, texture_font_char_jp_2}, // 2 + {0xFF13, 10, TEXT_FLAG_PACKED, texture_font_char_jp_3}, // 3 + {0xFF14, 10, TEXT_FLAG_PACKED, texture_font_char_jp_4}, // 4 + {0xFF15, 10, TEXT_FLAG_PACKED, texture_font_char_jp_5}, // 5 + {0xFF16, 10, TEXT_FLAG_PACKED, texture_font_char_jp_6}, // 6 + {0xFF17, 10, TEXT_FLAG_PACKED, texture_font_char_jp_7}, // 7 + {0xFF18, 10, TEXT_FLAG_PACKED, texture_font_char_jp_8}, // 8 + {0xFF19, 10, TEXT_FLAG_PACKED, texture_font_char_jp_9}, // 9 + {0xFF1F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_question}, // ? + {0xFF21, 10, TEXT_FLAG_PACKED, texture_font_char_jp_A}, // A + {0xFF22, 10, TEXT_FLAG_PACKED, texture_font_char_jp_B}, // B + {0xFF23, 10, TEXT_FLAG_PACKED, texture_font_char_jp_C}, // C + {0xFF24, 10, TEXT_FLAG_PACKED, texture_font_char_jp_D}, // D + {0xFF25, 10, TEXT_FLAG_PACKED, texture_font_char_jp_E}, // E + {0xFF26, 10, TEXT_FLAG_PACKED, texture_font_char_jp_F}, // F + {0xFF27, 10, TEXT_FLAG_PACKED, texture_font_char_jp_G}, // G + {0xFF28, 10, TEXT_FLAG_PACKED, texture_font_char_jp_H}, // H + {0xFF29, 10, TEXT_FLAG_PACKED, texture_font_char_jp_I}, // I + {0xFF2A, 10, TEXT_FLAG_PACKED, texture_font_char_jp_J}, // J + {0xFF2B, 10, TEXT_FLAG_PACKED, texture_font_char_jp_K}, // K + {0xFF2C, 10, TEXT_FLAG_PACKED, texture_font_char_jp_L}, // L + {0xFF2D, 10, TEXT_FLAG_PACKED, texture_font_char_jp_M}, // M + {0xFF2E, 10, TEXT_FLAG_PACKED, texture_font_char_jp_N}, // N + {0xFF2F, 10, TEXT_FLAG_PACKED, texture_font_char_jp_O}, // O + {0xFF30, 10, TEXT_FLAG_PACKED, texture_font_char_jp_P}, // P + {0xFF31, 10, TEXT_FLAG_PACKED, texture_font_char_jp_Q}, // Q + {0xFF32, 10, TEXT_FLAG_PACKED, texture_font_char_jp_R}, // R + {0xFF33, 10, TEXT_FLAG_PACKED, texture_font_char_jp_S}, // S + {0xFF34, 10, TEXT_FLAG_PACKED, texture_font_char_jp_T}, // T + {0xFF35, 10, TEXT_FLAG_PACKED, texture_font_char_jp_U}, // U + {0xFF36, 10, TEXT_FLAG_PACKED, texture_font_char_jp_V}, // V + {0xFF37, 10, TEXT_FLAG_PACKED, texture_font_char_jp_W}, // W + {0xFF38, 10, TEXT_FLAG_PACKED, texture_font_char_jp_X}, // X + {0xFF39, 10, TEXT_FLAG_PACKED, texture_font_char_jp_Y}, // Y + {0xFF3A, 10, TEXT_FLAG_PACKED, texture_font_char_jp_Z}, // Z + + {0xFF58, 10, TEXT_FLAG_PACKED, texture_font_char_jp_multiply}, // x + {0xFF5E, 10, TEXT_FLAG_PACKED, texture_font_char_jp_tilde}, // ~ #endif }; +const struct Utf8CharLUTEntry main_font_utf8_4byte_lut[] = { + +}; + +const struct Utf8CharLUTEntry main_font_utf8_missing_char = {0, 9, 0, texture_font_missing_character}; + +const struct Utf8LUT main_font_utf8_lut = { + main_font_utf8_2byte_lut, + main_font_utf8_3byte_lut, + main_font_utf8_4byte_lut, + ARRAY_COUNT(main_font_utf8_2byte_lut), + ARRAY_COUNT(main_font_utf8_3byte_lut), + ARRAY_COUNT(main_font_utf8_4byte_lut), + &main_font_utf8_missing_char, +}; + #if !CREDITS_TEXT_STRING_FONT -// credits font LUT 0x02008738-0x020087CB -const Texture *const main_credits_font_lut[] = { - 0x0, 0x0, 0x0, texture_credits_char_3, - texture_credits_char_4, 0x0, texture_credits_char_6, 0x0, - 0x0, 0x0, texture_credits_char_A, texture_credits_char_B, - texture_credits_char_C, texture_credits_char_D, texture_credits_char_E, texture_credits_char_F, - texture_credits_char_G, texture_credits_char_H, texture_credits_char_I, texture_credits_char_J, - texture_credits_char_K, texture_credits_char_L, texture_credits_char_M, texture_credits_char_N, - texture_credits_char_O, texture_credits_char_P, texture_credits_char_Q, texture_credits_char_R, - texture_credits_char_S, texture_credits_char_T, texture_credits_char_U, texture_credits_char_V, - texture_credits_char_W, texture_credits_char_X, texture_credits_char_Y, texture_credits_char_Z, - texture_credits_char_period, +// ASCII lookup table for the green credits font +const struct AsciiCharLUTEntry main_credits_font_lut[] = { + {NULL, 4}, // 32 " " + {NULL, 0}, // 33 "!" (Unimplemented) + {NULL, 0}, // 34 "\"" (Unimplemented) + {NULL, 0}, // 35 "#" (Unimplemented) + {NULL, 0}, // 36 "$" (Unimplemented) + {NULL, 0}, // 37 "%" (Unimplemented) + {NULL, 0}, // 38 "&" (Unimplemented) + {NULL, 0}, // 39 "'" (Unimplemented) + {NULL, 0}, // 40 "(" (Unimplemented) + {NULL, 0}, // 41 ")" (Unimplemented) + {NULL, 0}, // 42 "*" (Unimplemented) + {NULL, 0}, // 43 "+" (Unimplemented) + {NULL, 0}, // 44 "," (Unimplemented) + {NULL, 0}, // 45 "-" (Unimplemented) + {texture_credits_char_period, 7}, // 46 "." + {NULL, 0}, // 47 "/" (Unimplemented) + {NULL, 0}, // 48 "0" (Unimplemented) + {NULL, 0}, // 49 "1" (Unimplemented) + {NULL, 0}, // 50 "2" (Unimplemented) + {texture_credits_char_3, 7}, // 51 "3" + {texture_credits_char_4, 7}, // 52 "4" + {NULL, 0}, // 53 "5" (Unimplemented) + {texture_credits_char_6, 7}, // 54 "6" + {NULL, 0}, // 55 "7" (Unimplemented) + {NULL, 0}, // 56 "8" (Unimplemented) + {NULL, 0}, // 57 "9" (Unimplemented) + {NULL, 0}, // 58 ":" (Unimplemented) + {NULL, 0}, // 59 ";" (Unimplemented) + {NULL, 0}, // 60 "<" (Unimplemented) + {NULL, 0}, // 61 "=" (Unimplemented) + {NULL, 0}, // 62 ">" (Unimplemented) + {NULL, 0}, // 63 "?" (Unimplemented) + {NULL, 0}, // 64 "@" (Unimplemented) + {texture_credits_char_A, 7}, // 65 "A" + {texture_credits_char_B, 7}, // 66 "B" + {texture_credits_char_C, 7}, // 67 "C" + {texture_credits_char_D, 7}, // 68 "D" + {texture_credits_char_E, 7}, // 69 "E" + {texture_credits_char_F, 7}, // 70 "F" + {texture_credits_char_G, 7}, // 71 "G" + {texture_credits_char_H, 7}, // 72 "H" + {texture_credits_char_I, 7}, // 73 "I" + {texture_credits_char_J, 7}, // 74 "J" + {texture_credits_char_K, 7}, // 75 "K" + {texture_credits_char_L, 7}, // 76 "L" + {texture_credits_char_M, 7}, // 77 "M" + {texture_credits_char_N, 7}, // 78 "N" + {texture_credits_char_O, 7}, // 79 "O" + {texture_credits_char_P, 7}, // 80 "P" + {texture_credits_char_Q, 7}, // 81 "Q" + {texture_credits_char_R, 7}, // 82 "R" + {texture_credits_char_S, 7}, // 83 "S" + {texture_credits_char_T, 7}, // 84 "T" + {texture_credits_char_U, 7}, // 85 "U" + {texture_credits_char_V, 7}, // 86 "V" + {texture_credits_char_W, 7}, // 87 "W" + {texture_credits_char_X, 7}, // 88 "X" + {texture_credits_char_Y, 7}, // 89 "Y" + {texture_credits_char_Z, 7}, // 90 "Z" + {NULL, 0}, // 91 "[" (Unimplemented) + {NULL, 0}, // 92 "\" (Unimplemented) + {NULL, 0}, // 93 "]" (Unimplemented) + {NULL, 0}, // 94 "^" (Unimplemented) + {NULL, 0}, // 95 "_" (Unimplemented) + {NULL, 0}, // 96 "`" (Unimplemented) + {texture_credits_char_A, 7}, // 97 "a" + {texture_credits_char_B, 7}, // 98 "b" + {texture_credits_char_C, 7}, // 99 "c" + {texture_credits_char_D, 7}, // 100 "d" + {texture_credits_char_E, 7}, // 101 "e" + {texture_credits_char_F, 7}, // 102 "f" + {texture_credits_char_G, 7}, // 103 "g" + {texture_credits_char_H, 7}, // 104 "h" + {texture_credits_char_I, 7}, // 105 "i" + {texture_credits_char_J, 7}, // 106 "j" + {texture_credits_char_K, 7}, // 107 "k" + {texture_credits_char_L, 7}, // 108 "l" + {texture_credits_char_M, 7}, // 109 "m" + {texture_credits_char_N, 7}, // 110 "n" + {texture_credits_char_O, 7}, // 111 "o" + {texture_credits_char_P, 7}, // 112 "p" + {texture_credits_char_Q, 7}, // 113 "q" + {texture_credits_char_R, 7}, // 114 "r" + {texture_credits_char_S, 7}, // 115 "s" + {texture_credits_char_T, 7}, // 116 "t" + {texture_credits_char_U, 7}, // 117 "u" + {texture_credits_char_V, 7}, // 118 "v" + {texture_credits_char_W, 7}, // 119 "w" + {texture_credits_char_X, 7}, // 120 "x" + {texture_credits_char_Y, 7}, // 121 "y" + {texture_credits_char_Z, 7}, // 122 "z" + {NULL, 0}, // 123 "{" (Unimplemented) + {NULL, 0}, // 124 "|" (Unimplemented) + {NULL, 0}, // 125 "}" (Unimplemented) + {NULL, 0}, // 126 "~" (Unimplemented) }; #endif @@ -2077,16 +2738,22 @@ const Texture *const main_hud_camera_lut[] = { texture_hud_char_arrow_up, texture_hud_char_arrow_down, }; -// If you change the language here, the following Makefile rule also needs to -// change, to generate the right version of define_text.inc.c: -// $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/$(VERSION)/define_text.inc.c -#if defined(VERSION_JP) || defined(VERSION_SH) -#include "text/jp/define_text.inc.c" -#elif defined(VERSION_US) -#include "text/us/define_text.inc.c" -#endif +// If not using multilang, include the text data here in segment 0x02. +// Otherwise, it will be placed into segment 0x19. +#ifndef MULTILANG +#include "sounds.h" +#include "seq_ids.h" -UNUSED static const u64 segment2_unused_0 = 0; +#define COURSE_NAME_TABLE seg2_course_name_table +#define ACT_NAME_TABLE seg2_act_name_table +#define DIALOG_TABLE seg2_dialog_table + +#define DIALOG_FILE "us/dialogs.h" +#define COURSE_FILE "us/courses.h" +#include "text/define_text.inc.c" +#undef DIALOG_FILE +#undef COURSE_FILE +#endif // 0x0200EC60 - 0x0200EC98 const Gfx dl_hud_img_begin[] = { @@ -2177,62 +2844,14 @@ const Gfx dl_draw_text_bg_box[] = { gsSPEndDisplayList(), }; -#ifndef VERSION_EU // 0x0200EE28 - 0x0200EE68 static const Vtx vertex_ia8_char[] = { -#if defined(VERSION_JP) || defined(VERSION_SH) - {{{ 0, 0, 0}, 0, { 0, 1024}, {0xff, 0xff, 0xff, 0xff}}}, - {{{ 8, 0, 0}, 0, { 512, 1024}, {0xff, 0xff, 0xff, 0xff}}}, - {{{ 8, 16, 0}, 0, { 512, 0}, {0xff, 0xff, 0xff, 0xff}}}, - {{{ 0, 16, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, -#else - // ex-alo change - // Corrects IA font UV {{{ 0, 0, 0}, 0, { 0, 256}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 8, 0, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 8, 16, 0}, 0, { 512, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 0, 16, 0}, 0, { 512, 256}, {0xff, 0xff, 0xff, 0xff}}}, -#endif -}; -// !EU -#endif - -#undef UV - -#ifdef VERSION_EU -// 0x020073B0 -const Gfx dl_ia_text_begin[] = { - gsDPPipeSync(), - gsDPSetTexturePersp(G_TP_NONE), - gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA), - gsDPSetEnvColor(255, 255, 255, 255), - gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2), - gsDPSetTextureFilter(G_TF_POINT), - gsSPEndDisplayList(), -}; - -// 0x020073E8 - 0x02007418 -const Gfx dl_ia_text_tex_settings[] = { - gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_MIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_MIRROR, 4, G_TX_NOLOD), - gsDPLoadSync(), - gsDPLoadBlock(G_TX_LOADTILE, 0, 0, ((16 * 8 + G_IM_SIZ_4b_INCR) >> G_IM_SIZ_4b_SHIFT) - 1, CALC_DXT(16, G_IM_SIZ_4b_BYTES)), - gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_4b, 1, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_MIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_MIRROR, 4, G_TX_NOLOD), - gsDPSetTileSize(0, 0, 0, (16 - 1) << G_TEXTURE_IMAGE_FRAC, (8 - 1) << G_TEXTURE_IMAGE_FRAC), - gsSPEndDisplayList(), -}; - -// 0x02007418 - 0x02007450 -const Gfx dl_ia_text_end[] = { - gsDPPipeSync(), - gsDPSetTexturePersp(G_TP_PERSP), - gsDPSetRenderMode(G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2), - gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE), - gsDPSetEnvColor(255, 255, 255, 255), - gsDPSetTextureFilter(G_TF_BILERP), - gsSPEndDisplayList(), }; -#elif defined(VERSION_US) const Gfx dl_ia_text_begin[] = { gsDPPipeSync(), gsSPClearGeometryMode(G_LIGHTING), @@ -2244,44 +2863,39 @@ const Gfx dl_ia_text_begin[] = { gsSPEndDisplayList(), }; +// 0x020073E8 - 0x02007418 const Gfx dl_ia_text_tex_settings[] = { - gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD), + gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, (G_TX_WRAP | G_TX_MIRROR), 3, G_TX_NOLOD, (G_TX_WRAP | G_TX_MIRROR), 4, G_TX_NOLOD), gsDPLoadSync(), - gsDPLoadBlock(G_TX_LOADTILE, 0, 0, ((16 * 8 + G_IM_SIZ_4b_INCR) >> G_IM_SIZ_4b_SHIFT) - 1, CALC_DXT(16, G_IM_SIZ_4b_BYTES)), - gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_4b, 1, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 3, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 4, G_TX_NOLOD), - gsDPSetTileSize(0, 0, 0, (16 - 1) << G_TEXTURE_IMAGE_FRAC, (8 - 1) << G_TEXTURE_IMAGE_FRAC), + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, ((((16 * 8) + G_IM_SIZ_4b_INCR) >> G_IM_SIZ_4b_SHIFT) - 1), CALC_DXT(16, G_IM_SIZ_4b_BYTES)), + gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_4b, 1, 0, G_TX_RENDERTILE, 0, (G_TX_WRAP | G_TX_MIRROR), 3, G_TX_NOLOD, (G_TX_WRAP | G_TX_MIRROR), 4, G_TX_NOLOD), + gsDPSetTileSize(0, 0, 0, ((16 - 1) << G_TEXTURE_IMAGE_FRAC), ((8 - 1) << G_TEXTURE_IMAGE_FRAC)), gsSPVertex(vertex_ia8_char, 4, 0), gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), gsSPEndDisplayList(), }; -#else -// 0x0200EE68 - 0x0200EEA8 -const Gfx dl_ia_text_begin[] = { - gsDPPipeSync(), - gsSPClearGeometryMode(G_LIGHTING), - gsDPSetCombineMode(G_CC_FADEA, G_CC_FADEA), - gsDPSetEnvColor(255, 255, 255, 255), - gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2), - gsDPSetTextureFilter(G_TF_POINT), - gsSPTexture(0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON), - gsSPEndDisplayList(), +static const Vtx vertex_ia8_char_packed[] = { + {{{ 0, 0, 0}, 0, { 0, 1024}, {0xff, 0xff, 0xff, 0xff}}}, + {{{ 8, 0, 0}, 0, { 512, 1024}, {0xff, 0xff, 0xff, 0xff}}}, + {{{ 8, 16, 0}, 0, { 512, 0}, {0xff, 0xff, 0xff, 0xff}}}, + {{{ 0, 16, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, }; // 0x0200EEA8 - 0x0200EEF0 -const Gfx dl_ia_text_tex_settings[] = { +const Gfx dl_ia_text_tex_settings_packed[] = { + gsSPTexture(0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON), // gross gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_8b, 0, 0, G_TX_LOADTILE, 0, G_TX_CLAMP, 4, G_TX_NOLOD, G_TX_CLAMP, 3, G_TX_NOLOD), gsDPLoadSync(), - gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 8 * 16 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES)), + gsDPLoadBlock(G_TX_LOADTILE, 0, 0, ((8 * 16) - 1), CALC_DXT(8, G_IM_SIZ_8b_BYTES)), gsDPSetTile(G_IM_FMT_IA, G_IM_SIZ_8b, 1, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP, 4, G_TX_NOLOD, G_TX_CLAMP, 3, G_TX_NOLOD), - gsDPSetTileSize(0, 0, 0, (8 - 1) << G_TEXTURE_IMAGE_FRAC, (16 - 1) << G_TEXTURE_IMAGE_FRAC), - gsSPVertex(vertex_ia8_char, 4, 0), + gsDPSetTileSize(0, 0, 0, ((8 - 1) << G_TEXTURE_IMAGE_FRAC), ((16 - 1) << G_TEXTURE_IMAGE_FRAC)), + gsSPVertex(vertex_ia8_char_packed, 4, 0), gsSP2Triangles( 0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), // gross gsSPEndDisplayList(), }; -#endif -#ifndef VERSION_EU // 0x0200EEF0 - 0x0200EF30 const Gfx dl_ia_text_end[] = { gsDPPipeSync(), @@ -2293,7 +2907,7 @@ const Gfx dl_ia_text_end[] = { gsDPSetTextureFilter(G_TF_BILERP), gsSPEndDisplayList(), }; -#endif + // 0x0200EF30 - 0x0200EF60 static const Vtx vertex_triangle[] = { diff --git a/bin/translation_de.c b/bin/translation_de.c new file mode 100644 index 000000000..eaae2fbb3 --- /dev/null +++ b/bin/translation_de.c @@ -0,0 +1,17 @@ +// SM64 (EU) Segment 19 - Deutsch + +#include "macros.h" + +#include "game/ingame_menu.h" +#include "sounds.h" +#include "seq_ids.h" + +#define COURSE_NAME_TABLE course_name_table_de +#define ACT_NAME_TABLE act_name_table_de +#define DIALOG_TABLE dialog_table_de + +#define DIALOG_FILE "de/dialogs.h" +#define COURSE_FILE "de/courses.h" +#include "text/define_text.inc.c" +#undef DIALOG_FILE +#undef COURSE_FILE diff --git a/bin/translation_en.c b/bin/translation_en.c new file mode 100644 index 000000000..8b0e4dff5 --- /dev/null +++ b/bin/translation_en.c @@ -0,0 +1,17 @@ +// SM64 (EU) Segment 19 - English + +#include "macros.h" + +#include "game/ingame_menu.h" +#include "sounds.h" +#include "seq_ids.h" + +#define COURSE_NAME_TABLE course_name_table_en +#define ACT_NAME_TABLE act_name_table_en +#define DIALOG_TABLE dialog_table_en + +#define DIALOG_FILE "us/dialogs.h" +#define COURSE_FILE "us/courses.h" +#include "text/define_text.inc.c" +#undef DIALOG_FILE +#undef COURSE_FILE diff --git a/bin/translation_fr.c b/bin/translation_fr.c new file mode 100644 index 000000000..fd6704566 --- /dev/null +++ b/bin/translation_fr.c @@ -0,0 +1,17 @@ +// SM64 (EU) Segment 19 - Français + +#include "macros.h" + +#include "game/ingame_menu.h" +#include "sounds.h" +#include "seq_ids.h" + +#define COURSE_NAME_TABLE course_name_table_fr +#define ACT_NAME_TABLE act_name_table_fr +#define DIALOG_TABLE dialog_table_fr + +#define DIALOG_FILE "fr/dialogs.h" +#define COURSE_FILE "fr/courses.h" +#include "text/define_text.inc.c" +#undef DIALOG_FILE +#undef COURSE_FILE diff --git a/bin/translation_jp.c b/bin/translation_jp.c new file mode 100644 index 000000000..3d45ab9f9 --- /dev/null +++ b/bin/translation_jp.c @@ -0,0 +1,17 @@ +// SM64 (EU) Segment 19 - 日本語 (Japanese) + +#include "macros.h" + +#include "game/ingame_menu.h" +#include "sounds.h" +#include "seq_ids.h" + +#define COURSE_NAME_TABLE course_name_table_jp +#define ACT_NAME_TABLE act_name_table_jp +#define DIALOG_TABLE dialog_table_jp + +#define DIALOG_FILE "jp/dialogs.h" +#define COURSE_FILE "jp/courses.h" +#include "text/define_text.inc.c" +#undef DIALOG_FILE +#undef COURSE_FILE diff --git a/charmap.txt b/charmap.txt deleted file mode 100644 index 49aaee553..000000000 --- a/charmap.txt +++ /dev/null @@ -1,356 +0,0 @@ -'0' = 0x00 -'0' = 0x00 -'1' = 0x01 -'1' = 0x01 -'2' = 0x02 -'2' = 0x02 -'3' = 0x03 -'3' = 0x03 -'4' = 0x04 -'4' = 0x04 -'5' = 0x05 -'5' = 0x05 -'6' = 0x06 -'6' = 0x06 -'7' = 0x07 -'7' = 0x07 -'8' = 0x08 -'8' = 0x08 -'9' = 0x09 -'9' = 0x09 -'A' = 0x0A -'A' = 0x0A -'B' = 0x0B -'B' = 0x0B -'C' = 0x0C -'C' = 0x0C -'D' = 0x0D -'D' = 0x0D -'E' = 0x0E -'E' = 0x0E -'F' = 0x0F -'F' = 0x0F -'G' = 0x10 -'G' = 0x10 -'H' = 0x11 -'H' = 0x11 -'I' = 0x12 -'I' = 0x12 -'J' = 0x13 -'J' = 0x13 -'K' = 0x14 -'K' = 0x14 -'L' = 0x15 -'L' = 0x15 -'M' = 0x16 -'M' = 0x16 -'N' = 0x17 -'N' = 0x17 -'O' = 0x18 -'O' = 0x18 -'P' = 0x19 -'P' = 0x19 -'Q' = 0x1A -'Q' = 0x1A -'R' = 0x1B -'R' = 0x1B -'S' = 0x1C -'S' = 0x1C -'T' = 0x1D -'T' = 0x1D -'U' = 0x1E -'U' = 0x1E -'V' = 0x1F -'V' = 0x1F -'W' = 0x20 -'W' = 0x20 -'X' = 0x21 -'X' = 0x21 -'Y' = 0x22 -'Y' = 0x22 -'Z' = 0x23 -'Z' = 0x23 -'a' = 0x24 -'b' = 0x25 -'c' = 0x26 -'d' = 0x27 -'e' = 0x28 -'f' = 0x29 -'g' = 0x2A -'h' = 0x2B -'i' = 0x2C -'j' = 0x2D -'k' = 0x2E -'l' = 0x2F -'m' = 0x30 -'n' = 0x31 -'o' = 0x32 -'p' = 0x33 -'q' = 0x34 -'r' = 0x35 -'s' = 0x36 -'t' = 0x37 -'u' = 0x38 -'v' = 0x39 -'w' = 0x3A -'x' = 0x3B -'y' = 0x3C -'z' = 0x3D -'\'' = 0x3E -'.' = 0x3F - -# Mario face US/EU menu string (Note: NOT multi-text, each char has a part of the face) -'☺' = 0x40, 0x41 - -'あ' = 0x40 -'い' = 0x41 -'う' = 0x42 -'え' = 0x43 -'お' = 0x44 -'か' = 0x45 -'き' = 0x46 -'く' = 0x47 -'け' = 0x48 -'こ' = 0x49 -'さ' = 0x4A -'し' = 0x4B -'す' = 0x4C -'せ' = 0x4D -'そ' = 0x4E -'た' = 0x4F -'ち' = 0x50 -'つ' = 0x51 -'て' = 0x52 -'と' = 0x53 -'な' = 0x54 -'に' = 0x55 -'ぬ' = 0x56 -'ね' = 0x57 -'の' = 0x58 -'は' = 0x59 -'ひ' = 0x5A -'ふ' = 0x5B -'へ' = 0x5C -'ほ' = 0x5D -'ま' = 0x5E -'み' = 0x5F -'む' = 0x60 -'め' = 0x61 -'も' = 0x62 -'や' = 0x63 -'ゆ' = 0x64 -'よ' = 0x65 -'ら' = 0x66 -'り' = 0x67 -'る' = 0x68 -'れ' = 0x69 -'ろ' = 0x6A -'わ' = 0x6B -'を' = 0x6C -'ん' = 0x6D -'。' = 0x6E -',' = 0x6F -'、' = 0x6F -'ア' = 0x70 -'イ' = 0x71 -'ウ' = 0x72 -'エ' = 0x73 -'オ' = 0x74 -'カ' = 0x75 -'キ' = 0x76 -'ク' = 0x77 -'ケ' = 0x78 -'コ' = 0x79 -'サ' = 0x7A -'シ' = 0x7B -'ス' = 0x7C -'セ' = 0x7D -'ソ' = 0x7E -'タ' = 0x7F -'チ' = 0x80 -'ツ' = 0x81 -'テ' = 0x82 -'ト' = 0x83 -'ナ' = 0x84 -'ニ' = 0x85 -'ヌ' = 0x86 -'ネ' = 0x87 -'ノ' = 0x88 -'ハ' = 0x89 -'ヒ' = 0x8A -'フ' = 0x8B -'ヘ' = 0x8C -'ホ' = 0x8D -'マ' = 0x8E -'ミ' = 0x8F -'ム' = 0x90 -'メ' = 0x91 -'モ' = 0x92 -'ヤ' = 0x93 -'ユ' = 0x94 -'ヨ' = 0x95 -'ラ' = 0x96 -'リ' = 0x97 -'ル' = 0x98 -'レ' = 0x99 -'ロ' = 0x9A -'ワ' = 0x9B -# 0x9C is unused, only defined in jp menu char lut -'ヲ' = 0x9C -'ン' = 0x9D -' ' = 0x9E -' ' = 0x9E -'-' = 0x9F -'ー' = 0x9F -'ぇ' = 0xA0 -'っ' = 0xA1 -'ゃ' = 0xA2 -'ゅ' = 0xA3 -'ょ' = 0xA4 -'ぁ' = 0xA5 -'ぃ' = 0xA6 -'ぅ' = 0xA7 -'ぉ' = 0xA8 -'ェ' = 0xD0 -'ッ' = 0xD1 -'ャ' = 0xD2 -'ュ' = 0xD3 -'ョ' = 0xD4 -'ァ' = 0xD5 -'ィ' = 0xD6 -'ゥ' = 0xD7 -'ォ' = 0xD8 -'[%]' = 0xE0 -'(' = 0xE1 -'(' = 0xE1 -')(' = 0xE2 -')(' = 0xE2 -')' = 0xE3 -')' = 0xE3 -'+' = 0xE4 -'↔' = 0xE4 -'&' = 0xE5 -':' = 0xE6 -'゛' = 0xF0 -'゜' = 0xF1 -'!' = 0xF2 -'!' = 0xF2 -'%' = 0xF3 -'%' = 0xF3 -'?' = 0xF4 -'?' = 0xF4 -'『' = 0xF5 -'』' = 0xF6 -'~' = 0xF7 -'~' = 0xF7 -'…' = 0xF8 -'$' = 0xF9 -'★' = 0xFA -'×' = 0xFB -'・' = 0xFC -'☆' = 0xFD -'\n' = 0xFE - -# hiragana or katakana with dakuten -'が' = 0xF0, 0x45 -'ぎ' = 0xF0, 0x46 -'ぐ' = 0xF0, 0x47 -'げ' = 0xF0, 0x48 -'ご' = 0xF0, 0x49 -'ざ' = 0xF0, 0x4A -'じ' = 0xF0, 0x4B -'ず' = 0xF0, 0x4C -'ぜ' = 0xF0, 0x4D -'ぞ' = 0xF0, 0x4E -'だ' = 0xF0, 0x4F -'ぢ' = 0xF0, 0x50 -'づ' = 0xF0, 0x51 -'で' = 0xF0, 0x52 -'ど' = 0xF0, 0x53 -'ば' = 0xF0, 0x59 -'び' = 0xF0, 0x5A -'ぶ' = 0xF0, 0x5B -'べ' = 0xF0, 0x5C -'ぼ' = 0xF0, 0x5D -'ガ' = 0xF0, 0x75 -'ギ' = 0xF0, 0x76 -'グ' = 0xF0, 0x77 -'ゲ' = 0xF0, 0x78 -'ゴ' = 0xF0, 0x79 -'ザ' = 0xF0, 0x7A -'ジ' = 0xF0, 0x7B -'ズ' = 0xF0, 0x7C -'ゼ' = 0xF0, 0x7D -'ゾ' = 0xF0, 0x7E -'ダ' = 0xF0, 0x7F -'ヂ' = 0xF0, 0x80 -'ヅ' = 0xF0, 0x81 -'デ' = 0xF0, 0x82 -'ド' = 0xF0, 0x83 -'バ' = 0xF0, 0x89 -'ビ' = 0xF0, 0x8A -'ブ' = 0xF0, 0x8B -'ベ' = 0xF0, 0x8C -'ボ' = 0xF0, 0x8D - -# hiragana or katakana with handakuten -'ぱ' = 0xF1, 0x59 -'ぴ' = 0xF1, 0x5A -'ぷ' = 0xF1, 0x5B -'ぺ' = 0xF1, 0x5C -'ぽ' = 0xF1, 0x5D -'パ' = 0xF1, 0x89 -'ピ' = 0xF1, 0x8A -'プ' = 0xF1, 0x8B -'ペ' = 0xF1, 0x8C -'ポ' = 0xF1, 0x8D - -# overwritten US symbols -# these symbols overwrite -# a previous symbol. -'^' = 0x50 -'|' = 0x51 -'<' = 0x52 -'>' = 0x53 -'[A]' = 0x54 -'[B]' = 0x55 -'[C]' = 0x56 -'[Z]' = 0x57 -'[R]' = 0x58 -'/' = 0xD0 - -# multi-text US symbols -'the' = 0xD1 -'you' = 0xD2 - -# EU ROM symbols -'à' = 0x60 -'â' = 0x61 -'ä' = 0x62 -'À' = 0x64 -'Â' = 0x65 -'Ä' = 0x66 -'è' = 0x70 -'ê' = 0x71 -'ë' = 0x72 -'é' = 0x73 -'È' = 0x74 -'Ê' = 0x75 -'Ë' = 0x76 -'É' = 0x77 -'ù' = 0x80 -'û' = 0x81 -'ü' = 0x82 -'Ù' = 0x84 -'Û' = 0x85 -'Ü' = 0x86 -'ô' = 0x91 -'ö' = 0x92 -'Ô' = 0x95 -'Ö' = 0x96 -'î' = 0xA1 -'ï' = 0xA2 -'ß' = 0xEC -'Ç' = 0xED -'ç' = 0xEE -'„' = 0xF0 diff --git a/charmap_menu.txt b/charmap_menu.txt deleted file mode 100644 index 7642e737b..000000000 --- a/charmap_menu.txt +++ /dev/null @@ -1,30 +0,0 @@ -# Menu HUD chars, only used in JP -# Char values used by text_menu_strings.h.in -'フ' = 0x00 -'ァ' = 0x01 -'イ' = 0x02 -'ル' = 0x03 -'セ' = 0x04 -'レ' = 0x05 -'ク' = 0x06 -'ト' = 0x07 -'を' = 0x08 -'コ' = 0x09 -'ピ' = 0x0A -'ー' = 0x0B -'す' = 0x0C -'る' = 0x0D -'け' = 0x0E -'マ' = 0x0F -'リ' = 0x10 -'オ' = 0x11 -'ス' = 0x12 -'ア' = 0x13 -'み' = 0x14 -'ど' = 0x15 -'の' = 0x16 -'?' = 0x17 -'サ' = 0x18 -'ウ' = 0x19 -'ン' = 0x1A -'ド' = 0x1B diff --git a/defines.mk b/defines.mk index 02c16c1a4..8fd5ed94c 100644 --- a/defines.mk +++ b/defines.mk @@ -5,13 +5,13 @@ # Build debug version DEBUG ?= 0 # Enable extended options menu by default -EXT_OPTIONS_MENU ?= 1 +EXT_OPTIONS_MENU ?= 0 # Enable debug options menu (Enabled if DEBUG=1) EXT_DEBUG_MENU ?= 0 # Enable better camera (Puppycam 2) -BETTERCAMERA ?= 1 +BETTERCAMERA ?= 0 # Enable cheats -CHEATS_ACTIONS ?= 1 +CHEATS_ACTIONS ?= 0 # Enable rumble functions (Originally in Shindou) RUMBLE_FEEDBACK ?= 1 # Disable no drawing distance by default diff --git a/include/config.h b/include/config.h index 2c443e156..377a7b52d 100644 --- a/include/config.h +++ b/include/config.h @@ -63,6 +63,7 @@ #include "config/config_camera.h" #include "config/config_collision.h" #include "config/config_graphics.h" +#include "config/config_language.h" #include "config/config_movement.h" // Screen Size Defines diff --git a/include/config/config_language.h b/include/config/config_language.h new file mode 100644 index 000000000..6dcff15a1 --- /dev/null +++ b/include/config/config_language.h @@ -0,0 +1,33 @@ +/** + * Adds support for multiple languages to the game. + */ +// #define MULTILANG + +/** + * Toggles for individual languages. Only works when MULTILANG is enabled. + * Note that English will always be enabled. + */ +#define ENABLE_FRENCH +#define ENABLE_GERMAN +// #define ENABLE_JAPANESE + +/** + * This define enables support for Japanese characters even when multilang or Japanese is not enabled. + * Requires a Japanese baserom. + */ +// #define JAPANESE_CHARACTERS + +/** + * This replaces translation specific defines to general ones to be used for more languages. + */ +//#define SIMPLE_MULTILANG_ASSETS + +#ifndef MULTILANG + #undef ENABLE_FRENCH + #undef ENABLE_GERMAN + #undef ENABLE_JAPANESE +#endif // !MULTILANG + +#ifdef ENABLE_JAPANESE + #define JAPANESE_CHARACTERS +#endif // ENABLE_JAPANESE diff --git a/include/eu_translation.h b/include/eu_translation.h deleted file mode 100644 index 196868250..000000000 --- a/include/eu_translation.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef EU_TRANSLATION_H -#define EU_TRANSLATION_H - -// EU changes most text to arrays for each language. This define allows these -// differences to be combined. -#ifdef VERSION_EU - #define LANGUAGE_ARRAY(cmd) cmd[LANGUAGE_FUNCTION] -#else - #define LANGUAGE_ARRAY(cmd) cmd -#endif - -extern void *dialog_table_eu_en[]; -extern void *course_name_table_eu_en[]; -extern void *act_name_table_eu_en[]; - -extern void *dialog_table_eu_fr[]; -extern void *course_name_table_eu_fr[]; -extern void *act_name_table_eu_fr[]; - -extern void *dialog_table_eu_de[]; -extern void *course_name_table_eu_de[]; -extern void *act_name_table_eu_de[]; - -#endif // EU_TRANSLATION_H diff --git a/include/qol_defines.h b/include/qol_defines.h index 465b105f4..12262f690 100644 --- a/include/qol_defines.h +++ b/include/qol_defines.h @@ -22,7 +22,7 @@ // --| Quality of life redone files /// Adds Zelda level select used on OOT, MM and Animal Forest /// Credits: (AloXado320) -#define ZELDA_STYLE_LEVEL_SELECT (0 || QOL_REDONE) +//#define ZELDA_STYLE_LEVEL_SELECT (0 || QOL_REDONE) /// Adds improved platform displacement with intertia #define PLATFORM_DISPLACEMENT_2 (0 || QOL_REDONE) /// Uses optimized shadows which are faster than vanilla diff --git a/include/segment_symbols.h b/include/segment_symbols.h index d2f788a72..41b29132f 100644 --- a/include/segment_symbols.h +++ b/include/segment_symbols.h @@ -116,11 +116,18 @@ DECLARE_SEGMENT(title_screen_bg_mio0) DECLARE_SEGMENT(debug_level_select_mio0) -#ifdef VERSION_EU -DECLARE_SEGMENT(translation_de_mio0) +#ifdef MULTILANG DECLARE_SEGMENT(translation_en_mio0) +#ifdef ENABLE_FRENCH DECLARE_SEGMENT(translation_fr_mio0) #endif +#ifdef ENABLE_GERMAN +DECLARE_SEGMENT(translation_de_mio0) +#endif +#ifdef ENABLE_JAPANESE +DECLARE_SEGMENT(translation_jp_mio0) +#endif +#endif #endif diff --git a/include/text_cheats_strings.h.in b/include/text_cheats_strings.h.in deleted file mode 100644 index c86b1cd02..000000000 --- a/include/text_cheats_strings.h.in +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef TEXT_CHEATS_STRINGS_H -#define TEXT_CHEATS_STRINGS_H - -#define TEXT_OPT_CHEATS _("CHEATS") -#define TEXT_OPT_CHEATS_WALKON _("WALK ON CHEATS") -#define TEXT_OPT_CHEATS_BLJANY _("BLJ ANYWHERE CHEAT") - -#if defined(VERSION_JP) || defined(VERSION_SH) - -// TODO: Actually translate this to JP - -#define TEXT_OPT_CHEAT0 _("ENABLE CHEATS") -#define TEXT_OPT_CHEAT1 _("MOON-JUMP (PRESS L)") -#define TEXT_OPT_CHEAT2 _("INFINITE HEALTH") -#define TEXT_OPT_CHEAT3 _("INFINITE LIVES") -#define TEXT_OPT_CHEAT4 _("INVINCIBLE PLAYER") -#define TEXT_OPT_CHEAT5 _("SUPER SPEED") -#define TEXT_OPT_CHEAT6 _("SUPER RESPONSIVE CONTROLS") -#define TEXT_OPT_CHEAT7 _("EXIT COURSE AT ANY TIME") -#define TEXT_OPT_CHEAT8 _("NO FALL DAMAGE") -#define TEXT_OPT_CHEAT9 _("PLAYER SIZE") -#define TEXT_OPT_CHEAT10 _("BLJ ANYWHERE CHEAT") -#define TEXT_OPT_CHEAT11 _("WALK ON CHEATS") - -#define TEXT_CHEAT_MSIZE0 _("NORMAL") -#define TEXT_CHEAT_MSIZE1 _("TINY") -#define TEXT_CHEAT_MSIZE2 _("HUGE") - -#define TEXT_CHEAT_BLJOPT0 _("DISABLED") -#define TEXT_CHEAT_BLJOPT1 _("PRESSING") -#define TEXT_CHEAT_BLJOPT2 _("HOLDING") - -#define TEXT_CHEAT_BLJANY0 _("BLJ TOGGLE") -#define TEXT_CHEAT_BLJANY1 _("BLJ START SPEED") - -#define TEXT_CHEAT_WALKON0 _("WALK ON LAVA") -#define TEXT_CHEAT_WALKON1 _("WALK ON QUICKSAND") -#define TEXT_CHEAT_WALKON2 _("WALK ON WATER") -#define TEXT_CHEAT_WALKON3 _("WALK ON GAS") -#define TEXT_CHEAT_WALKON4 _("WALK ON SLOPE") -#define TEXT_CHEAT_WALKON5 _("WALK ON DEATH BARRIER") - -#else // VERSION - -#define TEXT_OPT_CHEAT0 _("Enable cheats") -#define TEXT_OPT_CHEAT1 _("Moon-jump (Press L)") -#define TEXT_OPT_CHEAT2 _("Infinite health") -#define TEXT_OPT_CHEAT3 _("Infinite lives") -#define TEXT_OPT_CHEAT4 _("Invincible player") -#define TEXT_OPT_CHEAT5 _("Super speed") -#define TEXT_OPT_CHEAT6 _("Super responsive controls") -#define TEXT_OPT_CHEAT7 _("Exit course at any time") -#define TEXT_OPT_CHEAT8 _("No fall damage") -#define TEXT_OPT_CHEAT9 _("Player size") -#define TEXT_OPT_CHEAT10 _("BLJ anywhere cheat") -#define TEXT_OPT_CHEAT11 _("Walk on cheats") - -#define TEXT_CHEAT_MSIZE0 _("Normal") -#define TEXT_CHEAT_MSIZE1 _("Tiny") -#define TEXT_CHEAT_MSIZE2 _("Huge") - -#define TEXT_CHEAT_BLJOPT0 _("Disabled") -#define TEXT_CHEAT_BLJOPT1 _("Pressing") -#define TEXT_CHEAT_BLJOPT2 _("Holding") - -#define TEXT_CHEAT_BLJANY0 _("BLG toggle") -#define TEXT_CHEAT_BLJANY1 _("BLJ start speed") - -#define TEXT_CHEAT_WALKON0 _("Walk on lava") -#define TEXT_CHEAT_WALKON1 _("Walk on quicksand") -#define TEXT_CHEAT_WALKON2 _("Walk on water") -#define TEXT_CHEAT_WALKON3 _("Walk on gas") -#define TEXT_CHEAT_WALKON4 _("Walk on slope") -#define TEXT_CHEAT_WALKON5 _("Walk on death barrier") - -#endif - -#endif // TEXT_CHEATS_STRINGS_H diff --git a/include/text_debug_strings.h.in b/include/text_debug_strings.h.in deleted file mode 100644 index 182c2e26f..000000000 --- a/include/text_debug_strings.h.in +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef TEXT_DEBUG_STRINGS_H -#define TEXT_DEBUG_STRINGS_H - -#define TEXT_OPT_DEBUG _("DEBUG") -#define TEXT_OPT_DEBUG_WARP _("WARP DEBUG") - -#if defined(VERSION_JP) || defined(VERSION_SH) -// TODO: Actually translate this to JP -#define TEXT_OPT_DEBUG0 _("SIMPLE DEBUG DISPLAY") -#define TEXT_OPT_DEBUG1 _("COMPLEX DEBUG DISPLAY") -#define TEXT_OPT_DEBUG2 _("LEVEL SELECT") -#define TEXT_OPT_DEBUG3 _("FREE MOVEMENT (PRESS L)") -#define TEXT_OPT_DEBUG4 _("DEBUG CAP CHANGER") -#define TEXT_OPT_DEBUG5 _("SHOW PROFILER") -#define TEXT_OPT_DEBUG6 _("SHOW FPS") -#define TEXT_OPT_DEBUG7 _("COMPLETE SAVE") -#define TEXT_OPT_DEBUG8 _("WARP DEBUG") - -#define TEXT_DEBUG_WARP0 _("WARP TO ENDING") -#define TEXT_DEBUG_WARP1 _("WARP TO CREDITS") -#define TEXT_DEBUG_WARP2 _("WARP TO LEVEL SUCCESS") -#define TEXT_DEBUG_WARP3 _("WARP TO LEVEL FAILURE") - -#else -#define TEXT_OPT_DEBUG0 _("Simple Debug Display") -#define TEXT_OPT_DEBUG1 _("Complex Debug Display") -#define TEXT_OPT_DEBUG2 _("Level Select") -#define TEXT_OPT_DEBUG3 _("Free Movement (Press L)") -#define TEXT_OPT_DEBUG4 _("Debug Cap Changer") -#define TEXT_OPT_DEBUG5 _("Show Profiler") -#define TEXT_OPT_DEBUG6 _("Show FPS") -#define TEXT_OPT_DEBUG7 _("Complete Save") -#define TEXT_OPT_DEBUG8 _("Warp Debug") - -#define TEXT_DEBUG_WARP0 _("Warp to Ending") -#define TEXT_DEBUG_WARP1 _("Warp to Credits") -#define TEXT_DEBUG_WARP2 _("Warp to Level Success") -#define TEXT_DEBUG_WARP3 _("Warp to Level Failure") - -#endif - -#endif // TEXT_DEBUG_STRINGS_H diff --git a/include/text_menu_strings.h.in b/include/text_menu_strings.h.in deleted file mode 100644 index 3ac477eb8..000000000 --- a/include/text_menu_strings.h.in +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TEXT_MENU_STRINGS_H -#define TEXT_MENU_STRINGS_H - -// These strings use a different table defined in menu_hud_lut -// Unlike text_strings.h.in, the charmap is different and -// uses char values from charmap_menu.txt - -/** - * File Select JP HUD Text - */ -#define TEXT_JPHUD_MARIO _("マリオ") -#define TEXT_JPHUD_SELECT_FILE _("ファイルセレクト") -#define TEXT_JPHUD_CHECK_FILE _("どのスコアをみる?") -#define TEXT_JPHUD_COPY_FILE _("ファイルコピーする") -#define TEXT_JPHUD_ERASE_FILE _("ファイルけす") -#define TEXT_JPHUD_SOUND_SELECT _("サウンドセレクト") - -#endif // TEXT_MENU_STRINGS_H diff --git a/include/text_options_strings.h.in b/include/text_options_strings.h.in deleted file mode 100644 index fee3c600f..000000000 --- a/include/text_options_strings.h.in +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef TEXT_OPTIONS_STRINGS_H -#define TEXT_OPTIONS_STRINGS_H - -/* Extended options menu text */ - -// Menu title strings - -#define TEXT_OPT_OPTIONS _("OPTIONS") -#define TEXT_OPT_CAMERA _("CAMERA") -#define TEXT_OPT_CONTROLS _("CONTROLS") -#define TEXT_OPT_VIDEO _("DISPLAY") -#define TEXT_OPT_AUDIO _("SOUND") -#define TEXT_OPT_SETTINGS _("SETTINGS") - -// Markers - -#define TEXT_OPT_L_HIGHLIGHT _(">") -#define TEXT_OPT_R_HIGHLIGHT _("<") -#define TEXT_OPT_UNBOUND _("NONE") - -// Language specific strings - -#if defined(VERSION_JP) || defined(VERSION_SH) - -// TODO: Actually translate this to JP - -// No . in JP - -#define TEXT_OPT_PRESSKEY _("・・・") - -// Option strings - -#define TEXT_OPT_BUTTON1 _("R OPTIONS") -#define TEXT_OPT_BUTTON2 _("R RETURN") - -#define TEXT_OPT_ENABLED _("ENABLED") -#define TEXT_OPT_DISABLED _("DISABLED") - -#define TEXT_OPT_VANILLA_CAM _("VANILLA CAMERA") -#define TEXT_OPT_LAKITU_PARALLEL _("PARALLEL LAKITU CAM") -#define TEXT_OPT_SR_MARIO_CAM _("STAR ROAD MARIO CAM") -#define TEXT_OPT_CAM_C_UP_SOUNDS _("CAMERA SOUND EFFECTS") -#define TEXT_OPT_CAM_PARALLEL_COL _("PARALLEL CAM COLLISION") - -#define TEXT_OPT_PUPPYON _("PUPPYCAM 2") -#define TEXT_OPT_PUPPYCAM _("PUPPY CAMERA") -#define TEXT_OPT_CAMMOUSE _("CAMERA MOUSE CONTROL") -#define TEXT_OPT_CAMX _("CAMERA X SENSITIVITY") -#define TEXT_OPT_CAMY _("CAMERA Y SENSITIVITY") -#define TEXT_OPT_INVERTX _("INVERT X AXIS") -#define TEXT_OPT_INVERTY _("INVERT Y AXIS") -#define TEXT_OPT_CAMC _("CAMERA CENTRE SPEED") -#define TEXT_OPT_ANALOGUE _("ANALOGUE CAMERA") -#define TEXT_OPT_CAMSCHEME _("CONTROL SCHEME") -#define TEXT_OPT_OPA_TYPE _("OPACITY TYPE") -#define TEXT_OPT_DBG_CAM _("DEBUG CAMERA") - -#define TEXT_OPT_CAM_SCH1 _("DOUBLE TAP") -#define TEXT_OPT_CAM_SCH2 _("SINGLE PRESS") -#define TEXT_OPT_CAM_SCH3 _("CLASSIC") - -#define TEXT_OPT_OPA_T1 _("NONE") -#define TEXT_OPT_OPA_T2 _("FADE IN-OUT") -#define TEXT_OPT_OPA_T3 _("POP IN-OUT") - -#define TEXT_OPT_TEXFILTER _("TEXTURE FILTERING") -#define TEXT_OPT_FSCREEN _("FULLSCREEN") -#define TEXT_OPT_NEAREST _("NEAREST") -#define TEXT_OPT_LINEAR _("LINEAR") -#define TEXT_OPT_MVOLUME _("MASTER VOLUME") -#define TEXT_OPT_MUSVOLUME _("MUSIC VOLUME") -#define TEXT_OPT_SFXVOLUME _("SFX VOLUME") -#define TEXT_OPT_ENVVOLUME _("ENV VOLUME") -#define TEXT_OPT_VSYNC _("VERTICAL SYNC") -#define TEXT_OPT_APPLY _("APPLY") -#define TEXT_OPT_RESETWND _("RESET WINDOW") - -#define TEXT_OPT_HUD _("HUD") -#define TEXT_OPT_MOUSE _("MOUSE") - -#define TEXT_BIND_A _("A BUTTON") -#define TEXT_BIND_B _("B BUTTON") -#define TEXT_BIND_START _("START BUTTON") -#define TEXT_BIND_L _("L TRIGGER") -#define TEXT_BIND_R _("R TRIGGER") -#define TEXT_BIND_Z _("Z TRIGGER") -#define TEXT_BIND_C_UP _("C-UP") -#define TEXT_BIND_C_DOWN _("C-DOWN") -#define TEXT_BIND_C_LEFT _("C-LEFT") -#define TEXT_BIND_C_RIGHT _("C-RIGHT") -#define TEXT_BIND_D_UP _("D-UP") -#define TEXT_BIND_D_DOWN _("D-DOWN") -#define TEXT_BIND_D_LEFT _("D-LEFT") -#define TEXT_BIND_D_RIGHT _("D-RIGHT") -#define TEXT_BIND_UP _("STICK UP") -#define TEXT_BIND_DOWN _("STICK DOWN") -#define TEXT_BIND_LEFT _("STICK LEFT") -#define TEXT_BIND_RIGHT _("STICK RIGHT") -#define TEXT_OPT_DEADZONE _("STICK DEADZONE") -#define TEXT_OPT_RUMBLE _("RUMBLE STRENGTH") - -#else // VERSION - -// Markers - -#define TEXT_OPT_PRESSKEY _("...") - -// Option strings - -#define TEXT_OPT_BUTTON1 _("[R] Options") -#define TEXT_OPT_BUTTON2 _("[R] Return") - -#define TEXT_OPT_ENABLED _("Enabled") -#define TEXT_OPT_DISABLED _("Disabled") - -#define TEXT_OPT_VANILLA_CAM _("VANILLA CAMERA") -#define TEXT_OPT_LAKITU_PARALLEL _("Parallel Lakitu Cam") -#define TEXT_OPT_SR_MARIO_CAM _("Star Road Mario Cam") -#define TEXT_OPT_CAM_C_UP_SOUNDS _("Camera Sound Effects") -#define TEXT_OPT_CAM_PARALLEL_COL _("Parallel Cam Collision") - -#define TEXT_OPT_PUPPYON _("PuppyCam 2") -#define TEXT_OPT_PUPPYCAM _("PUPPY CAMERA") -#define TEXT_OPT_CAMMOUSE _("Camera Mouse Control") -#define TEXT_OPT_CAMX _("Camera X Sensitivity") -#define TEXT_OPT_CAMY _("Camera Y Sensitivity") -#define TEXT_OPT_INVERTX _("Invert X Axis") -#define TEXT_OPT_INVERTY _("Invert Y Axis") -#define TEXT_OPT_CAMC _("Camera Centre Speed") -#define TEXT_OPT_ANALOGUE _("Analogue Camera") -#define TEXT_OPT_CAMSCHEME _("Control Scheme") -#define TEXT_OPT_OPA_TYPE _("Opacity Type") -#define TEXT_OPT_DBG_CAM _("Debug Camera") - -#define TEXT_OPT_CAM_SCH1 _("Double Tap") -#define TEXT_OPT_CAM_SCH2 _("Single Press") -#define TEXT_OPT_CAM_SCH3 _("Classic") - -#define TEXT_OPT_OPA_T1 _("None") -#define TEXT_OPT_OPA_T2 _("Fade In-Out") -#define TEXT_OPT_OPA_T3 _("Pop In-Out") - -#define TEXT_OPT_TEXFILTER _("Texture Filtering") -#define TEXT_OPT_FSCREEN _("Fullscreen") -#define TEXT_OPT_NEAREST _("Nearest") -#define TEXT_OPT_LINEAR _("Linear") -#define TEXT_OPT_MVOLUME _("Master Volume") -#define TEXT_OPT_MUSVOLUME _("Music Volume") -#define TEXT_OPT_SFXVOLUME _("Sfx Volume") -#define TEXT_OPT_ENVVOLUME _("Env Volume") -#define TEXT_OPT_VSYNC _("Vertical Sync") -#define TEXT_OPT_APPLY _("Apply") -#define TEXT_OPT_RESETWND _("Reset Window") - -#define TEXT_OPT_HUD _("HUD") -#define TEXT_OPT_MOUSE _("Mouse") - -#define TEXT_BIND_A _("A Button") -#define TEXT_BIND_B _("B Button") -#define TEXT_BIND_START _("Start Button") -#define TEXT_BIND_L _("L Trigger") -#define TEXT_BIND_R _("R Trigger") -#define TEXT_BIND_Z _("Z Trigger") -#define TEXT_BIND_C_UP _("C-Up") -#define TEXT_BIND_C_DOWN _("C-Down") -#define TEXT_BIND_C_LEFT _("C-Left") -#define TEXT_BIND_C_RIGHT _("C-Right") -#define TEXT_BIND_D_UP _("D-Up") -#define TEXT_BIND_D_DOWN _("D-Down") -#define TEXT_BIND_D_LEFT _("D-Left") -#define TEXT_BIND_D_RIGHT _("D-Right") -#define TEXT_BIND_UP _("Stick Up") -#define TEXT_BIND_DOWN _("Stick Down") -#define TEXT_BIND_LEFT _("Stick Left") -#define TEXT_BIND_RIGHT _("Stick Right") -#define TEXT_OPT_DEADZONE _("Stick Deadzone") -#define TEXT_OPT_RUMBLE _("Rumble Strength") - -#endif // VERSION - -#endif // TEXT_OPTIONS_STRINGS_H diff --git a/include/text_strings.h.in b/include/text_strings.h.in deleted file mode 100644 index ce5a293ad..000000000 --- a/include/text_strings.h.in +++ /dev/null @@ -1,502 +0,0 @@ -#ifndef TEXT_STRINGS_H -#define TEXT_STRINGS_H - -#include "text_menu_strings.h" - -#ifdef EXT_OPTIONS_MENU -#include "text_options_strings.h" -#endif - -#ifdef CHEATS_ACTIONS -#include "text_cheats_strings.h" -#endif - -#ifdef EXT_DEBUG_MENU -#include "text_debug_strings.h" -#endif - -/** - * Global Symbols - */ -#define TEXT_ZERO _("0") -#define TEXT_COIN _("$") -#define TEXT_STAR _("★") -#define TEXT_COIN_X _("$×") -#define TEXT_STAR_X _("★×") -#define TEXT_VARIABLE_X _("×") -#define TEXT_UNFILLED_STAR _("☆") - -/** - * Global Text - */ -// File Select -#define TEXT_NEW _("NEW") // New File Text -#define TEXT_4DASHES _("----") // Used in Score File Menu - -// Ingame Menu -#define TEXT_PAUSE _("PAUSE") // Pause text, Castle Courses -#define TEXT_HUD_CONGRATULATIONS _("CONGRATULATIONS") // Course Complete Text, Bowser Courses - -#ifdef TARGET_N64 -// Memory Expansion Error Screen -#define TEXT_CONSOLE_8MB _("If you're using an N64 console, then you will need to buy an\nExpansion Pak to play this ROM hack.") -#define TEXT_PJ64 _("If you are using PJ64 1.6, go to:\nOptions > Settings > Rom Settings Tab > Memory Size\nthen select 8 MB from the drop-down box.") -#define TEXT_PJ64_2 _("If you are using PJ64 2.X, go to:\nOptions > Settings > Config: > Memory Size, select 8 MB") -#endif - -#if defined(VERSION_JP) || defined(VERSION_SH) - -/** - * File Select Text - */ -// Main Screens -// JPHUD menu strings are defined in "text_menu_strings.h.in" -#define TEXT_MARIO TEXT_JPHUD_MARIO // View Score Menu -#define TEXT_SELECT_FILE TEXT_JPHUD_SELECT_FILE -#define TEXT_CHECK_FILE TEXT_JPHUD_CHECK_FILE -#define TEXT_COPY_FILE TEXT_JPHUD_COPY_FILE -#define TEXT_ERASE_FILE TEXT_JPHUD_ERASE_FILE -#define TEXT_SOUND_SELECT TEXT_JPHUD_SOUND_SELECT - -#define TEXT_FILE_MARIO_A _("マリオA") -#define TEXT_FILE_MARIO_B _("マリオB") -#define TEXT_FILE_MARIO_C _("マリオC") -#define TEXT_FILE_MARIO_D _("マリオD") - -// Menu Options -#define TEXT_SCORE _("スコア") -#define TEXT_COPY _("コピー") -#define TEXT_ERASE _("けす") - -// Sound Options -#define TEXT_STEREO _("ステレオ") -#define TEXT_MONO _("モノラル") -#define TEXT_HEADSET _("ヘッドホン") - -// Misc Menu Text -#define TEXT_SAVED_DATA_EXISTS _("ファイルにデータがはいってます") -#define TEXT_NO_SAVED_DATA_EXISTS _("ファイルにデータがありません") - -// Inside a Menu -#define TEXT_RETURN _("もどる") -#define TEXT_CHECK_SCORE _("スコアをみる") -#define TEXT_COPY_FILE_BUTTON _("ファイルコピー") -#define TEXT_ERASE_FILE_BUTTON _("ファイルけす") - -// Score Menu -#define TEXT_HI_SCORE _("ハイスコア") -#define TEXT_MY_SCORE _("マイスコア") -#define TEXT_SCORE_MARIO_A _("マリオA") -#define TEXT_SCORE_MARIO_B _("マリオB") -#define TEXT_SCORE_MARIO_C _("マリオC") -#define TEXT_SCORE_MARIO_D _("マリオD") - -// Copy Menu -#define TEXT_COPY_IT_TO_WHERE _("どこにコピーしますか?") -#define TEXT_COPYING_COMPLETED _("コピーおわりました") -#define TEXT_NO_FILE_TO_COPY_FROM _("からのファイルがありません") - -// Erase Menu -#define TEXT_SURE _("ほんと?") -#define TEXT_YES _("はい") -#define TEXT_NO _("いいえ") -#define TEXT_FILE_MARIO_A_JUST_ERASED _("マリオAをけしました") - -/** - * Menus Text (Pause, Course Completed) - */ -// Main Courses -#define TEXT_COURSE _("コース") -#define TEXT_MYSCORE _("マイスコア") -#define TEXT_CONTINUE _("つづけて マリオする?") -#define TEXT_EXIT_GAME _("ゲームをしゅうりょうする") -#define TEXT_EXIT_COURSE _("コースからでる?") -#define TEXT_CAMERA_ANGLE_R _("Rボタンのカメラきりかえ") - -// Camera Options -#define TEXT_LAKITU_MARIO _("ジュゲム↔マリオ") -#define TEXT_LAKITU_STOP _("ジュゲム↔ストップ") -#define TEXT_NORMAL_UPCLOSE _("(おすすめ)(リアル)") -#define TEXT_NORMAL_FIXED _("(おすすめ)(とまる)") - -// Course Completed Misc Text -#define TEXT_CATCH _("キャッチ!") -#define TEXT_CLEAR _("クリア!") -#define TEXT_HUD_HI_SCORE _("HISCORE") - -// Save Options -#define TEXT_SAVE_AND_CONTINUE _("セーブしてつづける?") -#define TEXT_SAVE_AND_QUIT _("セーブしておわる?") -#define TEXT_SAVE_EXIT_GAME _("ゲームをやめる?") -#define TEXT_CONTINUE_WITHOUT_SAVING _("セーブしないでつづける?") - -/** - * Ending Peach cutscene text. - */ -#define TEXT_FILE_MARIO_EXCLAMATION _("マリオ!!") -#define TEXT_POWER_STARS_RESTORED _("おしろにスターが もどったのね") -#define TEXT_THANKS_TO_YOU _("みんな あなたのおかげだわ!") -#define TEXT_THANK_YOU_MARIO _("ありがとう マリオ") -#define TEXT_SOMETHING_SPECIAL _("なにか おれいをしなくちゃ・・") -#define TEXT_LISTEN_EVERYBODY _("さあ みんな") -#define TEXT_LETS_HAVE_CAKE _("おいしいケーキを やきましょう") -#define TEXT_FOR_MARIO _("マリオの ために・・・") -#define TEXT_FILE_MARIO_QUESTION _("マリオ?") - -#endif - -#if defined(VERSION_US) || defined(VERSION_EU) - -/** - * File Select Text - */ -// Main Screens -#define TEXT_MARIO _("MARIO") // View Score Menu -#define TEXT_SELECT_FILE _("SELECT FILE") -#define TEXT_CHECK_FILE _("CHECK FILE") -#define TEXT_COPY_FILE _("COPY FILE") -#define TEXT_ERASE_FILE _("ERASE FILE") -#define TEXT_SOUND_SELECT _("SOUND SELECT") -#define TEXT_FILE_MARIO_A _("MARIO A") -#define TEXT_FILE_MARIO_B _("MARIO B") -#define TEXT_FILE_MARIO_C _("MARIO C") -#define TEXT_FILE_MARIO_D _("MARIO D") - -// Menu Options -#define TEXT_SCORE _("SCORE") -#define TEXT_COPY _("COPY") -#define TEXT_ERASE _("ERASE") - -// Sound Options -#define TEXT_STEREO _("STEREO") -#define TEXT_MONO _("MONO") -#define TEXT_HEADSET _("HEADSET") - -// Misc Menu Text -#define TEXT_SAVED_DATA_EXISTS _("SAVED DATA EXITS") // Misspell -#define TEXT_NO_SAVED_DATA_EXISTS _("NO SAVED DATA EXISTS") - -// Inside a Menu -#define TEXT_RETURN _("RETURN") -#define TEXT_CHECK_SCORE _("CHECK SCORE") -#define TEXT_COPY_FILE_BUTTON _("COPY FILE") -#define TEXT_ERASE_FILE_BUTTON _("ERASE FILE") - -// Score Menu -#define TEXT_HI_SCORE _("HI SCORE") -#define TEXT_MY_SCORE _("MY SCORE") -// Score Mario Text ("☺" is the Mario face defined in the US/EU menu char table) -#define TEXT_SCORE_MARIO_A _("☺A") -#define TEXT_SCORE_MARIO_B _("☺B") -#define TEXT_SCORE_MARIO_C _("☺C") -#define TEXT_SCORE_MARIO_D _("☺D") - -// Copy Menu -#define TEXT_COPY_IT_TO_WHERE _("COPY IT TO WHERE?") -#define TEXT_COPYING_COMPLETED _("COPYING COMPLETED") -#define TEXT_NO_FILE_TO_COPY_FROM _("NO EMPTY FILE") - -// Erase Menu -#define TEXT_SURE _("SURE?") -#define TEXT_YES _("YES") -#define TEXT_NO _("NO") -#define TEXT_FILE_MARIO_A_JUST_ERASED _("MARIO A JUST ERASED") - -/** - * Menus Text (Pause, Course Completed) - */ -// Main Courses -#define TEXT_COURSE _("COURSE") -#define TEXT_MYSCORE _("MYSCORE") -#define TEXT_CONTINUE _("CONTINUE") -#define TEXT_EXIT_COURSE _("EXIT COURSE") -#define TEXT_EXIT_GAME _("EXIT GAME") -#ifndef VERSION_EU // "R" text is different in EU -#define TEXT_CAMERA_ANGLE_R _("SET CAMERA ANGLE WITH R") -#endif - -// Camera Options -#define TEXT_LAKITU_MARIO _("LAKITU + MARIO") -#define TEXT_LAKITU_STOP _("LAKITU + STOP") -#define TEXT_NORMAL_UPCLOSE __("(NORMAL)(UP-CLOSE)") -#define TEXT_NORMAL_FIXED __("(NORMAL)(FIXED)") - -// Course Completed Misc Text -#define TEXT_CATCH _("CATCH") -#define TEXT_CLEAR _("CLEAR") -#define TEXT_HUD_HI_SCORE _("HI SCORE") - -// Save Options -#define TEXT_SAVE_AND_CONTINUE _("SAVE & CONTINUE") -#define TEXT_SAVE_AND_QUIT _("SAVE & QUIT") -#define TEXT_SAVE_EXIT_GAME _("SAVE & EXIT GAME") -#define TEXT_CONTINUE_WITHOUT_SAVING _("CONTINUE, DON'T SAVE") - -/** - * Ending Peach cutscene text. - */ -#define TEXT_FILE_MARIO_EXCLAMATION _("Mario!") -#define TEXT_POWER_STARS_RESTORED __("The power of the Stars is restored to the castle...") -#define TEXT_THANKS_TO_YOU __("...and it's all thanks to you!") -#define TEXT_THANK_YOU_MARIO __("Thank you, Mario!") -#define TEXT_SOMETHING_SPECIAL __("We have to do something special for you...") -#define TEXT_LISTEN_EVERYBODY _("Listen, everybody,") -#define TEXT_LETS_HAVE_CAKE _("let's bake a delicious cake...") -#define TEXT_FOR_MARIO _("...for Mario...") -#define TEXT_FILE_MARIO_QUESTION _("Mario!") - -#endif - -#ifdef VERSION_EU - -/** - * File Select Text - */ -#define TEXT_RETURN_FR _("RETOUR") -#define TEXT_RETURN_DE _("ZURÜCK") - -#define TEXT_CHECK_SCORE_FR _("SCORE") -#define TEXT_CHECK_SCORE_DE _("LEISTUNG") - -#define TEXT_COPY_FILE_FR _("COPIER") -#define TEXT_COPY_FILE_DE _("KOPIEREN") - -#define TEXT_ERASE_FILE_FR _("EFFACER") -#define TEXT_ERASE_FILE_DE _("LÖSCHEN") - -#define TEXT_SELECT_FILE_FR _("CHOISIR FICHIER") -#define TEXT_SELECT_FILE_DE _("WwHLE SPIEL") - -#define TEXT_SCORE_FR _("SCORE") -#define TEXT_SCORE_DE _("LEISTUNG") - -#define TEXT_COPY_FR _("COPIER") -#define TEXT_COPY_DE _("KOPIEREN") - -#define TEXT_ERASE_FR _("EFFACER") -#define TEXT_ERASE_DE _("LÖSCHEN") - -#define TEXT_OPTION _("OPTION") // new in EU -#define TEXT_OPTION_FR _("OPTION") -#define TEXT_OPTION_DE _("OPTIONEN") - -#define TEXT_CHECK_FILE_FR _("VOIR SCORE") -#define TEXT_CHECK_FILE_DE _("VON WELCHEM SPIEL") - -#define TEXT_NO_SAVED_DATA_EXISTS_FR _("AUCUNE SAUVEGARDE DISPONIBLE") -#define TEXT_NO_SAVED_DATA_EXISTS_DE _("KEIN SPIEL VORHANDEN") - -#define TEXT_COPY_FILE_BUTTON_FR _("COPIER FICHIER") -#define TEXT_COPY_FILE_BUTTON_DE _("SPIEL KOPIEREN") - -#define TEXT_COPY_IT_TO_WHERE_FR _("COPIER SUR?") -#define TEXT_COPY_IT_TO_WHERE_DE _("WOHIN KOPIEREN?") - -#define TEXT_COPYING_COMPLETED_FR _("COPIE ACHEVEÉ") -#define TEXT_COPYING_COMPLETED_DE _("SPIEL KOPIERT") - -#define TEXT_SAVED_DATA_EXISTS_FR _("SAVEGARDE EXISTANTE") -#define TEXT_SAVED_DATA_EXISTS_DE _("BEREITS BELEGT") - -#define TEXT_NO_FILE_TO_COPY_FROM_FR _("AUCUN FICHIER VIDE") -#define TEXT_NO_FILE_TO_COPY_FROM_DE _("KEIN PLATZ VORHANDEN") - -#define TEXT_YES_FR _("OUI") -#define TEXT_YES_DE _("JA") - -#define TEXT_NO_FR _("NON") -#define TEXT_NO_DE _("NEIN") - -#define TEXT_ERASE_FILE_BUTTON_FR _("EFFACER FICHIER") -#define TEXT_ERASE_FILE_BUTTON_DE _("SPIEL LxSCHEN") - -#define TEXT_SURE_FR _("OK?") -#define TEXT_SURE_DE _("SICHER?") - -#define TEXT_FILE_MARIO_A_JUST_ERASED_FR _("MARIO A EFFACÉ") -#define TEXT_FILE_MARIO_A_JUST_ERASED_DE _("MARIO A GELÖSCHT") - -#define TEXT_SOUND_SELECT_FR _("SON") -#define TEXT_SOUND_SELECT_DE _("SOUND") - -#define TEXT_LANGUAGE_SELECT _("LANGUAGE SELECT") // new in EU -#define TEXT_LANGUAGE_SELECT_FR _("SELECTION LANGUE") -#define TEXT_LANGUAGE_SELECT_DE _("WwHLE SPRACHE") - -#define TEXT_STEREO_FR _("STÉRÉO") -#define TEXT_MONO_FR _("MONO") -#define TEXT_HEADSET_FR _("CASQUE") - -#define TEXT_STEREO_DE _("STEREO") -#define TEXT_MONO_DE _("MONO") -#define TEXT_HEADSET_DE _("PHONES") - -#define TEXT_ENGLISH _("ENGLISH") -#define TEXT_FRENCH _("FRANÇAIS") -#define TEXT_GERMAN _("DEUTSCH") - -#define TEXT_HI_SCORE_FR _("MEILLEUR SCORE") -#define TEXT_HI_SCORE_DE _("BESTLEISTUNG") - -#define TEXT_MY_SCORE_FR _("MON SCORE") -#define TEXT_MY_SCORE_DE _("LEISTUNG") - -#define TEXT_NEW_FR _("VIDE") -#define TEXT_NEW_DE _("FREI") - - -/** - * Menus Text (Pause, Course Completed) - */ -// Main Courses -// English, "R" text is different -#define TEXT_CAMERA_ANGLE_R _("SET CAMERA ANGLE WITH [R]") -// French -#define TEXT_COURSE_FR _("NIVEAU") -#define TEXT_MY_SCORE_FR _("MON SCORE") -#define TEXT_CONTINUE_FR _("CONTINUER") -#define TEXT_EXIT_COURSE_FR _("QUITTER NIVEAU") -#define TEXT_EXIT_GAME_FR _("QUITTER JEU") -#define TEXT_CAMERA_ANGLE_R_FR _("RÉGLAGE CAMÉRA AVEC [R]") -// German -#define TEXT_COURSE_DE _("KURS") -#define TEXT_MY_SCORE_DE _("LEISTUNG") -#define TEXT_CONTINUE_DE _("WEITER") -#define TEXT_EXIT_COURSE_DE _("KURS VERLASSEN") -#define TEXT_EXIT_GAME_DE _("SPIEL VERLASSEN") -#define TEXT_CAMERA_ANGLE_R_DE _("KAMERA MIT [R] VERSTELLEN") - -// Camera Options -// French -#define TEXT_NORMAL_UPCLOSE_FR __("(NORMAL)(GROS-PLAN)") -#define TEXT_NORMAL_FIXED_FR __("(NORMAL)(FIXE)") -// German -#define TEXT_NORMAL_UPCLOSE_DE __("(NORMAL)(WEIT-ZOOM)") -#define TEXT_NORMAL_FIXED_DE __("(NORMAL)(STATIV)") - -// Course Completed Misc Text -// French -#define TEXT_HUD_HI_SCORE_FR _("MEILLEUR SCORE") -#define TEXT_HUD_CONGRATULATIONS_FR _("FELICITATIONS") -// German -#define TEXT_HUD_HI_SCORE_DE _("BESTLEISTUNG") -#define TEXT_HUD_CONGRATULATIONS_DE _("GRATULATION") - -// Save Options -// French -#define TEXT_SAVE_AND_CONTINUE_FR _("SAUVEGARDER & CONTINUER") -#define TEXT_SAVE_AND_QUIT_FR _("SAUVEGARDER & QUITTER") -#define TEXT_SAVE_EXIT_GAME_FR _("SAUVEGARDER & QUITTER JEU") -#define TEXT_CONTINUE_WITHOUT_SAVING_FR _("CONTINUER SANS SAUVEGARDER") -// German -#define TEXT_SAVE_AND_CONTINUE_DE _("SPEICHERN & WEITER") -#define TEXT_SAVE_AND_QUIT_DE _("SPEICHERN & ENDE") -#define TEXT_SAVE_EXIT_GAME_DE _("SPEICHERN & SPIEL VERLASSEN") -#define TEXT_CONTINUE_WITHOUT_SAVING_DE _("WEITER OHNE ZU SPEICHERN") - -/** - * Ending Peach cutscene text. - */ -// French -#define TEXT_POWER_STARS_RESTORED_FR _("Grâce aux étoiles, le château a retrouvé ses pouvoirs...") -#define TEXT_THANKS_TO_YOU_FR _("...et ceci grâce à toi!") -#define TEXT_THANK_YOU_MARIO_FR _("Merci, Mario!") -#define TEXT_SOMETHING_SPECIAL_FR _("Tu mérites une récompense...") -#define TEXT_COME_ON_EVERYBODY_FR _("Venez les amis...") -#define TEXT_LETS_HAVE_CAKE_FR _("Allons préparer un délicieux gâteau...") -#define TEXT_FOR_MARIO_FR _("...pour Mario...") -// German -#define TEXT_POWER_STARS_RESTORED_DE _("Die Macht der Sterne ruht wieder sicher im Schloss...") -#define TEXT_THANKS_TO_YOU_DE _("...und alles dank Deiner Hilfe!") -#define TEXT_THANK_YOU_MARIO_DE _("Vielen Dank, Mario!") -#define TEXT_SOMETHING_SPECIAL_DE _("Wir haben eine Überraschung für Dich...") -#define TEXT_COME_ON_EVERYBODY_DE _("Hört alle her...") -#define TEXT_LETS_HAVE_CAKE_DE _("Laßt uns einen leckeren Kuchen backen...") -#define TEXT_FOR_MARIO_DE _("...für Mario...") - -/** - * Course Table names for Score Menu Save view - */ -#define TEXT_MENU_BOB _(" 1 BOB-OMB BATTLEFIELD") -#define TEXT_MENU_WF _(" 2 WHOMP'S FORTRESS") -#define TEXT_MENU_JRB _(" 3 JOLLY ROGER BAY") -#define TEXT_MENU_CCM _(" 4 COOL, COOL MOUNTAIN") -#define TEXT_MENU_BBH _(" 5 BIG BOO'S HAUNT") -#define TEXT_MENU_HMC _(" 6 HAZY MAZE CAVE") -#define TEXT_MENU_LLL _(" 7 LETHAL LAVA LAND") -#define TEXT_MENU_SSL _(" 8 SHIFTING SAND LAND") -#define TEXT_MENU_DDD _(" 9 DIRE, DIRE DOCKS") -#define TEXT_MENU_SL _("10 SNOWMAN'S LAND") -#define TEXT_MENU_WDW _("11 WET-DRY WORLD") -#define TEXT_MENU_TTM _("12 TALL, TALL MOUNTAIN") -#define TEXT_MENU_THI _("13 TINY-HUGE ISLAND") -#define TEXT_MENU_TTC _("14 TICK TOCK CLOCK") -#define TEXT_MENU_RR _("15 RAINBOW RIDE") -#define TEXT_MENU_BITDW _(" BOWSER IN THE DARK WORLD") -#define TEXT_MENU_BITFS _(" BOWSER IN THE FIRE SEA") -#define TEXT_MENU_BITS _(" BOWSER IN THE SKY") -#define TEXT_MENU_PSS _(" THE PRINCESS'S SECRET SLIDE") -#define TEXT_MENU_COTMC _(" CAVERN OF THE METAL CAP") -#define TEXT_MENU_TOTWC _(" TOWER OF THE WING CAP") -#define TEXT_MENU_VCUTM _(" VANISH CAP UNDER THE MOAT") -#define TEXT_MENU_WMOTR _(" WING MARIO OVER THE RAINBOW") -#define TEXT_MENU_SA _(" THE SECRET AQUARIUM") -#define TEXT_MENU_NONE _("") -#define TEXT_MENU_STARS _(" CASTLE SECRET STARS") - -#define TEXT_MENU_BOB_FR _(" 1 BATAILLE DE BOB-OMB") -#define TEXT_MENU_WF_FR _(" 2 FORTERESSE DE WHOMP") -#define TEXT_MENU_JRB_FR _(" 3 BAIE DES PIRATES") -#define TEXT_MENU_CCM_FR _(" 4 MONTAGNE GLA-GLA") -#define TEXT_MENU_BBH_FR _(" 5 MANOIR DE BIG BOO") -#define TEXT_MENU_HMC_FR _(" 6 CAVERNE BRUMEUSE") -#define TEXT_MENU_LLL_FR _(" 7 LAVES FATALES") -#define TEXT_MENU_SSL_FR _(" 8 SABLES TROP MOUVANTS") -#define TEXT_MENU_DDD_FR _(" 9 AFFREUX BASSIN") -#define TEXT_MENU_SL_FR _("10 CHEZ LE ROI DES NEIGES") -#define TEXT_MENU_WDW_FR _("11 MONDE TREMPE-SECHE") -#define TEXT_MENU_TTM_FR _("12 TROP HAUTE MONTAGNE") -#define TEXT_MENU_THI_FR _("13 ILE GRANDS-PETITS") -#define TEXT_MENU_TTC_FR _("14 HORLOGE TIC-TAC") -#define TEXT_MENU_RR_FR _("15 COURSE ARC-EN-CIEL") -#define TEXT_MENU_BITDW_FR _(" BOWSER DES TENEBRES") -#define TEXT_MENU_BITFS_FR _(" BOWSER DES LAVES") -#define TEXT_MENU_BITS_FR _(" BOWSER DES CIEUX") -#define TEXT_MENU_PSS_FR _(" GLISSADE DE LA PRINCESSE") -#define TEXT_MENU_COTMC_FR _(" MINE DES CASQUETTES-METAL") -#define TEXT_MENU_TOTWC_FR _(" INTERRUPTEUR DE LA TOUR AILEE") -#define TEXT_MENU_VCUTM_FR _(" INVISIBLE SOUS LES DOUVES") -#define TEXT_MENU_WMOTR_FR _(" AU-DELA DE L'ARC-EN-CIEL") -#define TEXT_MENU_SA_FR _(" AQUARIUM SECRET") -#define TEXT_MENU_NONE_FR _("") -#define TEXT_MENU_STARS_FR _(" ETOILES SECRETES") - -#define TEXT_MENU_BOB_DE _(" 1 BOB-OMBS BOMBENBERG") -#define TEXT_MENU_WF_DE _(" 2 WUMMPS WUCHTWALL") -#define TEXT_MENU_JRB_DE _(" 3 PIRATENBUCHT PANIK") -#define TEXT_MENU_CCM_DE _(" 4 BIBBERBERG BOB") -#define TEXT_MENU_BBH_DE _(" 5 BIG BOOS BURG") -#define TEXT_MENU_HMC_DE _(" 6 GRÜNE GIFTGROTTE") -#define TEXT_MENU_LLL_DE _(" 7 LAVA LAGUNE") -#define TEXT_MENU_SSL_DE _(" 8 WOBIWABA WÜSTE") -#define TEXT_MENU_DDD_DE _(" 9 WILDE WASSERWERFT") -#define TEXT_MENU_SL_DE _("10 FROSTBEULEN FRUST") -#define TEXT_MENU_WDW_DE _("11 ATLANTIS AQUARIA") -#define TEXT_MENU_TTM_DE _("12 FLIEGENPILZ FIASKO") -#define TEXT_MENU_THI_DE _("13 GULLIVER GUMBA") -#define TEXT_MENU_TTC_DE _("14 TICK TACK TRAUMA") -#define TEXT_MENU_RR_DE _("15 REGENBOGEN RASEREI") -#define TEXT_MENU_BITDW_DE _(" BOWSERS SCHATTENWELT") -#define TEXT_MENU_BITFS_DE _(" BOWSERS LAVASEE") -#define TEXT_MENU_BITS_DE _(" BOWSERS LUFTSCHLOSS") -#define TEXT_MENU_PSS_DE _(" TOADSTOOLS RUTSCHBAHN") -#define TEXT_MENU_COTMC_DE _(" GRÜNER SCHALTERPALAST") -#define TEXT_MENU_TOTWC_DE _(" ROTER SCHALTERPALAST") -#define TEXT_MENU_VCUTM_DE _(" BLAUER SCHALTERPALAST") -#define TEXT_MENU_WMOTR_DE _(" REGENBOGEN FEUERWERK") -#define TEXT_MENU_SA_DE _(" VERSTECKTES AQUARIUM") -#define TEXT_MENU_NONE_DE _("") -#define TEXT_MENU_STARS_DE _(" GEHEIME STERNE") -#endif // VERSION_EU - -#endif // TEXT_STRINGS_H diff --git a/include/types.h b/include/types.h index 34c1a196b..8a38acc18 100644 --- a/include/types.h +++ b/include/types.h @@ -18,6 +18,8 @@ #define BAD_RETURN(cmd) cmd #endif +#define SCREEN_CENTER_X (SCREEN_WIDTH / 2) +#define SCREEN_CENTER_Y (SCREEN_HEIGHT / 2) struct Controller { /*0x00*/ s16 rawStickX; // diff --git a/levels/menu/custom/main_menu_seg7.acute.ia8.png b/levels/menu/custom/main_menu_seg7.acute.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..38e9d311997f15d5855bad39cd1fe4d5cfe2745a GIT binary patch literal 4602 zcmeHKdsGuw8V>~(Bd$t8(4x#nw2DmLkt5CLDuxF_Yx`&sz;`@14e6Y5P4^~{nvUdV1oc15j+5Sgz=4R&J-}k%U z_q*Tsoy=#dX!&INOgfE5n;fACiv_=~)aB{|M&tNQFgkl?s}smr#0HryCM}`IAu`L1 zL%5yL(rET;kID>3f1K}@H&|Pc7^+A0I~(QOv=eFvvLbY6iDf-IvV(G#`p;injD8fd z_P)&|SnvmFSs`UL+8tT6?^EDua*2QMz*!I z?}t1mtMmQ^B{(&$`P9z?R{3~b-z24{)SUa5zy$l;^7$fY$&QI7`U#vWIG%@N=9-klD9?%|Dvn#>v(9X6tcxA@Z z?uX6oH*3q<63xV#=&Rp6sEFFs@j>f2lh^$1v2~Hf@iOJbuP!G?HNGHfh^Y46CvHSO zV9x53FS}XaccV2r==k~Bwws;ClRa51=amM9cSg6OF|Q=JCES3#j!D_Ov~Z?x<)Qtn zEBh#V`Y<+qr*ye;F1Xwf&3Wc0EH{*A_-~(98Lizjk2AF>sOER|HIvr6 z@40*H&h&s=8C@ZBz2?<>HNU?5qA2Oh6xkyv^NYWiUr?I+*$wLu*7MfKa^H=CPuC1` zdIyF4hdswzIyb%)yA3LX5APG+dFj68L{}n`dwJmJ`YAo9pU$O&LCo-#QQrn3|H%Q( z&p`uTQyZ#3ZMj!mL!&v(A!IUDgiQ9PKtNek?Ag{H*{GVjrD1tYX??6mQ~2T&PD1Uy zGrn%CJl4!S)$OlL3Yf?7TX0(VMA?hfPj&G0h!QcO(?Z@k+@GZOm%* zIf+M5t-tUH)^({bx@n4LVRUW6fZwgc&MVbd|8pLj`C7L-U2@>2F5+`$ajt}+q`XEB;#UkX*RE2ePe6nf;ykV^`%FNC)ba@?zhZ{L>X|GS?;gw z%Kz`}o^MN@XV-o!?r3BjSvjfYh25>Eq8KcEge;;5+a-X&fRhMhH|UL4iCxNY@JhfvHO*o`4hWep zWh5w7kj!MkAwHAOWW(WhB9qHlM2CVcm{t-Swse>RJV_Zkk~B+LESt^7wDFiGOB#zK z7K>SIE{n^B0RpyW8A-$r8?AFFiXo0L+=^NVGf9|?5XFgTOlwIgg8|l|H~tySO66O6 zqjgvXpa;v2m{}Yqn`JPtMp{_O@Jv85?9i`TSk<5{vtn_pX{`mt!!vOsIcFpVhQ75o zueInM;b15W*W(5NwSrwaqqdYsC{=GQC<)RCgV|vP#2$qt3GF+vM)^jqIKmm}2rz%k zI|}_Kb_W=sluAjM30+IM7ZE09Q2R?T6G~tb$E|>a2?Q8|!3d@eg!w{&7S`|uTv&s0 z5g~>M*dh!aK^0-Nl86z-DJnqDBmfVJ@-&s;2u}(pu$keQj^7i zfa4?#NE*&E8`B&Ml;Dyjst75A%VfWsQRxv<3k*OF5Jt>ov%XtW69znvL?}Hu0)be} z6ADEfwn)Ge3f_U1;}$E(MT(WfX7YxZse_S#aDcQ3m8pQhVF99%$SgQQnk;IQNiStk zPC=BVBf+8Ip<_`HR)EN&a(+1L(LnQu#au8NZ`0wFQfyG)94^e}sySQus|d){BzxH~b8r!*93)pdQ=gz4RTEYfP^9QsBM7W7#z(*Lx}O zUf{9p`oGCVfA_kB8^J#y8+e(KHy6(ZFG3$^qU2$;!Tgf82Jke|tVp!dXp=sqE+^XV z3U4qufs9awPq^>q*|f Q0E8A19vyZxGTfA`+s zckey<)+z%1M%hiWqtR%iWd1(E;CHy?9X=F{+Rsd291^u8G@J@XlOVl8ry>&wh)UKI z5Md@&G@AK(?Uwmjx7|jrZV^>ZEz7bWd#)^I|Fh4QzJ7VgDadu_(`kYGRq}~(_F2EW z>cwBYdvl|Fmf5_{-G?6}%C!xuL5$w#_I0?cE+Rj(N+IZ z{K6k5d9$aw-3y5hx^uGq`DEW>KF4#?o8vPtoTj&GQcS~$8&@_RzHt?Yui-uY@rhHH7YS7drp z>OnGU3ANm_`O>=Lv}*Z=#)ex?qjLn~4A)x!xjFlhq+}}Vn~({6x8KV=@x1Mun_Sa; z<($06l6*#d_K>29F00AWzix3UKcGO>=iM?24*I8hTqft{Z(6(ZKuFHqR57exlz+Ce zIv_^+UD4r!Rm`fb2SzSiJpO({R_@wW%BVwrt>q38wQc#UFK;V1FxGIqoBUU92{0#m zKf3K^FJD$+w+zXQDNpy-{@Z@YnEOi=iK9Amo4r;YSn+d)TP7oG%(dhYWagU^TYMO7 zAA0o0#A)i&gTEcVcS7BU6|}sKZqv7|Z(3vTZ}aous|)G%(Cq!qzfJSoIMk!AoVVGr za8JSd))k8*RnYFNihsET3@UJ(@Dgj-DE0Nt-tWRstc}RZ`H`24lacExE0pYGxJui! zF3s=DAnn7S&fs+^0U^cwhD*C`Z(E^(X3u#N;~}c7Uez4qK}>x%}}Lrc-k>?>8Vc?T!V4y*^n*AGgLp&d_Ox^9(M zI0qJLUZ5REI_}Rk*Jrk9%(V|OZfo;lzp`bG+riMZ{jTz9&h<{0?$QYlT#q|%ZghW9 z#4sFt)A^HgY(}*+``h}wyST##w*m4Z(BQ}mSmQ0Fom zg}$SxA$7!&#W6o-qHQ~h93o6(_x^EqYRl4 zK{WOyJ*x4y6Jf8q{@`R)`9xH;W`u658vUfSMeTgIYwt0neic1$k%mxvu72(p?sWD# zw;)nrhTkn)RK7l>{`Hge=xZ5@sHeQHwV+=)lAtez%jbzPora0xIwiq0YxJOF(P*Bt z%z6}46BMK*Vo9xp{^)cm9U^fF{Y$=_E!RtlIMRQKfe2X=7>X@XVmX*4WDe;DcpG^(=(RW@$96z8Xf#*91U%9r{ZR zV<>3vtYE^ZOEh4FuZhr7jJ^;!_Ca5tXh^VzgJUcrfzSX^Be06}GwCOjD?VsgD2OFB zdaD*7yPqUQsy>p{&o|4CHJrYV0QC>J{iNT=ZWRVna=F+?hb3Cvlle&K7W-mchmpA0 z`pH#cJPr>bV4N>x!#o60!6G3?2qPj4LHJw`Ay3Ka10~ZMDO8IQ7AOGDBmoYBBPv{k z3SprVM_``7g9nQc6oCawKEW1UeOE2&HDUPr(#Rm0_ za9}nk6yb=ud@+YjXY~flvefkZXgyhf;=|J_(5DFiy`DADTtKg4eP~v_d|4>`8=u~D z_!}(%=m8_2#P0xI19W{71D_;3kX-|GeG&toBs`E^|2MkqK3;bSE%*nN1THg$&*JOA zMQE@xz|V*F?z_yIQZTdC`!6)oXd}j1-a)i&I~>8H4JDKN+O&-v(HpjgpBy>w-q`hQ7sk5d@7yBZW;+g{MZ}DFB_&Qz2U;|l MZ=lb?IWZ~!1LJ}J-~a#s literal 0 HcmV?d00001 diff --git a/levels/menu/custom/main_menu_seg7.circumflex.ia8.png b/levels/menu/custom/main_menu_seg7.circumflex.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..1e46fa7cc73f85edf359489781a92e804bda86ec GIT binary patch literal 4605 zcmeHKc~leU77wjfpeR*b5Uq{_qS$7cgluD?B0&-%h!ELaU@|j-k!&Ud1YBxSL48(5 zeWE^!(khB|tDs16At2RPMMcqCM0hA#t91oMMdf`7sBm8Y@toKH$T^eDeBbZ>?!CY7 z-g`1DLPG-kI(s-X7>vFOxhxF)I@&JBUf^5*Niz8UcyO93iVnk4Afw5kp|m7Kry5C! zv``ub!%}-cd-}R-kV{5`IAG0UucasFaW-wP-*)QZ8fBeQa6kB`wu|S=-IuQ&o#!ea z@N8s5;PZ@fB!6vbL@9W!cT>yVYUAf%7+B8-D#v1>gFaQ(E-P)IS=U=%J$0 zm08D;CY@5->Nc9$_9kxm`4ElFT$i19(8X!1TainRIT{&KTpV=uSz+wMtwB!@6*aYD zC)%{9=R`j5e|xqZj>#Id_-y79RWPTvVBoK!#!DL-Hm+PMIdf@-Gwi{uX;J-=dqpQZ zf2%Po;>HfxRdFt|T{S{J(!1$Ng+V$d*7JCFX>R`H1*hLE`1#I+)qH#qpWKe_54gV3 zv}#+iwUWN?@XX{Zadu0tNxysba^IPGrv?jarYv(m^2zACD(b?bmTx>J2OsStaM?8M z%qSXR)e%pE3NOa3hi4C$T>Dz;6#L_a#=|EE_cQc6|LwM4dg10zkIt(2fxQY@^U?H{ zFCv%!Bh`Bt7Hle9=CS-jl;X0dwfJR}ccg>$-&ME!`^f)H-g0%rqU*g(iwBP#_p;e# z-BXg`lb#sB@q!q0MNS)hJPP}d%IY_1P+p-|{iMaJ5>I&uJXD*rGx4aJ-gS_B(!n%K z1Ldu&EX$Yo-m_s~+o^T9>x@Cl-CHi#97?EK7k(wD@K&l%gjc1mOQIf!P2Kw_8Y{VR-+5V#u$~C|R|eB?_(jCw+5-z?=GK}DZ|^OtEeSgH zy4qa);8@E~msamB+Bv)R=(Pv)f4f%}F>JsT5A?}_#_w09O`jRnaCykC>hFH;Q&5mF zgfFksdne2pgKlo%`i}AXSH(@`vR1gHwJvx1z2?MSpPxJzE?V!=d#7u2Y2-8X#Gmy~8&ll&Ka0(H zv(O)JyA+XH>pC&B(R@SPcOkSo_Pa-omI(L8^NVr=+GO`CYU+2l3&}oKZB?(IUF#Qh`0 z-V(6lTkhaI^)E}8uG}{_|D035w%x4W4y_xO?sobyjaQ|rTRzpNWcZ2&S^KC**LJ^t zX&S1)VdhO^;5g;Y%ohz053OlVyHvaBcfbBMdwY|Kl8n~CsL#u5d3$CFEzI^sGb>hw zpMTZ-P3)b;p=6f(+}&W(xKm)FL@9$&+@ND&gh5TREIK2YH4KJiqQ!{ei6jlF$#_aH zg&&rlfFX*I!jXI>M``pY6DWC_i40E*QQ>KcxR`(^PH>i3P(Yv~X$-RHw0bjYk-~Of z6x`dE*)U{>(1}twN*N0I8%!kR%kpJ$m;n|lnF~*Fh9o9JgNDhbbW(sPDV#vlMwHD? zNl9U)@K^>@JR1><#cU3j&E+xyf@x0G)0l;+H+$MBIyhvc88=Zznlk7i8z-hVB+*hB z2K&(4_;g04@*Tb2+^GW4gKfc#Y=p&O>vZg{7G^pi8IW`a^p_T96&TFyFw$&DGT~%E zGO4FMyHXJNJ9}f2No!Asz}cjh)B&g&ctyIo3{)sX-&xosh^KT$yA=?-8cDb8a2)&c?jW)@YH<1SlES1p*Pc*9w%*7fSg4E9t7bc8V*J>H6nz|^c4z(OfjFY zW~#Xyo=C(e2sM}6g<_hC0#%7=yGCWBA^;T+6NpH@F9*bc3qdp-5ElWMc{~k=MEGK{ zkf*j&5jZ-9J;aMUkUA%(dt&ij>6Ekuuk{7=RMUW;ls6`tq!eQ|`m~97xf^>kin5|L)f!zXRgZi6D zj5e5527^`#+k%2@mi7XNBpt^hr_2D6YODFqst+gUbv$)6ftIpwL6E(0Q4H^JV#bn5 z!tMyzb!_1Ym_D8a9o|_|Z`Y~6I4+@D!{c!g0h1@ z-Pz3s4V{9SNWXZHDaZztkUbk{Y^Rt$-SH_2q)jOf=xeS07;otb_Jcqy01EB74@j)7CcW0C*AlNF5X?W3*?kIeP*;IT_{A zW(MO^H{0dF*plN87W>c&Wk8?XE)GM+y6)&#|4*>wu8{eu9Dl{*Am>-{&)eH4t}Oe? dF@G?FvF~Z07YlCfp93%qML>vb-{iRT{{sJR)usRd literal 0 HcmV?d00001 diff --git a/levels/menu/custom/main_menu_seg7.grave.ia8.png b/levels/menu/custom/main_menu_seg7.grave.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..ee9aad0ece84abd985007b0a496c5548bcebd06e GIT binary patch literal 4600 zcmeHKdsq`!77vPu6w#^_M66@*$vT-Ngpj0(NRt2&f-%N|Sd__R5~k#35<DK z?z!j7T_uZ&81CWcL7`BFOCm*b@as-q?ylgjce8@~;4$fnIEx%jg^VVHn$Y5qCC!LK zxQ$R#D7Kp|1RfIM)wQGDj!*UfX~(Gh8mTfPl1a+5RuF}V!C@d#i3bXU}! z^1%4cuyeQkuD1@I9pCv1I;)vnxBW(IRN0J)P3DZvvjhd+<|SRnSLi~Y{`RUuu{bJf zSzCLZM)+%`@#n|^FAc$xVtI%{8A$Gw`LV%M~FCCu49a>BOI5=LbnRvRalj@^1O zd2VdIda!kzW6Qjy8H>KkiI|8+(9V68&~U&zUAsi6SFFrTmTimK7?9xPG zR>eX8Vp?@}QS>rG?WdLRSd*ps=)lyb3qCvtd@vhh|GlO-@x1H7iXn{`n;Lwow?t%4 z>-7FhM-@M7c*vBB1*bhlN#&)@@84OtEPBJpX6{@2!w zWuK~{t(?VfY;j=X&K=i7H~TLw+mj@}TJG2(|^o-MR60Y4{qy2|FBH z6Y4J~TQ`)Z6+c$FCHjxbJT7&;ewqKZc-KZ-eo>7QwR_;4-5VC{l6bn-#gu31|2?Qg zG_|7pEF4#Puli&ZE!twpU;40pb$rQUVGCsa=JeS5X`C;7Z=X1H?LYVnMegF^KP+56 z>}7X$b^DR|IiV-ouLORc6LQ$Aq^Wj-d;7`ft^2%6?p-=@+0gMU@OnvjOVnfXi;VW` z$YgX+e?=)TJ5to>KHW^AxJ)91LYYJ;e7!%wuCN!cJ2CrA;+UKg#oYD0=^l62Z9VS& zY0dq+BiwR7mIlNXUzt>;93{+`|1h{sggCMw+pt9$UmkAr8Sh_nH}gyy$Nv1sM_r}( zR5YH}8df+z`{{TuBsaGGmvOooM;{*;w*qe*XYXWHKiaGIMiRDP<-gF(5HA_K=i;UX zTYS9ZhAK6mJjmIk{a0t>!HzI(1o6SDlC#Cr)_N8tAW}zDo}edNA$8GJYs)s~Us!+6=SiX4$(Eb@k%INCDOZ?Y zsXMN)mTl>Nxu}b?Kjhomv=7IGHN?w~R%5p1E54gp9(txZCF|PxwqwCHoZo6fZ+8rV zf@GOb{<+Hq^ci0Q^piMgG!HZAXsF7d#A!C25p)^~g&%4&qF6F+ft0w0&wJOoKiO{Jv< z(F`UH!r*eb2%U*AnJ_@W<}|$pwZVFG07=oqA;Qg=i7;9SgB~I|QKccpBA`;iJoGv~ zolz?7qt}~zRRDS*Hq?kPXmmuUL;72oEn+Jm=?&-)EzAngmJvB_Hl&y^Tx`YlmVo{g zDy+}mm}1g8(@|jvuEli#Y6e~zZ@G++NM(H%qy!p5XLMQtvEM>k2=yDW-inQ!ai-Hh z5MbWN`xg3j?oKd3Nu@lI0ZSpnlZXUV(mzjSzz7x3`N#<3D48ra3uZ7vlrW2>4u&~w zdN7QuIcx@pqg0_7y&siCZ?>R%3@51oIgJ23TozZU!qgm?8x%x`Sxg**IYC?$M%64P zUCE_~U>t5gia90%R3)nI9~DWZ0#pn-ox@~vRUjIA2+UHlP*@qH;XcrGNhW{fE9!e zpJzcyJsE5^mm3tq0nULOboLw2C%DNBYLR4R&}l(E%;duGKsrELl&n-h;IshQ@PsBD zwHQnagF!2xk|98(rL({xe$TQ*5@vu%BWu35>gVB0dfs|AftGMiL6Ea>c_`N7#Ee>T zmD3Th>zTrmP`w5RJG{4~UXK%huv`o-O9j+q!yGjigIRR05>{du7sgd|jLl_XDhArK zTz%|jgW8gcn(#0U$P{D)O30ZFG_6<6>2F7qnuL=|(ZT*^Fkw1V!C>-&*t}pm73obD zA@}s_Z28Fl=)rda`ZWPy*E0s13+PoyU$g4fi)-zeFx+kkn5ck zcqi~cbq&b%P71sec%ZueZ*qCOIqu+k@DC^z9A;jvU04VXLW7i15h6-=ZeGnv@HWgC zxd5Cr-y2O{E|fyMFBlwZkx0cuA9}j@Ok&QhYgh?}yd|PAh5I!u5%T!G`_kWjo-l7^ bI)!qq(e?Kyi{_620E$E$Bii?I;+OvgB-_we literal 0 HcmV?d00001 diff --git a/levels/menu/custom/main_menu_seg7.inverted_exclamation_mark.ia8.png b/levels/menu/custom/main_menu_seg7.inverted_exclamation_mark.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..9805002216f2390a8c2a38538a2d634a0fc6d7c1 GIT binary patch literal 4699 zcmeHKX;c$g77n-}f*T3~BI$^>w4J50l1M<=BL*W$11{K9DwR+|7L$SmXg6#DX%Tg1 zl+6(Y1eXRC^nj>{O)KKk&L|+DIJ68dxa$b0;JgG>IMaVTXZjyGsqMY*efQq)-gi&c zR#A|@wWWh4fk3bp1o#AltA+8f7!A&9@B*BPSnpu_=CZ^!=-D ziw*7Vu1mjKb5atV^}KfKgivO5%im9(#ZtQx5@sQ`R&Qw&G&fnB7HrNaPrXp z!lerv-)!oQ$*py|+qThgxYje)hc+|;(Qk>iS6j~|eH>q&)IpN!vEO>THo=$la3 z_d=f(AHLH+!|toh=eEt`Q#QB-_{u;{LXA=Q?SUY>J&Wx^+6$HalV&T)mYz0672f%#x#d{eyhzD%nZlN zE!eI~jZHT-KCfnZDqeBvpCPUJ&ug|cmZNLntMaeOLz8VY7?@O?$TT@OHEmJFYXz!X4 zrv%Th+i}jU!f*dyBkQkZT6j5F9m;*GkSC2QsCRPVrn(rA#|NP~HyrBgA54635gq%r zWNJ`GO`c_$RPuP=OzVW=Ly?k(g5|=W8eLrH3SIx*u}6A!7gCoczSgY0)KI(s;GE0y zkR!H~#6WT2H{V{>xn;?*ZS@$@A!51@td1|X1i>2!wYsMr_mp^x2U@Ody}Hdt1cWC&&rt8 zbUpjksKocYW!+XuYg0yFEL*wJ`s&kW*|gbJx~I*O8AV?9E)D#yj_oxy6_dMill7Z8 z{&y;!du_EpyhtnM+1);+=5;@8&5XKJoz(K^R;*?CO@Zbu?Q9r&xF79amV5&0{E*u0 z^|-7nE~MuP_CcJy;FiJZX~eyw?GxEwJA@;q8?{4t#H(ZJ>j}?`%=ZSo``fPemh!UM z+EI?Bzc@voZG2!JU9tIUrC(EoKe!h8*){hZ(TvLuOVPWZwHw+HaoZ-0`L%vpADLFq?yUdy53#-XFId*l0O> zcL*2%BAT|P`sVjH6LV8iHe2P`=49-&*$}A_6)Q&{&SwgaWz_B{n5O?%5Dqz6BnE2C zEVuKiJWa%0kBXf1%V+MN?#_iTE(*T#%zM}F%GL!At0tB_F67wWlJEU4YrROecYSOA zn;*_f?bl)UrEe=ef0NFbz6n3Dc=NZ^8s4-8H|UHb(pQaLdsCciV>1f!dIYEK=H|g= zt%1J_p5Mb%WwwQO>u!WT`CaRmOksP^-L};g6NqDi*1GLD)zNcXJUIX%{pUcIYvq*b zS}oT$j&$e1Ty;@>*Ei_A^kb)&oOjylE}Yf5p}NWA+F@Z-)b8HO?@x3}(*9x5=A6gf zn5GD;EV;Czzwcz0eNk5LeaC9TwR}<7fgjg7g5EU)13fBCxP*tOl@wT}mZB7cQUkgd zf#B|G(7;F(iW8-%0#orx&#J0PL`=pfg|dV+p~f4H!~){As5m}Ig2YE5Tp7vJ!_wWr z0|ZJGhlvJdv`WV_@JS|K9=JCSQ%OV<1drmA!h|BCw_1x5nG`04M)oyev2>D$CDC0g zlkKHA8`o^LveD+WZe}Pc+iNP3>0#j;CK>_iG8IvKOaGDrxvJkh75+uQo58*X3E{TWS9d(WRweYAvySSShOJ&OSKrNN;rC`S4JuspmKu|4uo>J zWVW0oCo?&6K*glV$x>9xf@CNnlX2N5Dq|jai$nrGiB1_HH;ss*VO*}(DnY4ZDw$fZ z`wW&~N>q%)M%f@Xi@}5#ZY(;3&4w6^&!7-gs{RER=dDFyT&_ctu)_yS>f<=}2kAoSOpqQ1 zi_BqyoH02NLgqpoh|K0lIUJbDVslXXaCV(qj_YA9x<~;c1<`;KGDSn2H>k4faJ)Ve zHA+YW`2?uzB Mz&FUJ#4954zgve0?EnA( literal 0 HcmV?d00001 diff --git a/levels/menu/custom/main_menu_seg7.inverted_question_mark.ia8.png b/levels/menu/custom/main_menu_seg7.inverted_question_mark.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..7a2e5078a77a52fd6d53e36c543f52a51dcdf559 GIT binary patch literal 4682 zcmeI0X;c$g7RMvwLNhSqiXe@oqoB}KDjV4#AclYef@wfS#DPjx1xmA-6eMUP3U1gU z+NV_-aG?=w8^s-jhG9heI5N24GVUnKqPU>KfXh+mRY1fu{l#;pzmapQQt!R{e(&D@ zyYHSd+s|gKGCsPeL z9k&o_8qIR!$u_OAWxD;E_onrd4EL|5Zp_Tyd&8ySdGD4dDHq**xvqQK&NF|2Y-ZX@ zY|Iy5-|yV~Zf3LRY|qlvy~W|vE8FTF9Cr3xEEfdAP0K2?8`ILoqnsAnc&=S8>ejy{ zCtZ_C!vdUNv^wQ>j#}jZ_)X?lO{-UhG(KHhxYTKE)2Iim3q4vzaaCGVUG>u!xwZN$ zIs5Ti^P7iyX?K;%75Uq0tZqSzVaC1YsSXam<-1EapK5g6yWsuVal>2Y6r77}ZnT}( z6;`|~w!*RI>Fk`N95=5Qqg#yi+umk%BQwq=zwD~Np5u6@x1uUP^pdpuzH`x=Ydsql z9*rB_VbpY#Z`nVh#yRZN#T^L;!q*?&xX!PkPk4PaoZB&Ti_`Iuc*o_W3sq-U zJ08zXRcMk}u=j#J-z{mCWyEg`&2+H$O*-uD(&PQ@>zOwXC&yka&qG@ylz0YveYK^c z#5`@on2?o8FSv7`eJ9Fr5M;zv7mj4`Hty@|jZ+SiG)cQGj~%BaSDzsM8|OUoJV6QSamtgu5r#zd6NZD`mZ zYkK~;GsCm0zyLE;yOzu+>E^n0}Ps3UAbCSzB1b7`{2pq`h(3y8&e{E5Bgsb{M;Cr zEr={kncRO4eH*Hb_Z9|mD=!zLDR<$MYMXe2i%v{BmC0;)??;d$1BG7(#SLnV> z-Q%&HL7BJQb!T3<3f_5Dj(^ZJwYTBPgkzI;7UEONch=c(S z<1c6ITDLCKzQC~{ck{UPB!lv2?eNkfp8QbmsZG1bo9{-DY**WiFvBprjS^UFNbvAK zUXb&zn)d46UC8Oc$c9eo_ggD(`c8`bOWEUMf#Wsx_BnaWmDu*>H;a0{{kzIJjc`8j zx-#Ir%4xz%vLrOq8$KZ(?|X^E-KXmM_oMCW+)kzB?k;>Oub${ph#a{Yc2EB7KA}6} zSUfT9(!3}4jKOP}e5uEVEKfonl^n4|xT&h;<*lgEvrxu=O7c7_$4oF9MUJVA+a(_Q zJ@t>g@aZ{+s>ADCv-}j3+tO>V`kyOREMC0zRb~9Kw&?6e+a|X{(TeQEn98ya|P+)2nc%MQZ?MibnGbuow_@F;3D| zcp{;bFgky&WzY#s!kFiyU?~hzJc*dK)QCqdjfh5Kd1_k#cKuf|% zB1wZ7hRtR()68Y+jfpT@Boe_a4$R>|zydO*>PW-_=}c27L?0svH=#ztKoWW#onj&? zeKILwFu*wdgMV6sLNS2Xnfg@#dcYRM0JE7aSgVBx&oGg)6aeXW=yzwBqCriEBXN^H z*@)t@6kJD68H@;#E0hBSDx^e0Yp@0d#QS713>~mDBpWqW8w`bU4Xy=H6Y!7yi9JcE zKZ^B}5}4TfC}ML(Y>bCM z93P<&;t5znNae#)L23>n!i5OJM+MwLD7nr=B03bOPyo&(07orA5LAF65Q_3y5RZ*u zkPubl5F6toLfi*q3Du%Oh}lL0WF?{*>=lK=07@ue2~;Yz074Kp@CIS4ArXg*Ll~RG z7phqTt_t_DqNsfk2P)+f28YS|*rU`Sq*`y(f>bATnBHvqI2282@hB3ZWMlJvxI7Ry zkH_cp_-y`1qq(@z1X7NovRO=S9~nc%!GMW?)FHG;A`TmLiPkC9#)v^UKw5;#R6w@& zgJ{H3BaV=IW3*nckuWH4=@inM;B>#fZJ9-wfJG{m^Zi*Lg)ixA^&J8YVI88=t%)l} z(7r`XND7Ww7XtJ8hR`HLmxzNC-k(w*`ibA$E}jZwak(PM2S^Kn1`dgYJT=6}xGEMK z!9_xTpT+}plU_}l5hEU$2qFd1fE2PuL!aKSvgfDXn3HfyLKZmREFXx&i)IVOT#=Z? zW5E5v!ql1m5Un5lKYI9C4F(kfFt4u<6c;EQ~-N)A*TnByunZe79bF1?a@FHZR3JVFMy!@h(a2;778cNlV=GighzyE1iXS4^dvbU2l6sGfj~PdC{kOk zFGP8$ASx)sTU%5tQW3056$Kw1!Cov>1xHb@SSxsU0xC@V$C=xIWad2f-rxGxTHjuK zP0l9qqELIg*>(g1!Cn|9hy+g?(`91`?rN)KaGw;H79E2}A}K_zP9w*ZC=pN9qD0h) z$q5AGFFngtx_+;zuP%E(x5?SCjq{;Z)PL1gEq9vb^|@QyFV+w2FK1QecuQycL<)LgH<;ptODZ)@OYQ6Uap(H(yFt} z(ASo<))?*cWa@V79oMjxFDKnUyRN|SBB|$IZOh=WfghRKlRmV1u&e%&zS(zSL?N$L z*m<~S(Bb<7OijPx^|AE-xU-9KTz&Cv?=J^$%}58i+zvnZVk8pf*INqVuJ?ORL|*B|EF_Sn)`}$ z#lTLVUnOp`NzG!l-!!Y>(#4U6PhMPit1K#;zhJKKR%pk9{Dj zJd+p}UV+$TXGbqWM_9Ha)T|T`uYN4Hz?=8Q77>oJB6qs*mc@p@=WK3w1q zF_XG$9bKR zS2&Asg;gU*kkQTZJd@E|bgSFR-9lEZ)D7LuB*=e(Db@EAU)(bK2HMm{f z*u7W%s^miE$DR2X_{ps&n zKs)_<`1q_PY}bnU3}xL1ty{S-=jKgwteF4Qg{j^5tUDT@=@s+!Ep4AD zHu`*?-uv6VD0pY_<+lDgaq059A7?16_Gl;Pwb?H#JTce9z1XD_j4DGPuIN~K3%otz zq`9^>wz(Jn5wND_(A~?q18eUG)L7m~&|F*FOCVTyVnIP-VNlSUg9eUQ!QO4H3(txj zG8@_tkPL_F92$LZ&lFVou!mP^my}|b#bvOtdQa1~gHCtOu-mfk2ReLd={~>l`0pXJ z$d{Va5&w<3`rdfOE#aP=hjC%GN42+uUSDmf+1+*TO0y*YG|~6z@ZxkGpJ*~ft=VW<1%JJyDrU$KX)M}4U5B;X~d?Gk` zxKUI4-1R)_xnv%%U3H9UU z!$aR~%#G(iz06)?VPh>eWS(b~f`;XcfyNXgir`5#Dl#I|NKmp-r3EdEK=2DNY7uD? ziW4Ph0;cAZ9-V3+5iuE`w2UdDinKwf0t-vip;2jzqNQm`Qm%{?;BV(=eQtLfT6eAo0R4>(GS{&1; zi6%}&qA}on5(%sm-^8cVibQYe)%sBtfF2YhqNUKtREkPP8Ec`(gOdTtXh45!p^par zof3)aH3pp&4NgYYxW`xune?r_)}T|G(~(Ijs1j8Hs2+HwjdK|)6p7zjm?TKRR9dqY z5PKXF$K>zC8W)>s#hlLAK!EvM-f`$RxtqZNB@*!j8mYk)o>0Iinf&u)8Yw2@nO|X4 zLPc0I2_$21sSqsV${>yuWv2RaMNL$IoQwe;gpHsmn+8KH zhMWVzFdcy;2we`zsZu$@VId4y!W~1gScieCM3iHrGEvC@6$4>OxeN&vlA}~WMMY>3 z0?X-;jKgFgY$goDOxR2%lk!3|Iu!!86H_4xC`GGIFfW({=PeKm`6N1dByjVLSc%|r zU;xelrj}_^^zXpYmXCRQ4i%ot%dZ43{j z1EfVvl?n*V79bm5kPby~jV@ZFQSwQq5QrvAbAc26Mz$pk(*s1RspdzkJ_=nuG8#Dq zO3b`OB$^AChe$`9=#gYpW_ASZMwX-sM4fL3P3qoFjGnll-g`!~V-l>)rMAsN&r30Aq6$%za z+uYdFO0y#n9h%O>4!m9&|JnAk2p1b+-@jaKKV6>FNQ!#lcpB+_PS~QgahMSr@&&LX N2!j_1Dgsw!{110)_4oh) literal 0 HcmV?d00001 diff --git a/levels/menu/custom/main_menu_seg7.tilde_diacritic.ia8.png b/levels/menu/custom/main_menu_seg7.tilde_diacritic.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..b23b40d0c91895b095c4112f66a3a754a5eb55ae GIT binary patch literal 4598 zcmeHKdsGu=77xCFC}O2n>Z6Qt>w{&I$!qc`0Wk>>G)OU6P(dfj1V)lf$P5tB)>@T? zqR3h)ijNdpEv#<^T+u>Nu_|g&M3l8^bUn9E}bxLb#%f%{;eOkFG;jip02J82@!I7DaI za0qu0CKk)l@}Mw2uWj0h)i>hm0wz`R(fUcFzPVZ(|3VQNy=jm0-7;%eefSvNjFpu6 zxm(QE%0
>T@ELXsx#+$%0Eruu^pJwmmudW6JF!QMa*0813%LAHz z+>Y0HKf6aNA7>p~hmbQ5eD#iOaQ+k9`Yg}TiJ|pZ$Cj1GSoPtjb_T}JQLBVA&+*o_ z6F+5kW(F!Qo>^9OO1Zwisd~bkZ@hi%Pk-LK?VwXp?br1vKcZgw__pxwzYgzxcW2UJ zsHt_~rGkoIzPGNEW6Bl3sAIE(tkI~;O+CW5ot@+3GwEG_X zhhJW4z}f?zeU+Qi%B|&v6`vlKrJNA>EKf0f(f)?^O0MF;^$FYDYd3i6_Yb|!z4z1D zJ8Qn4QU0Xh&nN08oDTI3;V#*@!sDE}dF8+TlM}?d@rtJAs>-|vjZ||&Rcc4Y zp<3mz_H`d-dHJQ5uSLz7~g$($`2*)2eVji?-NR8lt!t1*&d)NwrtJ+F5*PgsMR&QN;t{er)8_zA)AMe zKXl+%_my?Wiqwt8Ok@vgpY9psqkpucsO;}=6-3*mqcb@1jW-X)J$uwD*l;p- z{>h*7bVVn1ql>dfV&Asy@X-8z0>7_dmFz+Gwt}?%t)OfGua?Ba)N`{fetwUu;4TXIV@%?C3h$|E?hZy zW|nyz$fZIjD>$**C`d`#aY)1!aS>SUAkqY!AT|_eH=5+ps?c5t@TTA-(X>s@ZLJTIRCsSz!hXdr$ z%lIrdt@ahXmFi^y@WFFnHXfgg@GKTyUki#>rvZ@OfPUA4(t)wei^eH3)o#GmX}Fc1 z+!w-Vcx7)(wVPe(7!5q!j9Y*z1-$b6xeU{2qh47s6eJQBo68E2-A|JyOs~o67aJpS zrPDVMVEziXpZ3e#UCKa9tCg!rLn;%VMy22|{^dr}Kp5pckC<41BSHae65|qBBo*>u znMf~$g(ggdio}>$CN=bd(tsZq%xb_HC;-kS0FKybGVyVv0M_#XjtD^|FecNRU`@E&)ThJS0k^;0Uy;=oMw@^E=mElNB-5$aA{}AD=h7I% zCm%SG2_-TaA`|naV!>;rdAOYdwaB3I5w5TYnb{aQNC!}hF_j7cToxc3xzdhfG-=n7 zq*=jXf`S-JSAj!;J=+paP(UMtsrlZjpNpsTy!AAJnQ)09$W^#<%+TY6!qRY~%Mq~a z5gC#&Ya$LhytkxYt`onrT_!P~Z`9)=m@ngtVUZ9;U`&dju#71K5oR)?25EnEiZs#b zm>myE1et*Ee?1^V) z<;E)7;tLktX^mFxerJT+*r|fd7kRV5l8;6eqVs4rEQZ+6yS;0#9M-W|747a%$Bj8p Q12IdZj#TZLx%ji+0O?4^5&!@I literal 0 HcmV?d00001 diff --git a/levels/menu/header.h b/levels/menu/header.h index 8f9726f2f..e8e391e25 100644 --- a/levels/menu/header.h +++ b/levels/menu/header.h @@ -2,6 +2,7 @@ #define MENU_HEADER_H #include "types.h" +#include "src/game/ingame_menu.h" // geo extern const GeoLayout geo_menu_mario_save_button[]; @@ -41,19 +42,31 @@ extern const Gfx dl_menu_generic_button_dynamic[]; extern const Gfx dl_menu_idle_hand[]; extern const Gfx dl_menu_grabbing_hand[]; -extern const u8 *const menu_hud_lut[]; -extern const u8 *const menu_font_lut[]; + +extern struct DiacriticLUTEntry menu_font_diacritic_lut[]; +extern struct AsciiCharLUTEntry menu_font_lut[]; +extern struct Utf8LUT menu_font_utf8_lut; + extern const Gfx dl_menu_ia8_text_begin[]; extern const Gfx dl_menu_ia8_text_end[]; extern const Gfx dl_menu_rgba16_wood_course[]; -extern const Gfx dl_menu_texture_course_upper[]; -extern const Gfx dl_menu_texture_niveau_upper[]; -extern const Gfx dl_menu_texture_kurs_upper[]; extern const Collision main_menu_seg7_collision[]; -#ifdef VERSION_EU -extern const u8 eu_course_strings_en_table[]; -extern const u8 eu_course_strings_fr_table[]; -extern const u8 eu_course_strings_de_table[]; +#ifdef MULTILANG +extern const char *(*course_strings_language_table[])[]; +extern Gfx dl_menu_rgba16_wood_course_end[]; +extern Gfx dl_menu_texture_course_upper[]; +extern const char *course_strings_en_table[]; +#ifdef ENABLE_FRENCH +extern Gfx dl_menu_texture_niveau_upper[]; +extern const char *course_strings_fr_table[]; +#endif +#ifdef ENABLE_GERMAN +extern Gfx dl_menu_texture_kurs_upper[]; +extern const char *course_strings_de_table[]; +#endif +#ifdef ENABLE_JAPANESE +extern const char *course_strings_jp_table[]; +#endif #endif // script diff --git a/levels/menu/leveldata.c b/levels/menu/leveldata.c index 9201bfe0e..8ec8a084c 100644 --- a/levels/menu/leveldata.c +++ b/levels/menu/leveldata.c @@ -5,10 +5,8 @@ #include "surface_terrains.h" #include "types.h" -#ifdef VERSION_EU -#include "text_strings.h" -#endif #include "make_const_nonconst.h" +#include "game/ingame_menu.h" // 0x07000000 - 0x07000018 static const Lights1 lights_menu_save_button = gdSPDefLights1( @@ -621,161 +619,7 @@ const Gfx dl_menu_grabbing_hand[] = { gsSPBranchList(dl_menu_hand), }; -// 0x070073D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_hu[] = { -#include "levels/menu/main_menu_seg7.073D0.rgba16.inc.c" -}; - -// 0x070075D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_small_a[] = { -#include "levels/menu/main_menu_seg7.075D0.rgba16.inc.c" -}; - -// 0x070077D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_i[] = { -#include "levels/menu/main_menu_seg7.077D0.rgba16.inc.c" -}; - -// 0x070079D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_ru[] = { -#include "levels/menu/main_menu_seg7.079D0.rgba16.inc.c" -}; - -// 0x07007BD0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_se[] = { -#include "levels/menu/main_menu_seg7.07BD0.rgba16.inc.c" -}; - -// 0x07007DD0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_re[] = { -#include "levels/menu/main_menu_seg7.07DD0.rgba16.inc.c" -}; - -// 0x07007FD0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_ku[] = { -#include "levels/menu/main_menu_seg7.07FD0.rgba16.inc.c" -}; - -// 0x070081D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_to[] = { -#include "levels/menu/main_menu_seg7.081D0.rgba16.inc.c" -}; - -// 0x070083D0 -ALIGNED8 static const Texture texture_menu_hud_char_hiragana_wo[] = { -#include "levels/menu/main_menu_seg7.083D0.rgba16.inc.c" -}; - -// 0x070085D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_ko[] = { -#include "levels/menu/main_menu_seg7.085D0.rgba16.inc.c" -}; - -// 0x070087D0 -ALIGNED8 static const Texture texture_menu_hud_char_kana_handakuten_pi[] = { -#include "levels/menu/main_menu_seg7.087D0.rgba16.inc.c" -}; - -// 0x070089D0 -ALIGNED8 static const Texture texture_menu_hud_char_choonpu[] = { -#include "levels/menu/main_menu_seg7.089D0.rgba16.inc.c" -}; - -// 0x07008BD0 -ALIGNED8 static const Texture texture_menu_hud_char_hiragana_su[] = { -#include "levels/menu/main_menu_seg7.08BD0.rgba16.inc.c" -}; - -// 0x07008DD0 -ALIGNED8 static const Texture texture_menu_hud_char_hiragana_ru[] = { -#include "levels/menu/main_menu_seg7.08DD0.rgba16.inc.c" -}; - -// 0x07008FD0 -ALIGNED8 static const Texture texture_menu_hud_char_hiragana_ke[] = { -#include "levels/menu/main_menu_seg7.08FD0.rgba16.inc.c" -}; - -// 0x070091D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_ma[] = { -#include "levels/menu/main_menu_seg7.091D0.rgba16.inc.c" -}; - -// 0x070093D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_ri[] = { -#include "levels/menu/main_menu_seg7.093D0.rgba16.inc.c" -}; - -// 0x070095D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_o[] = { -#include "levels/menu/main_menu_seg7.095D0.rgba16.inc.c" -}; - -// 0x070097D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_su[] = { -#include "levels/menu/main_menu_seg7.097D0.rgba16.inc.c" -}; - -// 0x070099D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_a[] = { -#include "levels/menu/main_menu_seg7.099D0.rgba16.inc.c" -}; - -// 0x07009BD0 -ALIGNED8 static const Texture texture_menu_hud_char_hiragana_mi[] = { -#include "levels/menu/main_menu_seg7.09BD0.rgba16.inc.c" -}; - -// 0x07009DD0 -ALIGNED8 static const Texture texture_menu_hud_char_hira_dakuten_do[] = { -#include "levels/menu/main_menu_seg7.09DD0.rgba16.inc.c" -}; - -// 0x07009FD0 -ALIGNED8 static const Texture texture_menu_hud_char_hiragana_no[] = { -#include "levels/menu/main_menu_seg7.09FD0.rgba16.inc.c" -}; - -// 0x0700A1D0 -ALIGNED8 static const Texture texture_menu_hud_char_question[] = { -#include "levels/menu/main_menu_seg7.0A1D0.rgba16.inc.c" -}; - -// 0x0700A3D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_sa[] = { -#include "levels/menu/main_menu_seg7.0A3D0.rgba16.inc.c" -}; - -// 0x0700A5D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_u[] = { -#include "levels/menu/main_menu_seg7.0A5D0.rgba16.inc.c" -}; - -// 0x0700A7D0 -ALIGNED8 static const Texture texture_menu_hud_char_katakana_n[] = { -#include "levels/menu/main_menu_seg7.0A7D0.rgba16.inc.c" -}; - -// 0x0700A9D0 -ALIGNED8 static const Texture texture_menu_hud_char_kana_dakuten_do[] = { -#include "levels/menu/main_menu_seg7.0A9D0.rgba16.inc.c" -}; - -// Menu HUD print table, only used in JP -// 0x0700ABD0 -const Texture *const menu_hud_lut[] = { - texture_menu_hud_char_katakana_hu, texture_menu_hud_char_katakana_small_a, texture_menu_hud_char_katakana_i, texture_menu_hud_char_katakana_ru, - texture_menu_hud_char_katakana_se, texture_menu_hud_char_katakana_re, texture_menu_hud_char_katakana_ku, texture_menu_hud_char_katakana_to, - texture_menu_hud_char_hiragana_wo, texture_menu_hud_char_katakana_ko, texture_menu_hud_char_kana_handakuten_pi, texture_menu_hud_char_choonpu, - texture_menu_hud_char_hiragana_su, texture_menu_hud_char_hiragana_ru, texture_menu_hud_char_hiragana_ke, texture_menu_hud_char_katakana_ma, - texture_menu_hud_char_katakana_ri, texture_menu_hud_char_katakana_o, texture_menu_hud_char_katakana_su, texture_menu_hud_char_katakana_a, - texture_menu_hud_char_hiragana_mi, texture_menu_hud_char_hira_dakuten_do, texture_menu_hud_char_hiragana_no, texture_menu_hud_char_question, - texture_menu_hud_char_katakana_sa, texture_menu_hud_char_katakana_u, texture_menu_hud_char_katakana_n, texture_menu_hud_char_kana_dakuten_do, -}; - -#if defined(VERSION_JP) || defined(VERSION_SH) -UNUSED static const u64 menu_unused_0 = 0; - +#ifdef JAPANESE_CHARACTERS // 0x0700AC48 ALIGNED8 static const Texture texture_menu_font_char_jp_0[] = { #include "levels/menu/main_menu_seg7.0AC48.ia8.inc.c" @@ -842,7 +686,7 @@ ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_u[] = { }; // 0x0700AF88 -ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_c[] = { +ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_e[] = { #include "levels/menu/main_menu_seg7.0AF88.ia8.inc.c" }; @@ -962,7 +806,7 @@ ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_hi[] = { }; // 0x0700B588 -ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_hu[] = { +ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_fu[] = { #include "levels/menu/main_menu_seg7.0B588.ia8.inc.c" }; @@ -1082,7 +926,7 @@ ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_small_o[] = { }; // 0x0700BB88 -ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_small_ka[] = { +ALIGNED8 static const Texture texture_menu_font_char_jp_hiragana_small_ya[] = { #include "levels/menu/main_menu_seg7.0BB88.ia8.inc.c" }; @@ -1252,7 +1096,7 @@ ALIGNED8 static const Texture texture_menu_font_char_jp_katakana_hi[] = { }; // 0x0700C408 -ALIGNED8 static const Texture texture_menu_font_char_jp_katakana_hu[] = { +ALIGNED8 static const Texture texture_menu_font_char_jp_katakana_fu[] = { #include "levels/menu/main_menu_seg7.0C408.ia8.inc.c" }; @@ -1372,7 +1216,7 @@ ALIGNED8 static const Texture texture_menu_font_char_jp_katakana_small_o[] = { }; // 0x0700CA08 -ALIGNED8 static const Texture texture_menu_font_char_jp_katakana_small_ka[] = { +ALIGNED8 static const Texture texture_menu_font_char_jp_katakana_small_ya[] = { #include "levels/menu/main_menu_seg7.0CA08.ia8.inc.c" }; @@ -1412,26 +1256,25 @@ ALIGNED8 static const Texture texture_menu_font_char_jp_D[] = { }; // 0x0700CC08 -ALIGNED8 static const Texture texture_menu_font_char_jp_coin[] = { -#include "levels/menu/main_menu_seg7.0CC08.ia8.inc.c" -}; +//ALIGNED8 static const Texture texture_menu_font_char_jp_coin[] = { +//#include "levels/menu/main_menu_seg7.0CC08.ia8.inc.c" +//}; // 0x0700CC48 -ALIGNED8 static const Texture texture_menu_font_char_jp_star_filled[] = { -#include "levels/menu/main_menu_seg7.0CC48.ia8.inc.c" -}; +//ALIGNED8 static const Texture texture_menu_font_char_jp_star_filled[] = { +//#include "levels/menu/main_menu_seg7.0CC48.ia8.inc.c" +//}; // 0x0700CC88 -ALIGNED8 static const Texture texture_menu_font_char_jp_multiply[] = { -#include "levels/menu/main_menu_seg7.0CC88.ia8.inc.c" -}; +//ALIGNED8 static const Texture texture_menu_font_char_jp_multiply[] = { +//#include "levels/menu/main_menu_seg7.0CC88.ia8.inc.c" +//}; // 0x0700CCC8 ALIGNED8 static const Texture texture_menu_font_char_jp_exclamation[] = { #include "levels/menu/main_menu_seg7.0CCC8.ia8.inc.c" }; - -#else +#endif // 0x0700AC40 ALIGNED8 static const Texture texture_menu_font_char_0[] = { @@ -1498,19 +1341,19 @@ ALIGNED8 static const Texture texture_menu_font_char_C[] = { #include "levels/menu/main_menu_seg7_us.0AF40.ia8.inc.c" }; -#ifdef VERSION_EU +//#ifdef VERSION_EU // 0x0700AF80 -ALIGNED8 static const Texture texture_menu_font_char_D[] = { -#include "levels/menu/main_menu_seg7_eu.0AF80.ia8.inc.c" -}; +//ALIGNED8 static const Texture texture_menu_font_char_D[] = { +//#include "levels/menu/main_menu_seg7_eu.0AF80.ia8.inc.c" +//}; -#else +//#else // 0x0700AF80 ALIGNED8 static const Texture texture_menu_font_char_D[] = { #include "levels/menu/main_menu_seg7_us.0AF80.ia8.inc.c" }; -#endif +//#endif // 0x0700AFC0 ALIGNED8 static const Texture texture_menu_font_char_E[] = { @@ -1642,18 +1485,18 @@ ALIGNED8 static const Texture texture_menu_font_char_dash[] = { #include "levels/menu/main_menu_seg7_us.0B600.ia8.inc.c" }; -#ifdef VERSION_EU +//#ifdef VERSION_EU // 0x0700B640 -ALIGNED8 static const Texture texture_menu_font_char_comma[] = { -#include "levels/menu/main_menu_seg7_eu.0B640.ia8.inc.c" -}; +//ALIGNED8 static const Texture texture_menu_font_char_comma[] = { +//#include "levels/menu/main_menu_seg7_eu.0B640.ia8.inc.c" +//}; // 0x0700B680 -ALIGNED8 static const Texture texture_menu_font_char_apostrophe[] = { -#include "levels/menu/main_menu_seg7_eu.0B680.ia8.inc.c" -}; +//ALIGNED8 static const Texture texture_menu_font_char_apostrophe[] = { +//#include "levels/menu/main_menu_seg7_eu.0B680.ia8.inc.c" +//}; -#else +//#else // 0x0700B640 ALIGNED8 static const Texture texture_menu_font_char_comma[] = { @@ -1664,7 +1507,7 @@ ALIGNED8 static const Texture texture_menu_font_char_comma[] = { ALIGNED8 static const Texture texture_menu_font_char_apostrophe[] = { #include "levels/menu/main_menu_seg7_us.0B680.ia8.inc.c" }; -#endif +//#endif // 0x0700B6C0 ALIGNED8 static const Texture texture_menu_font_char_exclamation[] = { @@ -1695,167 +1538,420 @@ ALIGNED8 static const Texture texture_menu_font_char_period[] = { ALIGNED8 static const Texture texture_menu_font_char_ampersand[] = { #include "levels/menu/main_menu_seg7_us.0B800.ia8.inc.c" }; -#endif -#ifdef VERSION_EU + // 0x0700B840 -ALIGNED8 static const Texture texture_menu_font_char_umlaut[] = { -#include "levels/menu/main_menu_seg7_eu.0B840.ia8.inc.c" +ALIGNED8 static const Texture texture_menu_font_char_diacritic_umlaut[] = { +#include "levels/menu/predone/main_menu_seg7_eu.0B840.ia8.inc.c" }; // 0x0700B880 -ALIGNED8 static const Texture texture_menu_font_char_cedilla_mayus[] = { -#include "levels/menu/main_menu_seg7_eu.0B880.ia8.inc.c" -}; +//ALIGNED8 static const Texture texture_menu_font_char_cedilla_mayus[] = { +//#include "levels/menu/main_menu_seg7_eu.0B880.ia8.inc.c" +//}; // 0x0700B8C0 ALIGNED8 static const Texture texture_menu_font_char_colon[] = { -#include "levels/menu/main_menu_seg7_eu.0B8C0.ia8.inc.c" +#include "levels/menu/predone/main_menu_seg7_eu.0B8C0.ia8.inc.c" }; -#endif -// Menu small font print table -// 0x0700CD08 -const Texture *const menu_font_lut[] = { -#if defined(VERSION_JP) || defined(VERSION_SH) - texture_menu_font_char_jp_0, texture_menu_font_char_jp_1, texture_menu_font_char_jp_2, texture_menu_font_char_jp_3, - texture_menu_font_char_jp_4, texture_menu_font_char_jp_5, texture_menu_font_char_jp_6, texture_menu_font_char_jp_7, - texture_menu_font_char_jp_8, texture_menu_font_char_jp_9, texture_menu_font_char_jp_A, texture_menu_font_char_jp_B, - texture_menu_font_char_jp_C, texture_menu_font_char_jp_D, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - texture_menu_font_char_jp_hiragana_a, texture_menu_font_char_jp_hiragana_i, texture_menu_font_char_jp_hiragana_u, texture_menu_font_char_jp_hiragana_c, - texture_menu_font_char_jp_hiragana_o, texture_menu_font_char_jp_hiragana_ka, texture_menu_font_char_jp_hiragana_ki, texture_menu_font_char_jp_hiragana_ku, - texture_menu_font_char_jp_hiragana_ke, texture_menu_font_char_jp_hiragana_ko, texture_menu_font_char_jp_hiragana_sa, texture_menu_font_char_jp_hiragana_shi, - texture_menu_font_char_jp_hiragana_su, texture_menu_font_char_jp_hiragana_se, texture_menu_font_char_jp_hiragana_so, texture_menu_font_char_jp_hiragana_ta, - texture_menu_font_char_jp_hiragana_chi, texture_menu_font_char_jp_hiragana_tsu, texture_menu_font_char_jp_hiragana_te, texture_menu_font_char_jp_hiragana_to, - texture_menu_font_char_jp_hiragana_na, texture_menu_font_char_jp_hiragana_ni, texture_menu_font_char_jp_hiragana_nu, texture_menu_font_char_jp_hiragana_ne, - texture_menu_font_char_jp_hiragana_no, texture_menu_font_char_jp_hiragana_ha, texture_menu_font_char_jp_hiragana_hi, texture_menu_font_char_jp_hiragana_hu, - texture_menu_font_char_jp_hiragana_he, texture_menu_font_char_jp_hiragana_ho, texture_menu_font_char_jp_hiragana_ma, texture_menu_font_char_jp_hiragana_mi, - texture_menu_font_char_jp_hiragana_mu, texture_menu_font_char_jp_hiragana_me, texture_menu_font_char_jp_hiragana_mo, texture_menu_font_char_jp_hiragana_ya, - texture_menu_font_char_jp_hiragana_yu, texture_menu_font_char_jp_hiragana_yo, texture_menu_font_char_jp_hiragana_ra, texture_menu_font_char_jp_hiragana_ri, - texture_menu_font_char_jp_hiragana_ru, texture_menu_font_char_jp_hiragana_re, texture_menu_font_char_jp_hiragana_ro, texture_menu_font_char_jp_hiragana_wa, - texture_menu_font_char_jp_hiragana_wo, texture_menu_font_char_jp_hiragana_n, 0x0, 0x0, - texture_menu_font_char_jp_katakana_a, texture_menu_font_char_jp_katakana_i, texture_menu_font_char_jp_katakana_u, texture_menu_font_char_jp_katakana_e, - texture_menu_font_char_jp_katakana_o, texture_menu_font_char_jp_katakana_ka, texture_menu_font_char_jp_katakana_ki, texture_menu_font_char_jp_katakana_ku, - texture_menu_font_char_jp_katakana_ke, texture_menu_font_char_jp_katakana_ko, texture_menu_font_char_jp_katakana_sa, texture_menu_font_char_jp_katakana_shi, - texture_menu_font_char_jp_katakana_su, texture_menu_font_char_jp_katakana_se, texture_menu_font_char_jp_katakana_so, texture_menu_font_char_jp_katakana_ta, - texture_menu_font_char_jp_katakana_chi, texture_menu_font_char_jp_katakana_tsu, texture_menu_font_char_jp_katakana_te, texture_menu_font_char_jp_katakana_to, - texture_menu_font_char_jp_katakana_na, texture_menu_font_char_jp_katakana_ni, texture_menu_font_char_jp_katakana_nu, texture_menu_font_char_jp_katakana_ne, - texture_menu_font_char_jp_katakana_no, texture_menu_font_char_jp_katakana_ha, texture_menu_font_char_jp_katakana_hi, texture_menu_font_char_jp_katakana_hu, - texture_menu_font_char_jp_katakana_he, texture_menu_font_char_jp_katakana_ho, texture_menu_font_char_jp_katakana_ma, texture_menu_font_char_jp_katakana_mi, - texture_menu_font_char_jp_katakana_mu, texture_menu_font_char_jp_katakana_me, texture_menu_font_char_jp_katakana_mo, texture_menu_font_char_jp_katakana_ya, - texture_menu_font_char_jp_katakana_yu, texture_menu_font_char_jp_katakana_yo, texture_menu_font_char_jp_katakana_ra, texture_menu_font_char_jp_katakana_ri, - texture_menu_font_char_jp_katakana_ru, texture_menu_font_char_jp_katakana_re, texture_menu_font_char_jp_katakana_ro, texture_menu_font_char_jp_katakana_wa, - texture_menu_font_char_jp_katakana_wo, texture_menu_font_char_jp_katakana_n, 0x0, texture_menu_font_char_jp_long_vowel, - texture_menu_font_char_jp_hiragana_small_e, texture_menu_font_char_jp_hiragana_small_tsu, texture_menu_font_char_jp_hiragana_small_ka, texture_menu_font_char_jp_hiragana_small_yu, - texture_menu_font_char_jp_hiragana_small_yo, texture_menu_font_char_jp_hiragana_small_a, texture_menu_font_char_jp_hiragana_small_i, texture_menu_font_char_jp_hiragana_small_u, - texture_menu_font_char_jp_hiragana_small_o, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - texture_menu_font_char_jp_katakana_small_e, texture_menu_font_char_jp_katakana_small_tsu, texture_menu_font_char_jp_katakana_small_ka, texture_menu_font_char_jp_katakana_small_yu, - texture_menu_font_char_jp_katakana_small_yo, texture_menu_font_char_jp_katakana_small_a, texture_menu_font_char_jp_katakana_small_i, texture_menu_font_char_jp_katakana_small_u, - texture_menu_font_char_jp_katakana_small_o, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - texture_menu_font_char_jp_dakuten, texture_menu_font_char_jp_handakuten, texture_menu_font_char_jp_exclamation, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, texture_menu_font_char_jp_coin, texture_menu_font_char_jp_star_filled, texture_menu_font_char_jp_multiply, - 0x0, 0x0, 0x0, 0x0, -#else - texture_menu_font_char_0, texture_menu_font_char_1, texture_menu_font_char_2, texture_menu_font_char_3, - texture_menu_font_char_4, texture_menu_font_char_5, texture_menu_font_char_6, texture_menu_font_char_7, - texture_menu_font_char_8, texture_menu_font_char_9, texture_menu_font_char_A, texture_menu_font_char_B, - texture_menu_font_char_C, texture_menu_font_char_D, texture_menu_font_char_E, texture_menu_font_char_F, - texture_menu_font_char_G, texture_menu_font_char_H, texture_menu_font_char_I, texture_menu_font_char_J, - texture_menu_font_char_K, texture_menu_font_char_L, texture_menu_font_char_M, texture_menu_font_char_N, - texture_menu_font_char_O, texture_menu_font_char_P, texture_menu_font_char_Q, texture_menu_font_char_R, - texture_menu_font_char_S, texture_menu_font_char_T, texture_menu_font_char_U, texture_menu_font_char_V, - texture_menu_font_char_W, texture_menu_font_char_X, texture_menu_font_char_Y, texture_menu_font_char_Z, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, texture_menu_font_char_apostrophe, texture_menu_font_char_period, - texture_menu_font_char_mface1, texture_menu_font_char_mface2, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, texture_menu_font_char_comma, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, texture_menu_font_char_dash, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, -#ifdef VERSION_EU - 0x0, texture_menu_font_char_ampersand, texture_menu_font_char_colon, 0x0, - 0x0, texture_menu_font_char_umlaut, 0x0, 0x0, - 0x0, texture_menu_font_char_cedilla_mayus, 0x0, 0x0, -#else - 0x0, texture_menu_font_char_ampersand, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, +// Custom Font + +ALIGNED8 static const Texture texture_menu_font_char_diacritic_cedilla[] = { +#include "levels/menu/custom/main_menu_seg7.cedilla.ia8.inc.c" +}; + +ALIGNED8 static const Texture texture_menu_font_char_inverted_exclamation_mark[] = { +#include "levels/menu/custom/main_menu_seg7.inverted_exclamation_mark.ia8.inc.c" +}; + +ALIGNED8 static const Texture texture_menu_font_char_inverted_question_mark[] = { +#include "levels/menu/custom/main_menu_seg7.inverted_question_mark.ia8.inc.c" +}; + +ALIGNED8 static const u8 texture_menu_font_char_diacritic_grave[] = { +#include "levels/menu/custom/main_menu_seg7.grave.ia8.inc.c" +}; + +ALIGNED8 static const u8 texture_menu_font_char_diacritic_acute[] = { +#include "levels/menu/custom/main_menu_seg7.acute.ia8.inc.c" +}; + +ALIGNED8 static const u8 texture_menu_font_char_diacritic_circumflex[] = { +#include "levels/menu/custom/main_menu_seg7.circumflex.ia8.inc.c" +}; + +ALIGNED8 static const u8 texture_menu_font_char_diacritic_tilde[] = { +#include "levels/menu/custom/main_menu_seg7.tilde_diacritic.ia8.inc.c" +}; + +ALIGNED8 static const Texture texture_menu_font_missing_character[] = { +#include "levels/menu/custom/main_menu_seg7.missing_character.ia8.inc.c" +}; + +// Diacritics for the small white menu font +const struct DiacriticLUTEntry menu_font_diacritic_lut[] = { + [TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE] = {-1, 5, "ˆ"}, + [TEXT_DIACRITIC_ACUTE_UPPERCASE] = { 0, 5, "ˊ"}, + [TEXT_DIACRITIC_GRAVE_UPPERCASE] = { 0, 5, "ˋ"}, + [TEXT_DIACRITIC_TILDE_UPPERCASE] = { 0, 5, "˜"}, + [TEXT_DIACRITIC_UMLAUT_UPPERCASE] = { 0, 4, "¨"}, + [TEXT_DIACRITIC_CEDILLA] = { 0, -2, "¸"}, +#ifdef JAPANESE_CHARACTERS + [TEXT_DIACRITIC_DAKUTEN] = { 6, 7, "゛"}, + [TEXT_DIACRITIC_HANDAKUTEN] = { 6, 7, "゜"}, #endif - 0x0, 0x0, texture_menu_font_char_exclamation, 0x0, - texture_menu_font_char_question, 0x0, 0x0, 0x0, - 0x0, texture_menu_font_char_coin, texture_menu_font_char_star_filled, texture_menu_font_char_multiply, - 0x0, 0x0, 0x0, 0x0, +}; + +// ASCII lookup table for the small white menu font +const struct AsciiCharLUTEntry menu_font_lut[] = { + {NULL, 4}, // 32 " " + {texture_menu_font_char_exclamation, 5}, // 33 "!" + {NULL, 0}, // 34 "\"" (Unimplemented) + {NULL, 0}, // 35 "#" (Unimplemented) + {NULL, 0}, // 36 "$" (Unimplemented) + {NULL, 0}, // 37 "%" (Unimplemented) + {texture_menu_font_char_ampersand, 8}, // 38 "&" + {texture_menu_font_char_apostrophe, 4}, // 39 "'" + {NULL, 0}, // 40 "(" (Unimplemented) + {NULL, 0}, // 41 ")" (Unimplemented) + {NULL, 0}, // 42 "*" (Unimplemented) + {NULL, 0}, // 43 "+" (Unimplemented) + {texture_menu_font_char_comma, 4}, // 44 "," + {texture_menu_font_char_dash, 6}, // 45 "-" + {texture_menu_font_char_period, 4}, // 46 "." + {NULL, 0}, // 47 "/" (Unimplemented) + {texture_menu_font_char_0, 7}, // 48 "0" + {texture_menu_font_char_1, 7}, // 49 "1" + {texture_menu_font_char_2, 7}, // 50 "2" + {texture_menu_font_char_3, 7}, // 51 "3" + {texture_menu_font_char_4, 7}, // 52 "4" + {texture_menu_font_char_5, 7}, // 53 "5" + {texture_menu_font_char_6, 7}, // 54 "6" + {texture_menu_font_char_7, 7}, // 55 "7" + {texture_menu_font_char_8, 7}, // 56 "8" + {texture_menu_font_char_9, 7}, // 57 "9" + {texture_menu_font_char_colon, 4}, // 58 ":" + {NULL, 0}, // 59 ";" (Unimplemented) + {NULL, 0}, // 60 "<" (Unimplemented) + {NULL, 0}, // 61 "=" (Unimplemented) + {NULL, 0}, // 62 ">" (Unimplemented) + {texture_menu_font_char_question, 7}, // 63 "?" + {NULL, 0}, // 64 "@" (Unimplemented) + {texture_menu_font_char_A, 6}, // 65 "A" + {texture_menu_font_char_B, 6}, // 66 "B" + {texture_menu_font_char_C, 6}, // 67 "C" + {texture_menu_font_char_D, 6}, // 68 "D" + {texture_menu_font_char_E, 6}, // 69 "E" + {texture_menu_font_char_F, 6}, // 70 "F" + {texture_menu_font_char_G, 6}, // 71 "G" + {texture_menu_font_char_H, 6}, // 72 "H" + {texture_menu_font_char_I, 5}, // 73 "I" + {texture_menu_font_char_J, 6}, // 74 "J" + {texture_menu_font_char_K, 6}, // 75 "K" + {texture_menu_font_char_L, 5}, // 76 "L" + {texture_menu_font_char_M, 8}, // 77 "M" + {texture_menu_font_char_N, 8}, // 78 "N" + {texture_menu_font_char_O, 6}, // 79 "O" + {texture_menu_font_char_P, 6}, // 80 "P" + {texture_menu_font_char_Q, 6}, // 81 "Q" + {texture_menu_font_char_R, 6}, // 82 "R" + {texture_menu_font_char_S, 6}, // 83 "S" + {texture_menu_font_char_T, 5}, // 84 "T" + {texture_menu_font_char_U, 6}, // 85 "U" + {texture_menu_font_char_V, 6}, // 86 "V" + {texture_menu_font_char_W, 8}, // 87 "W" + {texture_menu_font_char_X, 7}, // 88 "X" + {texture_menu_font_char_Y, 6}, // 89 "Y" + {texture_menu_font_char_Z, 6}, // 90 "Z" + {NULL, 0}, // 91 "[" (Unimplemented) + {NULL, 0}, // 92 "\\" (Unimplemented) + {NULL, 0}, // 93 "]" (Unimplemented) + {NULL, 0}, // 94 "^" (Unimplemented) + {NULL, 0}, // 95 "_" (Unimplemented) + {NULL, 0}, // 96 "`" (Unimplemented) + {texture_menu_font_char_A, 6}, // 97 "a" + {texture_menu_font_char_B, 6}, // 98 "b" + {texture_menu_font_char_C, 6}, // 99 "c" + {texture_menu_font_char_D, 6}, // 100 "d" + {texture_menu_font_char_E, 6}, // 101 "e" + {texture_menu_font_char_F, 6}, // 102 "f" + {texture_menu_font_char_G, 6}, // 103 "g" + {texture_menu_font_char_H, 6}, // 104 "h" + {texture_menu_font_char_I, 5}, // 105 "i" + {texture_menu_font_char_J, 6}, // 106 "j" + {texture_menu_font_char_K, 6}, // 107 "k" + {texture_menu_font_char_L, 5}, // 108 "l" + {texture_menu_font_char_M, 8}, // 109 "m" + {texture_menu_font_char_N, 8}, // 110 "n" + {texture_menu_font_char_O, 6}, // 111 "o" + {texture_menu_font_char_P, 6}, // 112 "p" + {texture_menu_font_char_Q, 6}, // 113 "q" + {texture_menu_font_char_R, 6}, // 114 "r" + {texture_menu_font_char_S, 6}, // 115 "s" + {texture_menu_font_char_T, 5}, // 116 "t" + {texture_menu_font_char_U, 6}, // 117 "u" + {texture_menu_font_char_V, 6}, // 118 "v" + {texture_menu_font_char_W, 8}, // 119 "w" + {texture_menu_font_char_X, 7}, // 120 "x" + {texture_menu_font_char_Y, 6}, // 121 "y" + {texture_menu_font_char_Z, 6}, // 122 "z" + {texture_menu_font_char_mface1, 8}, // 123 "{" (First half of Mario face) + {NULL, 0}, // 124 "|" (Unimplemented) + {texture_menu_font_char_mface2, 8}, // 125 "}" (Second half of Mario face) + {NULL, 0}, // 126 "~" (Unimplemented) +}; + +// UTF-8 lookup tables for the small white menu font +const struct Utf8CharLUTEntry menu_font_utf8_2byte_lut[] = { + {0x00A1, 5, 0, texture_menu_font_char_inverted_exclamation_mark}, // ¡ + {0x00A8, 0, 0, texture_menu_font_char_diacritic_umlaut}, // ¨ + {0x00B8, 0, 0, texture_menu_font_char_diacritic_cedilla}, // ¸ + {0x00BF, 7, 0, texture_menu_font_char_inverted_question_mark}, // ¿ + + {0x00C0, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_menu_font_char_A}, // À + {0x00C1, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_menu_font_char_A}, // Á + {0x00C2, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_menu_font_char_A}, // Â + {0x00C3, 6, TEXT_DIACRITIC_TILDE_UPPERCASE, texture_menu_font_char_A}, // Ã + {0x00C4, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_menu_font_char_A}, // Ä + + {0x00C7, 6, TEXT_DIACRITIC_CEDILLA, texture_menu_font_char_C}, // Ç + {0x00C8, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_menu_font_char_E}, // È + {0x00C9, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_menu_font_char_E}, // É + {0x00CA, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_menu_font_char_E}, // Ê + {0x00CB, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_menu_font_char_E}, // Ë + + {0x00CC, 5, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_menu_font_char_I}, // Ì + {0x00CD, 5, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_menu_font_char_I}, // Í + {0x00CE, 5, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_menu_font_char_I}, // Î + {0x00CF, 5, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_menu_font_char_I}, // Ï + + {0x00D1, 6, TEXT_DIACRITIC_TILDE_UPPERCASE, texture_menu_font_char_N}, // Ñ + {0x00D2, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_menu_font_char_O}, // Ò + {0x00D3, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_menu_font_char_O}, // Ó + {0x00D4, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_menu_font_char_O}, // Ô + {0x00D5, 6, TEXT_DIACRITIC_TILDE_UPPERCASE, texture_menu_font_char_O}, // Õ + {0x00D6, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_menu_font_char_O}, // Ö + + {0x00D7, 9, 0, texture_menu_font_char_multiply}, // × + + {0x00D9, 6, TEXT_DIACRITIC_GRAVE_UPPERCASE, texture_menu_font_char_U}, // Ù + {0x00DA, 6, TEXT_DIACRITIC_ACUTE_UPPERCASE, texture_menu_font_char_U}, // Ú + {0x00DB, 6, TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, texture_menu_font_char_U}, // Û + {0x00DC, 6, TEXT_DIACRITIC_UMLAUT_UPPERCASE, texture_menu_font_char_U}, // Ü + + {0x02C6, 0, 0, texture_menu_font_char_diacritic_circumflex}, // ˆ + {0x02CA, 0, 0, texture_menu_font_char_diacritic_acute}, // ˊ + {0x02CB, 0, 0, texture_menu_font_char_diacritic_grave}, // ˋ + {0x02DC, 0, 0, texture_menu_font_char_diacritic_tilde}, // ˜ +}; + +const struct Utf8CharLUTEntry menu_font_utf8_3byte_lut[] = { + {0x2605, 10, 0, texture_menu_font_char_star_filled}, // ★ + {0x272A, 8, 0, texture_menu_font_char_coin}, // ✪ + +#ifdef JAPANESE_CHARACTERS + {0x3000, 9, 0, NULL}, // " " (ideographic space) + {0x3041, 9, 0, texture_menu_font_char_jp_hiragana_small_a}, // ぁ + {0x3042, 9, 0, texture_menu_font_char_jp_hiragana_a}, // あ + {0x3043, 9, 0, texture_menu_font_char_jp_hiragana_small_i}, // ぃ + {0x3044, 9, 0, texture_menu_font_char_jp_hiragana_i}, // い + {0x3045, 9, 0, texture_menu_font_char_jp_hiragana_small_u}, // ぅ + {0x3046, 9, 0, texture_menu_font_char_jp_hiragana_u}, // う + {0x3047, 9, 0, texture_menu_font_char_jp_hiragana_small_e}, // ぇ + {0x3048, 9, 0, texture_menu_font_char_jp_hiragana_e}, // え + {0x3049, 9, 0, texture_menu_font_char_jp_hiragana_small_o}, // ぉ + {0x304A, 9, 0, texture_menu_font_char_jp_hiragana_o}, // お + {0x304B, 9, 0, texture_menu_font_char_jp_hiragana_ka}, // か + {0x304C, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ka}, // が + {0x304D, 9, 0, texture_menu_font_char_jp_hiragana_ki}, // き + {0x304E, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ki}, // ぎ + {0x304F, 9, 0, texture_menu_font_char_jp_hiragana_ku}, // く + {0x3050, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ku}, // ぐ + {0x3051, 9, 0, texture_menu_font_char_jp_hiragana_ke}, // け + {0x3052, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ke}, // げ + {0x3053, 9, 0, texture_menu_font_char_jp_hiragana_ko}, // こ + {0x3054, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ko}, // ご + {0x3055, 9, 0, texture_menu_font_char_jp_hiragana_sa}, // さ + {0x3056, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_sa}, // ざ + {0x3057, 9, 0, texture_menu_font_char_jp_hiragana_shi}, // し + {0x3058, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_shi}, // じ + {0x3059, 9, 0, texture_menu_font_char_jp_hiragana_su}, // す + {0x305A, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_su}, // ず + {0x305B, 9, 0, texture_menu_font_char_jp_hiragana_se}, // せ + {0x305C, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_se}, // ぜ + {0x305D, 9, 0, texture_menu_font_char_jp_hiragana_so}, // そ + {0x305E, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_so}, // ぞ + {0x305F, 9, 0, texture_menu_font_char_jp_hiragana_ta}, // た + {0x3060, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ta}, // だ + {0x3061, 9, 0, texture_menu_font_char_jp_hiragana_chi}, // ち + {0x3062, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_chi}, // ぢ + {0x3063, 9, 0, texture_menu_font_char_jp_hiragana_small_tsu}, // っ + {0x3064, 9, 0, texture_menu_font_char_jp_hiragana_tsu}, // つ + {0x3065, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_tsu}, // づ + {0x3066, 9, 0, texture_menu_font_char_jp_hiragana_te}, // て + {0x3067, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_te}, // で + {0x3068, 9, 0, texture_menu_font_char_jp_hiragana_to}, // と + {0x3069, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_to}, // ど + {0x306A, 9, 0, texture_menu_font_char_jp_hiragana_na}, // な + {0x306B, 9, 0, texture_menu_font_char_jp_hiragana_ni}, // に + {0x306C, 9, 0, texture_menu_font_char_jp_hiragana_nu}, // ぬ + {0x306D, 9, 0, texture_menu_font_char_jp_hiragana_ne}, // ね + {0x306E, 9, 0, texture_menu_font_char_jp_hiragana_no}, // の + {0x306F, 9, 0, texture_menu_font_char_jp_hiragana_ha}, // は + {0x3070, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ha}, // ば + {0x3071, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_hiragana_ha}, // ぱ + {0x3072, 9, 0, texture_menu_font_char_jp_hiragana_hi}, // ひ + {0x3073, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_hi}, // び + {0x3074, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_hiragana_hi}, // ぴ + {0x3075, 9, 0, texture_menu_font_char_jp_hiragana_fu}, // ふ + {0x3076, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_fu}, // ぶ + {0x3077, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_hiragana_fu}, // ぷ + {0x3078, 9, 0, texture_menu_font_char_jp_hiragana_he}, // へ + {0x3079, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_he}, // べ + {0x307A, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_hiragana_he}, // ぺ + {0x307B, 9, 0, texture_menu_font_char_jp_hiragana_ho}, // ほ + {0x307C, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_hiragana_ho}, // ぼ + {0x307D, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_hiragana_ho}, // ぽ + {0x307E, 9, 0, texture_menu_font_char_jp_hiragana_ma}, // ま + {0x307F, 9, 0, texture_menu_font_char_jp_hiragana_mi}, // み + {0x3080, 9, 0, texture_menu_font_char_jp_hiragana_mu}, // む + {0x3081, 9, 0, texture_menu_font_char_jp_hiragana_me}, // め + {0x3082, 9, 0, texture_menu_font_char_jp_hiragana_mo}, // も + {0x3083, 9, 0, texture_menu_font_char_jp_hiragana_small_ya}, // ゃ + {0x3084, 9, 0, texture_menu_font_char_jp_hiragana_ya}, // や + {0x3085, 9, 0, texture_menu_font_char_jp_hiragana_small_yu}, // ゅ + {0x3086, 9, 0, texture_menu_font_char_jp_hiragana_yu}, // ゆ + {0x3087, 9, 0, texture_menu_font_char_jp_hiragana_small_yo}, // ょ + {0x3088, 9, 0, texture_menu_font_char_jp_hiragana_yo}, // よ + {0x3089, 9, 0, texture_menu_font_char_jp_hiragana_ra}, // ら + {0x308A, 9, 0, texture_menu_font_char_jp_hiragana_ri}, // り + {0x308B, 9, 0, texture_menu_font_char_jp_hiragana_ru}, // る + {0x308C, 9, 0, texture_menu_font_char_jp_hiragana_re}, // れ + {0x308D, 9, 0, texture_menu_font_char_jp_hiragana_ro}, // ろ + {0x308F, 9, 0, texture_menu_font_char_jp_hiragana_wa}, // わ + {0x3092, 9, 0, texture_menu_font_char_jp_hiragana_wo}, // を + {0x3093, 9, 0, texture_menu_font_char_jp_hiragana_n}, // ん + + {0x309B, 0, 0, texture_menu_font_char_jp_dakuten}, // ゛ + {0x309C, 0, 0, texture_menu_font_char_jp_handakuten}, // ゜ + + {0x30A1, 9, 0, texture_menu_font_char_jp_katakana_small_a}, // ァ + {0x30A2, 9, 0, texture_menu_font_char_jp_katakana_a}, // ア + {0x30A3, 9, 0, texture_menu_font_char_jp_katakana_small_i}, // ィ + {0x30A4, 9, 0, texture_menu_font_char_jp_katakana_i}, // イ + {0x30A5, 9, 0, texture_menu_font_char_jp_katakana_small_u}, // ゥ + {0x30A6, 9, 0, texture_menu_font_char_jp_katakana_u}, // ウ + {0x30A7, 9, 0, texture_menu_font_char_jp_katakana_small_e}, // ェ + {0x30A8, 9, 0, texture_menu_font_char_jp_katakana_e}, // エ + {0x30A9, 9, 0, texture_menu_font_char_jp_katakana_small_o}, // ォ + {0x30AA, 9, 0, texture_menu_font_char_jp_katakana_o}, // オ + {0x30AB, 9, 0, texture_menu_font_char_jp_katakana_ka}, // カ + {0x30AC, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ka}, // ガ + {0x30AD, 9, 0, texture_menu_font_char_jp_katakana_ki}, // キ + {0x30AE, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ki}, // ギ + {0x30AF, 9, 0, texture_menu_font_char_jp_katakana_ku}, // ク + {0x30B0, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ku}, // グ + {0x30B1, 9, 0, texture_menu_font_char_jp_katakana_ke}, // ケ + {0x30B2, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ke}, // ゲ + {0x30B3, 9, 0, texture_menu_font_char_jp_katakana_ko}, // コ + {0x30B4, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ko}, // ゴ + {0x30B5, 9, 0, texture_menu_font_char_jp_katakana_sa}, // サ + {0x30B6, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_sa}, // ザ + {0x30B7, 9, 0, texture_menu_font_char_jp_katakana_shi}, // シ + {0x30B8, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_shi}, // ジ + {0x30B9, 9, 0, texture_menu_font_char_jp_katakana_su}, // ス + {0x30BA, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_su}, // ズ + {0x30BB, 9, 0, texture_menu_font_char_jp_katakana_se}, // セ + {0x30BC, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_se}, // ゼ + {0x30BD, 9, 0, texture_menu_font_char_jp_katakana_so}, // ソ + {0x30BE, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_so}, // ゾ + {0x30BF, 9, 0, texture_menu_font_char_jp_katakana_ta}, // タ + {0x30C0, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ta}, // ダ + {0x30C1, 9, 0, texture_menu_font_char_jp_katakana_chi}, // チ + {0x30C2, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_chi}, // ヂ + {0x30C3, 9, 0, texture_menu_font_char_jp_katakana_small_tsu}, // ッ + {0x30C4, 9, 0, texture_menu_font_char_jp_katakana_tsu}, // ツ + {0x30C5, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_tsu}, // ヅ + {0x30C6, 9, 0, texture_menu_font_char_jp_katakana_te}, // テ + {0x30C7, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_te}, // デ + {0x30C8, 9, 0, texture_menu_font_char_jp_katakana_to}, // ト + {0x30C9, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_to}, // ド + {0x30CA, 9, 0, texture_menu_font_char_jp_katakana_na}, // ナ + {0x30CB, 9, 0, texture_menu_font_char_jp_katakana_ni}, // ニ + {0x30CC, 9, 0, texture_menu_font_char_jp_katakana_nu}, // ヌ + {0x30CD, 9, 0, texture_menu_font_char_jp_katakana_ne}, // ネ + {0x30CE, 9, 0, texture_menu_font_char_jp_katakana_no}, // ノ + {0x30CF, 9, 0, texture_menu_font_char_jp_katakana_ha}, // ハ + {0x30D0, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ha}, // バ + {0x30D1, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_katakana_ha}, // パ + {0x30D2, 9, 0, texture_menu_font_char_jp_katakana_hi}, // ヒ + {0x30D3, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_hi}, // ビ + {0x30D4, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_katakana_hi}, // ピ + {0x30D5, 9, 0, texture_menu_font_char_jp_katakana_fu}, // フ + {0x30D6, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_fu}, // ブ + {0x30D7, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_katakana_fu}, // プ + {0x30D8, 9, 0, texture_menu_font_char_jp_katakana_he}, // ヘ + {0x30D9, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_he}, // ベ + {0x30DA, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_katakana_he}, // ペ + {0x30DB, 9, 0, texture_menu_font_char_jp_katakana_ho}, // ホ + {0x30DC, 9, TEXT_DIACRITIC_DAKUTEN, texture_menu_font_char_jp_katakana_ho}, // ボ + {0x30DD, 9, TEXT_DIACRITIC_HANDAKUTEN, texture_menu_font_char_jp_katakana_ho}, // ポ + {0x30DE, 9, 0, texture_menu_font_char_jp_katakana_ma}, // マ + {0x30DF, 9, 0, texture_menu_font_char_jp_katakana_mi}, // ミ + {0x30E0, 9, 0, texture_menu_font_char_jp_katakana_mu}, // ム + {0x30E1, 9, 0, texture_menu_font_char_jp_katakana_me}, // メ + {0x30E2, 9, 0, texture_menu_font_char_jp_katakana_mo}, // モ + {0x30E3, 9, 0, texture_menu_font_char_jp_katakana_small_ya}, // ャ + {0x30E4, 9, 0, texture_menu_font_char_jp_katakana_ya}, // ヤ + {0x30E5, 9, 0, texture_menu_font_char_jp_katakana_small_yu}, // ュ + {0x30E6, 9, 0, texture_menu_font_char_jp_katakana_yu}, // ユ + {0x30E7, 9, 0, texture_menu_font_char_jp_katakana_small_yo}, // ョ + {0x30E8, 9, 0, texture_menu_font_char_jp_katakana_yo}, // ヨ + {0x30E9, 9, 0, texture_menu_font_char_jp_katakana_ra}, // ラ + {0x30EA, 9, 0, texture_menu_font_char_jp_katakana_ri}, // リ + {0x30EB, 9, 0, texture_menu_font_char_jp_katakana_ru}, // ル + {0x30EC, 9, 0, texture_menu_font_char_jp_katakana_re}, // レ + {0x30ED, 9, 0, texture_menu_font_char_jp_katakana_ro}, // ロ + {0x30EF, 9, 0, texture_menu_font_char_jp_katakana_wa}, // ワ + {0x30F2, 9, 0, texture_menu_font_char_jp_katakana_wo}, // ヲ + {0x30F3, 9, 0, texture_menu_font_char_jp_katakana_n}, // ン + {0x30FC, 9, 0, texture_menu_font_char_jp_long_vowel}, // ー + + {0xFF01, 9, 0, texture_menu_font_char_jp_exclamation}, // ! + {0xFF10, 9, 0, texture_menu_font_char_jp_0}, // 0 + {0xFF11, 9, 0, texture_menu_font_char_jp_1}, // 1 + {0xFF12, 9, 0, texture_menu_font_char_jp_2}, // 2 + {0xFF13, 9, 0, texture_menu_font_char_jp_3}, // 3 + {0xFF14, 9, 0, texture_menu_font_char_jp_4}, // 4 + {0xFF15, 9, 0, texture_menu_font_char_jp_5}, // 5 + {0xFF16, 9, 0, texture_menu_font_char_jp_6}, // 6 + {0xFF17, 9, 0, texture_menu_font_char_jp_7}, // 7 + {0xFF18, 9, 0, texture_menu_font_char_jp_8}, // 8 + {0xFF19, 9, 0, texture_menu_font_char_jp_9}, // 9 + {0xFF21, 9, 0, texture_menu_font_char_jp_A}, // A + {0xFF22, 9, 0, texture_menu_font_char_jp_B}, // B + {0xFF23, 9, 0, texture_menu_font_char_jp_C}, // C + {0xFF24, 9, 0, texture_menu_font_char_jp_D}, // D #endif }; +const struct Utf8CharLUTEntry menu_font_utf8_4byte_lut[] = { + +}; + +const struct Utf8CharLUTEntry menu_font_utf8_missing_char = {0, 8, 0, texture_menu_font_missing_character}; + +const struct Utf8LUT menu_font_utf8_lut = { + menu_font_utf8_2byte_lut, + menu_font_utf8_3byte_lut, + menu_font_utf8_4byte_lut, + ARRAY_COUNT(menu_font_utf8_2byte_lut), + ARRAY_COUNT(menu_font_utf8_3byte_lut), + ARRAY_COUNT(menu_font_utf8_4byte_lut), + &menu_font_utf8_missing_char, +}; + // 0x0700D108 - 0x0700D160 const Gfx dl_menu_ia8_text_begin[] = { gsDPPipeSync(), @@ -2005,22 +2101,60 @@ const Collision main_menu_seg7_collision[] = { COL_END(), }; -#ifdef VERSION_EU +#ifdef MULTILANG // Duplicate course name tables; the main menu needs all languages loaded at // once since it switches language, so the copies in segment 19 aren't good // enough. -#define COURSE_TABLE eu_course_strings_en_table -#include "text/us/define_courses.inc.c" -#undef COURSE_TABLE +#define COURSE_NAME_TABLE course_strings_en_table +#define COURSE_FILE "us/courses.h" +#include "text/define_courses.inc.c" +#undef COURSE_NAME_TABLE +#undef COURSE_FILE + +#ifdef ENABLE_FRENCH +#define COURSE_NAME_TABLE course_strings_fr_table +#define COURSE_FILE "fr/courses.h" +#include "text/define_courses.inc.c" +#undef COURSE_NAME_TABLE +#undef COURSE_FILE +#endif -#define COURSE_TABLE eu_course_strings_fr_table -#include "text/fr/define_courses.inc.c" -#undef COURSE_TABLE +#ifdef ENABLE_GERMAN +#define COURSE_NAME_TABLE course_strings_de_table +#define COURSE_FILE "de/courses.h" +#include "text/define_courses.inc.c" +#undef COURSE_NAME_TABLE +#undef COURSE_FILE +#endif -#define COURSE_TABLE eu_course_strings_de_table -#include "text/de/define_courses.inc.c" -#undef COURSE_TABLE +#ifdef ENABLE_JAPANESE +#define COURSE_NAME_TABLE course_strings_jp_table +#define COURSE_FILE "jp/courses.h" +#include "text/define_courses.inc.c" +#undef COURSE_NAME_TABLE +#undef COURSE_FILE +#endif +const char *(*course_strings_language_table[])[] = { + &course_strings_en_table, +#ifdef ENABLE_FRENCH + &course_strings_fr_table, +#else + NULL, #endif +#ifdef ENABLE_GERMAN + &course_strings_de_table, +#else + NULL, +#endif +#ifdef ENABLE_JAPANESE + &course_strings_jp_table, +#else + NULL, +#endif +}; + +#endif + diff --git a/levels/menu/predone/main_menu_seg7_eu.0B840.ia8.png b/levels/menu/predone/main_menu_seg7_eu.0B840.ia8.png new file mode 100644 index 0000000000000000000000000000000000000000..6f361e5e95dad0c79bcfcd724d76d5ef040eee3c GIT binary patch literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^93afW0wnX;%77$;u&0Y-NJU(-0^gti=MOL(;@QH) XP$|p&_wgg^>mYegS3j3^P6= '0' && c <= '9') - return (c - '0' + 0x00); - - if (c >= 'A' && c <= 'Z') - return (c - 'A' + 0x0A); - - if (c >= 'a' && c <= 'z') - return (c - 'a' + 0x24); - - if (c == '\'') return 0x3E; - if (c == '.') return 0x3F; - if (c == ',') return 0x6F; - if (c == ' ') return 0x9E; - if (c == '-') return 0x9F; - if (c == '(') return 0xE1; - if (c == ')') return 0xE3; - if (c == '+') return 0xE4; - if (c == '&') return 0xE5; - if (c == ':') return 0xE6; - if (c == '!') return 0xF2; - if (c == '%') return 0xF3; - if (c == '?') return 0xF4; - if (c == '~') return 0xF7; - if (c == '$') return 0xF9; - if (c == '*') return 0xFA; - if (c == '#') return 0xFD; - if (c == '\n') return 0xFE; - - return 0x9E; -} - -s16 get_hud_str_width(u8 *str) { - u32 c; - s16 length = 0; - - while ((c = *str++) != GLOBAL_CHAR_TERMINATOR) { - length += (c == GLOBAL_CHAR_SPACE ? (HUD_LUT_STRIDE_GLOBAL / 2) : HUD_LUT_STRIDE_GLOBAL); - } - - return length; -} - -s16 get_hud_str_width_ascii(char *str) { - u32 c; - s16 length = 0; - - while ((c = *str++) != GLOBAL_CHAR_TERMINATOR) { - length += (c == ' ' ? (HUD_LUT_STRIDE_GLOBAL / 2) : HUD_LUT_STRIDE_GLOBAL); - } - - return length; -} - -s16 get_string_width_ascii(char *str) { - s16 i; - u8 buf[100]; - s16 bufPos = 0; - s16 width = 0; - - for (i = 0; str[i] != 0; i++) - buf[i] = ascii_to_font_char(str[i]); - buf[i] = DIALOG_CHAR_TERMINATOR; - - while (buf[bufPos] != DIALOG_CHAR_TERMINATOR) { - #if defined(VERSION_US) || defined(VERSION_EU) - width += gDialogCharWidths[buf[bufPos]]; - #else - width += JP_DIALOG_CHAR_WIDTH; - #endif - bufPos++; - } - - return width; -} - -s16 get_str_x_pos_from_center_custom_hex(s16 lutType, s16 centerPos, u8 *strHex, u8 useScale, f32 scale) { - s16 spacesWidth = 0; - - switch (lutType) { - case LUT_TYPE_HUD_HEX: - spacesWidth = get_hud_str_width(strHex); - break; - case LUT_TYPE_STR_HEX: - spacesWidth = get_string_width(strHex); - break; - default: - break; - } - - if (useScale) { - return (f32) centerPos - ((scale / 2.0) * (spacesWidth / 2.0)); - } - - // return the x position of where the string starts as half the string's - // length from the position of the provided center. - return (centerPos - (spacesWidth / 2.0)); -} - -s16 get_str_x_pos_from_center_custom_ascii(s16 lutType, s16 centerPos, char *strAscii, u8 useScale, f32 scale) { - s16 spacesWidth = 0; - - switch (lutType) { - case LUT_TYPE_HUD_ASCII: - spacesWidth = get_hud_str_width_ascii(strAscii); - break; - case LUT_TYPE_STR_ASCII: - spacesWidth = get_string_width_ascii(strAscii); - break; - default: - break; - } - - if (useScale) { - return (f32) centerPos - ((scale / 2.0) * (spacesWidth / 2.0)); - } - - // return the x position of where the string starts as half the string's - // length from the position of the provided center. - return (centerPos - (spacesWidth / 2.0)); -} - /** * Convert texture resolution to mask. */ @@ -273,22 +147,9 @@ static void allocate_quad_vertices(Gfx *dlHead, u16 w, u16 h) { /****************** * MISC RENDERING * ******************/ - -/** - * Like print_generic_string but uses ASCII, then it transform it to hex. - */ -void print_generic_string_ascii(s16 x, s16 y, const char *str) { - s16 i; - u8 buf[100]; - for (i = 0; str[i] != 0; i++) - buf[i] = ascii_to_font_char(str[i]); - buf[i] = DIALOG_CHAR_TERMINATOR; - - print_generic_string(x, y, buf); -} /** - * An detailed version of print_generic_strig_ascii that let's you + * An detailed version of print_generic_string that let's you * color the font and add shadow to it. */ void print_generic_string_detail(s16 x, s16 y, u8 *str, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad) { @@ -301,20 +162,6 @@ void print_generic_string_detail(s16 x, s16 y, u8 *str, u8 r, u8 g, u8 b, u8 a, print_generic_string(x, y, str); } -/** - * An detailed version of print_generic_strig that let's you - * color the font and add shadow to it. - */ -void print_generic_string_ascii_detail(s16 x, s16 y, const char *str, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad) { - if (hasShadow) { - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); - print_generic_string_ascii(x + shadowPad, y - shadowPad, str); - } - - gDPSetEnvColor(gDisplayListHead++, r, g, b, a); - print_generic_string_ascii(x, y, str); -} - /** * Prints a quadrilateral solid color. */ diff --git a/src/extras/draw_util.h b/src/extras/draw_util.h index 78a6c5d0e..677daf7f6 100644 --- a/src/extras/draw_util.h +++ b/src/extras/draw_util.h @@ -3,33 +3,12 @@ #include #include "game/ingame_menu.h" -// get_str_x_pos_from_center_custom_hex -enum xPosCenterCustomTypesHex { - LUT_TYPE_HUD_HEX, - LUT_TYPE_STR_HEX -}; - -// get_str_x_pos_from_center_custom_ascii -enum xPosCenterCustomTypesAscii { - LUT_TYPE_HUD_ASCII, - LUT_TYPE_STR_ASCII -}; - extern Gfx dl_texture_rect_ex_start[]; extern Gfx dl_texture_rect_ex_end[]; extern Gfx dl_tri_quad_ex_start[]; extern Gfx dl_tri_quad_ex_end[]; -s16 get_hud_str_width(u8 *str); -s16 get_hud_str_width_ascii(char *str); -s16 get_string_width_ascii(char *str); - -s16 get_str_x_pos_from_center_custom_hex(s16 lutType, s16 centerPos, u8 *strHex, u8 useScale, f32 scale); -s16 get_str_x_pos_from_center_custom_ascii(s16 lutType, s16 centerPos, char *strAscii, u8 useScale, f32 scale); - -void print_generic_string_ascii(s16 x, s16 y, const char *str); void print_generic_string_detail(s16 x, s16 y, u8 *text, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad); -void print_generic_string_ascii_detail(s16 x, s16 y, const char *str, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad); void print_solid_color_quad(s16 x1, s16 y1, s16 x2, s16 y2, u8 r, u8 g, u8 b, u8 a); diff --git a/src/extras/redone/title_screen.inc.c b/src/extras/redone/title_screen.inc.c index 780601678..d12232404 100644 --- a/src/extras/redone/title_screen.inc.c +++ b/src/extras/redone/title_screen.inc.c @@ -48,7 +48,7 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { gDPSetEnvColor(gDisplayListHead++, 255, 155, 150, 255); chrTemp = "SUPER MARIO LEVEL SELECT"; xPos = get_str_x_pos_from_center_custom_ascii(LUT_TYPE_STR_ASCII, SCREEN_WIDTH / 2, chrTemp, FALSE, 0); - print_generic_string_ascii(xPos, 210, chrTemp); + print_generic_string(xPos, 210, chrTemp); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); if (this->toggleControlsView) { @@ -93,16 +93,20 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { if (this->toggleCourseLevelView) { chrTemp = "LEVEL NAME"; print_generic_string(72, 180 - i * 11, levelNumStr); - print_generic_string_ascii(100, 180 - i * 11, levelName); + print_generic_string(100, 180 - i * 11, levelName); } else { chrTemp = "COURSE NAME"; print_generic_string(72, 180 - i * 11, courseNumStr); if (courseName != NULL && courseNum >= COURSE_MIN && courseNum <= COURSE_MAX) { - print_generic_string(100, 180 - i * 11, &courseName[3]); + if (check_number_string_in_course_names(courseName)) { + print_generic_string(100, 180 - i * 11, &courseName[3]); + } else { + print_generic_string(100, 180 - i * 11, courseName); + } } } gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - print_generic_string_ascii(60, 194, chrTemp); + print_generic_string(60, 194, chrTemp); } } @@ -141,18 +145,18 @@ void print_debug_level_select_settings(struct ZDebugLevelSelect *this) { gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); chrTemp = "Save File: "; - print_generic_string_ascii(20, 42, chrTemp); + print_generic_string(20, 42, chrTemp); print_generic_string(20 + get_string_width_ascii(chrTemp), 42, strSaveNum); chrTemp = "Level Act: "; - print_generic_string_ascii(20, 28, chrTemp); + print_generic_string(20, 28, chrTemp); print_generic_string(20 + get_string_width_ascii(chrTemp), 28, strActNum); if (actName != NULL && courseNum >= COURSE_MIN && courseNum <= COURSE_STAGES_MAX) { print_generic_string(20 + 20 + get_string_width_ascii(chrTemp), 28, actName); } chrTemp = "(C Down) - Show-Hide Controls"; - print_generic_string_ascii(20, 14, chrTemp); + print_generic_string(20, 14, chrTemp); } const char lvlSelectDbgCtrlStr[][40] = { @@ -170,10 +174,10 @@ const char lvlSelectDbgCtrlViewStr[] = { "(C Down) - Show-Hide Controls" }; void print_debug_level_select_controls(void) { s32 i; for (i = 0; i < ARRAY_COUNT(lvlSelectDbgCtrlStr); i++) { - print_generic_string_ascii(40, 186 - i * 16, lvlSelectDbgCtrlStr[i]); + print_generic_string(40, 186 - i * 16, lvlSelectDbgCtrlStr[i]); } - print_generic_string_ascii(40, 38, lvlSelectDbgCtrlViewStr); + print_generic_string(40, 38, lvlSelectDbgCtrlViewStr); } void print_debug_level_select_strings(struct ZDebugLevelSelect *this) { diff --git a/src/game/area.c b/src/game/area.c index ea9a9b50c..cf2eff469 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -86,13 +86,11 @@ Vp D_8032CF00 = { { { 640, 480, 511, 0 }, } }; -#ifdef VERSION_EU -const char *gNoControllerMsg[] = { +LangArray gNoControllerMsg = DEFINE_LANGUAGE_ARRAY( "NO CONTROLLER", "MANETTE DEBRANCHEE", "CONTROLLER FEHLT", -}; -#endif + "NO CONTROLLER"); void override_viewport_and_clip(Vp *a, Vp *b, u8 c, u8 d, u8 e) { u16 sp6 = ((c >> 3) << 11) | ((d >> 3) << 6) | ((e >> 3) << 1) | 1; @@ -111,29 +109,18 @@ void set_warp_transition_rgb(u8 red, u8 green, u8 blue) { gWarpTransBlue = blue; } -static int scale_x_to_correct_aspect_center(int x) { +static int scale_x_to_correct_aspect_center(int x) { // x is usually SCREEN_WIDTH / 2 f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO; return x + (SCREEN_HEIGHT * aspect / 2) - (SCREEN_WIDTH / 2); } void print_intro_text(void) { -#ifdef VERSION_EU - s32 language = eu_get_language(); -#endif if ((gGlobalTimer & 31) < 20) { if (gControllerBits == 0) { -#ifdef VERSION_EU - print_text_centered(SCREEN_WIDTH / 2, 20, gNoControllerMsg[language]); -#else - print_text_centered(scale_x_to_correct_aspect_center(SCREEN_WIDTH / 2), 20, "NO CONTROLLER"); -#endif + print_text_centered(SCREEN_CENTER_X, 20, LANG_ARRAY(gNoControllerMsg)); } else { -#ifdef VERSION_EU - print_text(GFX_DIMENSIONS_FROM_LEFT_EDGE(20), 20, "START"); -#else print_text_centered(GFX_DIMENSIONS_FROM_LEFT_EDGE(60), 38, "PRESS"); print_text_centered(GFX_DIMENSIONS_FROM_LEFT_EDGE(60), 20, "START"); -#endif } } } diff --git a/src/game/hud.c b/src/game/hud.c index 10db28fe0..ba5bbdce3 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -351,6 +351,7 @@ void render_hud_keys(void) { /** * Renders the timer when Mario start sliding in PSS. */ +/** void render_hud_timer(void) { u8 *(*hudLUT)[58] = segmented_to_virtual(&main_hud_lut); u16 timerValFrames = gHudDisplay.timer; @@ -386,7 +387,7 @@ void render_hud_timer(void) { render_hud_tex_lut(set_hud_auto_x_pos(HUD_TIME_SEC_AA_X), HUD_TIME_A_Y, (*hudLUT)[GLYPH_DOUBLE_QUOTE]); gSPDisplayList(gDisplayListHead++, dl_hud_img_end); } - + */ /** * Sets HUD status camera value depending of the actions * defined in update_camera_status. @@ -507,7 +508,7 @@ void render_hud(void) { } #if SHOW_TIMER if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER) { - render_hud_timer(); + //render_hud_timer(); } #endif } diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 32cb88b57..8b36db6ff 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -7,7 +7,7 @@ #include "course_table.h" #include "dialog_ids.h" #include "engine/math_util.h" -#include "eu_translation.h" +#include "segment_symbols.h" #include "game_init.h" #include "gfx_dimensions.h" #include "ingame_menu.h" @@ -20,64 +20,77 @@ #include "segment7.h" #include "seq_ids.h" #include "sm64.h" -#include "text_strings.h" #include "types.h" -#include "macros.h" +#include "config.h" +#include "main.h" // n64 +#include // non-n64 -#ifdef VERSION_EU -#undef LANGUAGE_FUNCTION -#define LANGUAGE_FUNCTION gInGameLanguage +u16 gDialogColorFadeTimer; +s8 gLastDialogLineNum; +DialogVariable gDialogVariable; +u16 gDialogTextAlpha; +s8 gRedCoinsCollected; + +// The language to display the game's text in. +u8 gInGameLanguage = LANGUAGE_ENGLISH; + +extern u8 dialog_table_en[]; +extern u8 course_name_table_en[]; +extern u8 act_name_table_en[]; + +#ifdef ENABLE_FRENCH +extern u8 dialog_table_fr[]; +extern u8 course_name_table_fr[]; +extern u8 act_name_table_fr[]; #endif -#ifdef CHEATS_ACTIONS -#include "extras/cheats.h" +#ifdef ENABLE_GERMAN +extern u8 dialog_table_de[]; +extern u8 course_name_table_de[]; +extern u8 act_name_table_de[]; #endif -#ifdef EXT_OPTIONS_MENU -#include "extras/options_menu.h" + +#ifdef ENABLE_JAPANESE +extern u8 dialog_table_jp[]; +extern u8 course_name_table_jp[]; +extern u8 act_name_table_jp[]; #endif -u16 gMenuTextColorTransTimer; -s8 gLastDialogLineNum; -s32 gDialogVariable; -u16 gMenuTextAlpha; -#ifdef VERSION_EU -s16 gDialogX; -s16 gDialogY; +// The language table for the game's dialogs, level names and act names. +void *languageTable[][3] = { +#ifndef MULTILANG + {&seg2_dialog_table, &seg2_course_name_table, &seg2_act_name_table}, +#else + {&dialog_table_en, &course_name_table_en, &act_name_table_en}, + +#ifdef ENABLE_FRENCH + {&dialog_table_fr, &course_name_table_fr, &act_name_table_fr}, +#else + {NULL, NULL, NULL}, #endif -s16 gCutsceneMsgXOffset; -s16 gCutsceneMsgYOffset; -s8 gRedCoinsCollected; -extern u8 gLastCompletedCourseNum; -extern u8 gLastCompletedStarNum; +#ifdef ENABLE_GERMAN + {&dialog_table_de, &course_name_table_de, &act_name_table_de}, +#else + {NULL, NULL, NULL}, +#endif -enum MenuState { - MENU_STATE_0, - MENU_STATE_1, - MENU_STATE_2, - MENU_STATE_3, - MENU_STATE_DEFAULT = MENU_STATE_0, - - // Dialog - MENU_STATE_DIALOG_OPENING = MENU_STATE_0, - MENU_STATE_DIALOG_OPEN = MENU_STATE_1, - MENU_STATE_DIALOG_SCROLLING = MENU_STATE_2, - MENU_STATE_DIALOG_CLOSING = MENU_STATE_3, - - // Pause Screen - MENU_STATE_PAUSE_SCREEN_OPENING = MENU_STATE_0, - MENU_STATE_PAUSE_SCREEN_COURSE = MENU_STATE_1, - MENU_STATE_PAUSE_SCREEN_CASTLE = MENU_STATE_2, - - // Course Complete Screen - MENU_STATE_COURSE_COMPLETE_SCREEN_OPENING = MENU_STATE_0, - MENU_STATE_COURSE_COMPLETE_SCREEN_OPEN = MENU_STATE_1 +#ifdef ENABLE_JAPANESE + {&dialog_table_jp, &course_name_table_jp, &act_name_table_jp}, +#else + {NULL, NULL, NULL}, +#endif +#endif }; -enum DialogBoxPageState { - DIALOG_PAGE_STATE_NONE, - DIALOG_PAGE_STATE_SCROLL, - DIALOG_PAGE_STATE_END +extern u8 gLastCompletedCourseNum; +extern u8 gLastCompletedStarNum; + +enum DialogBoxState { + DIALOG_STATE_OPENING, + DIALOG_STATE_VERTICAL, + DIALOG_STATE_HORIZONTAL, + DIALOG_STATE_CLOSING }; enum DialogBoxType { @@ -85,107 +98,44 @@ enum DialogBoxType { DIALOG_TYPE_ZOOM // used in signposts and wall signs and etc }; -#define DIALOG_BOX_ANGLE_DEFAULT 90.0f -#define DIALOG_BOX_SCALE_DEFAULT 19.0f - -#if defined(VERSION_US) || defined(VERSION_EU) -u8 gDialogCharWidths[256] = { // TODO: Is there a way to auto generate this? - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, - 6, 6, 5, 6, 6, 5, 8, 8, 6, 6, 6, 6, 6, 5, 6, 6, - 8, 7, 6, 6, 6, 5, 5, 6, 5, 5, 6, 5, 4, 5, 5, 3, - 7, 5, 5, 5, 6, 5, 5, 5, 5, 5, 7, 7, 5, 5, 4, 4, - 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 8, 8, 8, 7, 7, 6, 7, 7, 0, 0, 0, 0, 0, 0, 0, -#ifdef VERSION_EU - 6, 6, 6, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 4, - 5, 5, 5, 5, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 0, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 5, 6, - 0, 4, 4, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, -#else - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -#endif - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -#ifdef VERSION_EU - 7, 5, 10, 5, 9, 8, 4, 0, 0, 0, 0, 5, 5, 6, 5, 0, -#else - 7, 5, 10, 5, 9, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, -#endif - 0, 0, 5, 7, 7, 6, 6, 8, 0, 8, 10, 6, 4, 10, 0, 0 -}; -#endif +#define DEFAULT_DIALOG_BOX_ANGLE 90.0f +#define DEFAULT_DIALOG_BOX_SCALE 19.0f -s8 gMenuState = MENU_STATE_DEFAULT; -f32 gDialogBoxAngle = DIALOG_BOX_ANGLE_DEFAULT; -f32 gDialogBoxScale = DIALOG_BOX_SCALE_DEFAULT; +s8 gDialogBoxState = DIALOG_STATE_OPENING; +f32 gDialogBoxOpenTimer = DEFAULT_DIALOG_BOX_ANGLE; +f32 gDialogBoxScale = DEFAULT_DIALOG_BOX_SCALE; s16 gDialogScrollOffsetY = 0; s8 gDialogBoxType = DIALOG_TYPE_ROTATE; s16 gDialogID = DIALOG_NONE; -s16 gNextDialogPageStartStrIndex = 0; -s16 gDialogPageStartStrIndex = 0; -#ifdef VERSION_EU -s32 gInGameLanguage = LANGUAGE_ENGLISH; -#endif -s8 gMenuLineNum = 1; -s8 gDialogWithChoice = FALSE; +s16 gLastDialogPageStrPos = 0; +s16 gDialogTextPos = 0; +s8 gDialogLineNum = 1; +s8 gDialogHasResponse = FALSE; u8 gMenuHoldKeyIndex = 0; u8 gMenuHoldKeyTimer = 0; s32 gDialogResponse = DIALOG_RESPONSE_NONE; -#if !defined(EXTERNAL_DATA) && (defined(VERSION_JP) || defined(VERSION_SH) || defined(VERSION_EU)) -#ifdef VERSION_EU -#define CHCACHE_BUFLEN (8 * 8) // EU only converts 8x8 -#else -#define CHCACHE_BUFLEN (8 * 16) // JP only converts 8x16 or 16x8 characters -#endif -// stores char data unpacked from ia1 to ia8 or ia4 -// so that it won't be reconverted every time a character is rendered -static struct CachedChar { u8 used; u8 data[CHCACHE_BUFLEN]; } charCache[256]; -#endif // VERSION - -#ifdef HIGH_FPS_PC -static Gfx *sInterpolatedDialogOffsetPos; -static f32 sInterpolatedDialogOffset; -static Gfx *sInterpolatedDialogRotationPos; -static f32 sInterpolatedDialogScale; -static f32 sInterpolatedDialogRotation; -static Gfx *sInterpolatedDialogZoomPos; - -void patch_interpolated_dialog(void) { - Mtx *matrix; - - if (sInterpolatedDialogOffsetPos != NULL) { - matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); - guTranslate(matrix, 0, sInterpolatedDialogOffset, 0); - gSPMatrix(sInterpolatedDialogOffsetPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); - sInterpolatedDialogOffsetPos = NULL; - } - if (sInterpolatedDialogRotationPos != NULL) { - matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); - guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f); - gSPMatrix(sInterpolatedDialogRotationPos++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); - matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); - guRotate(matrix, sInterpolatedDialogRotation * 4.0f, 0, 0, 1.0f); - gSPMatrix(sInterpolatedDialogRotationPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); - sInterpolatedDialogRotationPos = NULL; - } - if (sInterpolatedDialogZoomPos != NULL) { - matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); - guTranslate(matrix, 65.0 - (65.0 / sInterpolatedDialogScale), (40.0 / sInterpolatedDialogScale) - 40, 0); - gSPMatrix(sInterpolatedDialogZoomPos++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); - matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); - guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f); - gSPMatrix(sInterpolatedDialogZoomPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH); - sInterpolatedDialogZoomPos = NULL; +static u8 sGenericFontLineHeight = 0; +static u8 sGenericFontLineAlignment = TEXT_ALIGN_LEFT; + +/************************************************** + * COMPATIBILITY * + **************************************************/ + +u8 check_number_string_in_course_name(char *courseName) { + // TODO JP Support + if ((courseName[0] == 0x20 || courseName[0] == 0x31) && + (courseName[1] == 0x20 || courseName[1] >= 0x30 && courseName[1] <= 0x39) && + courseName[2] == 0x20) { + return TRUE; } + + return FALSE; } -#endif + +/************************************************** + * MATRIX * + **************************************************/ void create_dl_identity_matrix(void) { Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); @@ -194,9 +144,6 @@ void create_dl_identity_matrix(void) { return; } - // ex-alo change - // Originally for GBI_FLOATS but it works on N64 and - // its smaller that the original long matrix code guMtxIdent(matrix); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH); @@ -271,487 +218,571 @@ void create_dl_ortho_matrix(void) { // Should produce G_RDPHALF_1 in Fast3D gSPPerspNormalize(gDisplayListHead++, 0xFFFF); - gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH) + gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH); } -#if defined(VERSION_JP) || defined(VERSION_SH) -static void alloc_ia8_text_from_i1(u8 *out, u16 *in, s16 width, s16 height) { - s32 inPos; - u16 bitMask; - u16 inWord; - s16 outPos = 0; +/** + * Determine which UTF-8 character to render, given a string and the current position in the string. + * Returns the table entry of the relevant character. + * Also increments the string position by the correct amount to reach the next character. + */ +struct Utf8CharLUTEntry *utf8_lookup(struct Utf8LUT *lut, char *str, s32 *strPos) { + u32 codepoint; + struct Utf8CharLUTEntry *usedLUT; + u32 length; + + lut = segmented_to_virtual(lut); + if (!(str[*strPos] & 0x20)) { + codepoint = ((str[*strPos] & 0x1F) << 6) | (str[*strPos + 1] & 0x3F); + *strPos += 1; + + usedLUT = segmented_to_virtual(lut->lut2Bytes); + length = lut->length2Bytes; + } else if (!(str[*strPos] & 0x10)) { + codepoint = ((str[*strPos] & 0xF) << 12) | ((str[*strPos + 1] & 0x3F) << 6) | (str[*strPos + 2] & 0x3F); + *strPos += 2; + + usedLUT = segmented_to_virtual(lut->lut3Bytes); + length = lut->length3Bytes; + } else { + codepoint = ((str[*strPos] & 0x7) << 18) | ((str[*strPos + 1] & 0x3F) << 12) | ((str[*strPos + 2] & 0x3F) << 6) | (str[*strPos + 3] & 0x3F); + *strPos += 3; - for (inPos = 0; inPos < (width * height) / 16; inPos++) { - inWord = BE_TO_HOST16(in[inPos]); - bitMask = 0x8000; + usedLUT = segmented_to_virtual(lut->lut4Bytes); + length = lut->length4Bytes; + } - while (bitMask != 0) { - if (inWord & bitMask) { - out[outPos] = 0xFF; - } else { - out[outPos] = 0x00; - } + s32 start = 0; + s32 end = length - 1; + s32 mid = (start + end) / 2; - bitMask /= 2; - outPos++; + while (start <= end) { + if (usedLUT[mid].codepoint == codepoint) { + return &usedLUT[mid]; + } + + if (usedLUT[mid].codepoint > codepoint) { + end = mid - 1; + } else { + start = mid + 1; } + + mid = (start + end) / 2; } + return segmented_to_virtual(lut->missingChar); } -static u8 *convert_ia8_char(u8 c, u16 *tex, s16 w, s16 h) { -#ifdef EXTERNAL_DATA - return (u8 *)tex; // the data's just a name -#else - if (!tex) return NULL; - if (!charCache[c].used) { - charCache[c].used = 1; - alloc_ia8_text_from_i1(charCache[c].data, tex, w, h); +/** + * Convert a character in the range 0-9 or A-F to an integer value. Returns -1 if the character is + * not a valid hex digit. + */ +static s32 hex_char_to_value(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; } - return charCache[c].data; -#endif + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + return -1; } -#endif -void render_generic_char(u8 c) { - void **fontLUT = segmented_to_virtual(main_font_lut); - void *packedTexture = segmented_to_virtual(fontLUT[c]); -#if defined(VERSION_JP) || defined(VERSION_SH) - void *unpackedTexture = convert_ia8_char(c, packedTexture, 8, 16); -#endif +/** + * Determine if the characters following an @ sign are a valid hex color code. + */ +static s32 is_color_code_valid(char *str, s32 strPos) { + for (s32 i = 0; i < 6; i++) { + if (hex_char_to_value(str[strPos + i]) == -1) { + return FALSE; + } + } + return TRUE; +} -#ifndef VERSION_EU - gDPPipeSync(gDisplayListHead++); -#endif -#if defined(VERSION_JP) || defined(VERSION_SH) - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture)); -#else - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(packedTexture)); -#endif - gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); -#ifdef VERSION_EU - gSPTextureRectangleFlip(gDisplayListHead++, gDialogX << 2, (gDialogY - 16) << 2, - (gDialogX + 8) << 2, gDialogY << 2, G_TX_RENDERTILE, 8 << 6, 4 << 6, 1 << 10, 1 << 10); +/** + * Get the exact width of the line of a string of any font in pixels, using the given ASCII and UTF-8 tables. + */ +s32 get_string_width(char *str, struct AsciiCharLUTEntry *asciiLut, struct Utf8LUT *utf8LUT) { + s32 width = 0; + s32 maxWidth = 0; + s32 strPos = 0; + char c; + + s32 isGenericFont = (asciiLut == main_font_lut); + + asciiLut = segmented_to_virtual(asciiLut); + + while ((c = str[strPos]) != '\0' && c != '\n') { + // Handle color codes and tabs if using generic font + if (isGenericFont) { + if (c == CHAR_COLOR_CODE) { + if (is_color_code_valid(str, strPos + 1)) { + strPos += 7; + continue; + } + } else if (c == '\t') { + width += 4 * SPACE_KERNING(asciiLut); + strPos++; + continue; + } + } + if (c & 0x80) { + width += utf8_lookup(utf8LUT, str, &strPos)->kerning; + } else { + width += asciiLut[ASCII_LUT_INDEX(c)].kerning; + } + strPos++; + } + + return MAX(width, maxWidth); +} + +/** + * Get the value to shift the X position of a string by, given a specific alignment. + */ +static s32 get_alignment_x_offset(char *str, u32 alignment, struct AsciiCharLUTEntry *asciiLut, struct Utf8LUT *utf8LUT) { + if (alignment == TEXT_ALIGN_LEFT) { + return 0; + } + s32 width = get_string_width(str, asciiLut, utf8LUT); + if (alignment == TEXT_ALIGN_CENTER) { + return -width / 2; + } + // TEXT_ALIGN_RIGHT + return -width; +} + +/** + * Takes a value and writes the string representation of the number into a buffer. + * If the language is set to Japanese, the number is written in full-width digits. + */ +void format_int_to_string(char *buf, s32 value) { +#ifdef ENABLE_JAPANESE + if (gInGameLanguage == LANGUAGE_JAPANESE) { + u8 digits[10]; + s32 numDigits = 0; + // Minus sign + if (value < 0) { + buf[0] = '-'; + buf++; + value = -value; + } + // Copy each digit of the number into an array, in reverse order. + do { + digits[numDigits++] = value % 10; + value /= 10; + } while (value != 0); + for (s32 i = 0; i < numDigits; i++) { + // The UTF-8 encoding of "0" is 0xEF, 0xBC, 0x90 + buf[i * 3] = 0xEF; + buf[i * 3 + 1] = 0xBC; + buf[i * 3 + 2] = 0x90 + digits[numDigits - i - 1]; + } + buf[numDigits * 3] = '\0'; + return; + } #endif + + sprintf(buf, "%d", value); } -#ifdef VERSION_EU -static void alloc_ia4_tex_from_i1(u8 *out, u8 *in, s16 width, s16 height) { +/** + * Unpacks a packed I1 character texture into a usable IA8 texture when TEXT_FLAG_PACKED is used. + * By default this is used for all the Japanese characters. + */ +static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) { s32 inPos; + u16 bitMask; + u8 *out; s16 outPos = 0; - u8 bitMask; - for (inPos = 0; inPos < (width * height) / 4; inPos++) { - bitMask = 0x80; + out = alloc_display_list((u32) width * (u32) height); + + if (out == NULL) { + return NULL; + } + + for (inPos = 0; inPos < (width * height) / 16; inPos++) { + bitMask = 0x8000; while (bitMask != 0) { - out[outPos] = (in[inPos] & bitMask) ? 0xF0 : 0x00; - bitMask /= 2; - out[outPos] = (in[inPos] & bitMask) ? out[outPos] + 0x0F : out[outPos]; + if (in[inPos] & bitMask) { + out[outPos] = 0xFF; + } else { + out[outPos] = 0x00; + } + bitMask /= 2; outPos++; } } -} -static u8 *convert_ia4_char(u8 c, u8 *tex, s16 w, s16 h) { -#ifdef EXTERNAL_DATA - return tex; // the data's just a name -#else - if (!tex) return NULL; - if (!charCache[c].used) { - charCache[c].used = 1; - alloc_ia4_tex_from_i1(charCache[c].data, tex, w, h); - } - return charCache[c].data; -#endif + return out; } -void render_generic_char_at_pos(s16 xPos, s16 yPos, u8 c) { - void **fontLUT = segmented_to_virtual(main_font_lut); - void *packedTexture = segmented_to_virtual(fontLUT[c]); - void *unpackedTexture = convert_ia4_char(c, packedTexture, 8, 8); +/** + * Renders a single ASCII character in the generic font. + */ +static u32 render_generic_ascii_char(char c) { + struct AsciiCharLUTEntry *fontLUT = segmented_to_virtual(main_font_lut); + const Texture *texture = fontLUT[ASCII_LUT_INDEX(c)].texture; - gDPPipeSync(gDisplayListHead++); - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture)); - gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); - gSPTextureRectangleFlip(gDisplayListHead++, xPos << 2, (yPos - 16) << 2, (xPos + 8) << 2, yPos << 2, - G_TX_RENDERTILE, 8 << 6, 4 << 6, 1 << 10, 1 << 10); -} + if (texture != NULL) { + gDPPipeSync(gDisplayListHead++); + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, texture); + gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); + } -void render_lowercase_diacritic(s16 *xPos, s16 *yPos, u8 letter, u8 diacritic) { - render_generic_char_at_pos(*xPos, *yPos, letter); - render_generic_char_at_pos(*xPos, *yPos, diacritic + 0xE7); - *xPos += gDialogCharWidths[letter]; + return fontLUT[ASCII_LUT_INDEX(c)].kerning; } -void render_uppercase_diacritic(s16 *xPos, s16 *yPos, u8 letter, u8 diacritic) { - render_generic_char_at_pos(*xPos, *yPos, letter); - render_generic_char_at_pos(*xPos, *yPos - 4, diacritic + 0xE3); - *xPos += gDialogCharWidths[letter]; -} -#endif // VERSION_EU +/** + * Renders a single UTF-8 character in the generic font. + */ +static u32 render_generic_unicode_char(char *str, s32 *strPos) { + struct Utf8CharLUTEntry *utf8Entry = utf8_lookup(&main_font_utf8_lut, str, strPos); -#if defined(VERSION_US) || defined(VERSION_EU) -struct MultiTextEntry { - u8 length; - u8 str[4]; -}; + if (utf8Entry->texture == NULL) { + return utf8Entry->kerning; + } -#define TEXT_THE_RAW ASCII_TO_DIALOG('t'), ASCII_TO_DIALOG('h'), ASCII_TO_DIALOG('e'), 0x00 -#define TEXT_YOU_RAW ASCII_TO_DIALOG('y'), ASCII_TO_DIALOG('o'), ASCII_TO_DIALOG('u'), 0x00 + gDPPipeSync(gDisplayListHead++); -enum MultiStringIDs { STRING_THE, STRING_YOU }; + if (utf8Entry->flags & TEXT_FLAG_PACKED) { + void *unpackedTexture = alloc_ia8_text_from_i1(segmented_to_virtual(utf8Entry->texture), 8, 16); + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, unpackedTexture); + gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings_packed); + } else { + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, utf8Entry->texture); + gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); + } -/* - * Place the multi-text string according to the ID passed. (US, EU) - * 0: 'the' - * 1: 'you' - */ -#if defined(VERSION_US) -void render_multi_text_string(s8 multiTextID) -#elif defined(VERSION_EU) -void render_multi_text_string(s16 *xPos, s16 *yPos, s8 multiTextID) -#endif -{ - s8 i; - struct MultiTextEntry textLengths[2] = { - { 3, { TEXT_THE_RAW } }, - { 3, { TEXT_YOU_RAW } }, - }; - - for (i = 0; i < textLengths[multiTextID].length; i++) { -#if defined(VERSION_US) - render_generic_char(textLengths[multiTextID].str[i]); - create_dl_translation_matrix( - MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[textLengths[multiTextID].str[i]]), 0.0f, 0.0f); -#elif defined(VERSION_EU) - render_generic_char_at_pos(*xPos, *yPos, textLengths[multiTextID].str[i]); - *xPos += gDialogCharWidths[textLengths[multiTextID].str[i]]; -#endif + if (utf8Entry->flags & TEXT_DIACRITIC_MASK) { + struct DiacriticLUTEntry *diacriticLUT = segmented_to_virtual(&main_font_diacritic_lut); + struct DiacriticLUTEntry *diacritic = &diacriticLUT[utf8Entry->flags & TEXT_DIACRITIC_MASK]; + + if (diacritic->xOffset | diacritic->yOffset) { + create_dl_translation_matrix(MENU_MTX_PUSH, diacritic->xOffset, diacritic->yOffset, 0.0f); + } + + s32 fakeStrPos = 0; + render_generic_unicode_char(segmented_to_virtual(diacritic->str), &fakeStrPos); + + if (diacritic->xOffset | diacritic->yOffset) { + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); + } } + + return utf8Entry->kerning; } -#endif -#if defined(VERSION_JP) || defined(VERSION_SH) - #define MAX_STRING_WIDTH 18 - #define CHAR_WIDTH_SPACE (f32)(JP_DIALOG_CHAR_WIDTH / 2) - #define CHAR_WIDTH_DEFAULT (f32)JP_DIALOG_CHAR_WIDTH +// Constants that control how the dialog box renders, the box is taller in Japanese. +#define DIALOG_LINE_HEIGHT_EN 16 +#define DIALOG_LINE_HEIGHT_JP 20 +#define BOX_TRANS_X_EN -7.f +#define BOX_TRANS_X_JP -5.f +#define BOX_TRANS_Y_EN 5.f +#define BOX_TRANS_Y_JP 2.f +#define BOX_SCALE_EN 5.f +#define BOX_SCALE_JP 4.f + +#ifdef ENABLE_JAPANESE +#define DIALOG_LINE_HEIGHT ((gInGameLanguage == LANGUAGE_JAPANESE) ? DIALOG_LINE_HEIGHT_JP : DIALOG_LINE_HEIGHT_EN) +#define BOX_TRANS_X ((gInGameLanguage == LANGUAGE_JAPANESE) ? BOX_TRANS_X_JP : BOX_TRANS_X_EN) +#define BOX_TRANS_Y ((gInGameLanguage == LANGUAGE_JAPANESE) ? BOX_TRANS_Y_JP : BOX_TRANS_Y_EN) +#define BOX_SCALE ((gInGameLanguage == LANGUAGE_JAPANESE) ? BOX_SCALE_JP : BOX_SCALE_EN) #else - #define MAX_STRING_WIDTH 16 - #define CHAR_WIDTH_SPACE (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE]) - #define CHAR_WIDTH_DEFAULT (f32)(gDialogCharWidths[str[strPos]]) +#define DIALOG_LINE_HEIGHT DIALOG_LINE_HEIGHT_EN +#define BOX_TRANS_X BOX_TRANS_X_EN +#define BOX_TRANS_Y BOX_TRANS_Y_EN +#define BOX_SCALE BOX_SCALE_EN #endif /** - * Prints a generic white string. - * In JP/EU a IA1 texture is used but in US a IA4 texture is used. + * Prints a generic white string. Used for both dialog entries and regular prints. + * Only prints a total of maxLines lines of text. If maxLines is -1, it will print + * until the end of the string. + * + * Uses the global variables sGenericFontLineHeight and sGenericFontLineAlignment + * to control printing. */ -void print_generic_string(s16 x, s16 y, const u8 *str) { - UNUSED s8 mark = DIALOG_MARK_NONE; // unused in EU +static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { s32 strPos = 0; - u8 lineNum = 1; -#ifdef VERSION_EU - s16 xCoord = x; - s16 yCoord = 240 - y; -#endif + char c; + s32 lineNum = 1; + s8 kerning = 0; + u8 queuedSpaces = 0; // Optimization to only have one translation matrix if there are multiple spaces in a row. + u8 color[3]; + s32 alignmentXOffset = get_alignment_x_offset(str, sGenericFontLineAlignment, main_font_lut, &main_font_utf8_lut); -#ifndef VERSION_EU create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0.0f); -#endif - while (str[strPos] != DIALOG_CHAR_TERMINATOR) { - switch (str[strPos]) { -#ifdef VERSION_EU - case DIALOG_CHAR_SPACE: - xCoord += 5; - break; - case DIALOG_CHAR_NEWLINE: - yCoord += 16; - xCoord = x; - lineNum++; - break; - case DIALOG_CHAR_LOWER_A_GRAVE: - case DIALOG_CHAR_LOWER_A_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_A_UMLAUT: - render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('a'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_UPPER_A_UMLAUT: // @bug grave and circumflex (0x64-0x65) are absent here - render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('A'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_LOWER_E_GRAVE: - case DIALOG_CHAR_LOWER_E_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_E_UMLAUT: - case DIALOG_CHAR_LOWER_E_ACUTE: - render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('e'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_UPPER_E_GRAVE: - case DIALOG_CHAR_UPPER_E_CIRCUMFLEX: - case DIALOG_CHAR_UPPER_E_UMLAUT: - case DIALOG_CHAR_UPPER_E_ACUTE: - render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('E'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_LOWER_U_GRAVE: - case DIALOG_CHAR_LOWER_U_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_U_UMLAUT: - render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('u'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_UPPER_U_UMLAUT: // @bug grave and circumflex (0x84-0x85) are absent here - render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('U'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_LOWER_O_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_O_UMLAUT: - render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('o'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_UPPER_O_UMLAUT: // @bug circumflex (0x95) is absent here - render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('O'), str[strPos] & 0xF); - break; - case DIALOG_CHAR_LOWER_I_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_I_UMLAUT: - render_lowercase_diacritic(&xCoord, &yCoord, DIALOG_CHAR_I_NO_DIA, str[strPos] & 0xF); - break; -#else // i.e. not EU - case DIALOG_CHAR_DAKUTEN: - mark = DIALOG_MARK_DAKUTEN; - break; - case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN: - mark = DIALOG_MARK_HANDAKUTEN; - break; - case DIALOG_CHAR_NEWLINE: + while ((c = str[strPos]) != '\0') { + // Handle text alignment if needed + if (alignmentXOffset != 0) { + create_dl_translation_matrix(MENU_MTX_NOPUSH, alignmentXOffset, 0.0f, 0.0f); + alignmentXOffset = 0; + } + switch (c) { + // Newline + case '\n': gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - create_dl_translation_matrix(MENU_MTX_PUSH, x, y - (lineNum * MAX_STRING_WIDTH), 0.0f); + if (lineNum == maxLines) { + return strPos + 1; + } + create_dl_translation_matrix(MENU_MTX_PUSH, x, y - (lineNum * sGenericFontLineHeight), 0.0f); lineNum++; + // Can skip any queued spaces + queuedSpaces = 0; + // Calculate alignment of new line + alignmentXOffset = get_alignment_x_offset(&str[strPos + 1], sGenericFontLineAlignment, main_font_lut, &main_font_utf8_lut); break; - case DIALOG_CHAR_PERIOD: - create_dl_translation_matrix(MENU_MTX_PUSH, -2.0f, -5.0f, 0.0f); - render_generic_char(DIALOG_CHAR_PERIOD_OR_HANDAKUTEN); - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - break; -#endif -#if defined(VERSION_US) || defined(VERSION_EU) - case DIALOG_CHAR_SLASH: -#ifdef VERSION_EU - xCoord += gDialogCharWidths[DIALOG_CHAR_SPACE] * 2; -#else - create_dl_translation_matrix( - MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * 2), 0.0f, 0.0f); -#endif - break; - case DIALOG_CHAR_MULTI_THE: -#ifdef VERSION_EU - render_multi_text_string(&xCoord, &yCoord, STRING_THE); -#else - render_multi_text_string(STRING_THE); -#endif + // Space + case ' ': + queuedSpaces++; break; - case DIALOG_CHAR_MULTI_YOU: -#ifdef VERSION_EU - render_multi_text_string(&xCoord, &yCoord, STRING_YOU); -#else - render_multi_text_string(STRING_YOU); -#endif + + // Tab + case '\t': + queuedSpaces += 4; break; -#endif -#ifndef VERSION_EU - case DIALOG_CHAR_SPACE: - create_dl_translation_matrix(MENU_MTX_NOPUSH, CHAR_WIDTH_SPACE, 0.0f, 0.0f); + // Backslash / escape character: Force the following character to print normally. + // Note that you will have to type '\\' to use this so that the compiler doesn't + // interpret it as a real escape character. To render one backslash, use '\\\\'. + case '\\': + strPos++; + goto render_character; + + // %d or %s: Display value of dialog variable, + case '%': + // Resolve queued spaces + if (queuedSpaces != 0) { + create_dl_translation_matrix(MENU_MTX_NOPUSH, queuedSpaces * SPACE_KERNING(segmented_to_virtual(main_font_lut)), 0.0f, 0.0f); + queuedSpaces = 0; + } + + // %d: Display dialog var as a decimal integer. + if (str[strPos + 1] == 'd') { + char dialogVarText[32]; + strPos++; + format_int_to_string(dialogVarText, gDialogVariable.asInt); + render_main_font_text(0, 0, dialogVarText, -1); + kerning = get_string_width(dialogVarText, main_font_lut, &main_font_utf8_lut); + create_dl_translation_matrix(MENU_MTX_NOPUSH, kerning, 0.0f, 0.0f); + break; + // %s: Display dialog var as a pointer to a string. + } else if (str[strPos + 1] == 's') { + strPos++; + render_main_font_text(0, 0, gDialogVariable.asStr, -1); + kerning = get_string_width(gDialogVariable.asStr, main_font_lut, &main_font_utf8_lut); + create_dl_translation_matrix(MENU_MTX_NOPUSH, kerning, 0.0f, 0.0f); + break; + // %%: Special case, print only a single %. + } else if (str[strPos + 1] == '%') { + strPos++; + } + + // If the character following the % is not 'd' or 's', print the % as a normal character. + goto render_character; + + // @XXXXXX: Set color of text to an RGB value. + // E.g. @FF0000 will set the color to red. + // Will use gDialogTextAlpha as the alpha value. + + // Note: multiple color codes may be needed in dialog as + // earlier color codes will not function if they scroll offscreen. + case CHAR_COLOR_CODE: // '@' + for (u32 i = 0; i < 3; i++) { + s32 firstDigit = hex_char_to_value(str[strPos + i * 2 + 1]); + s32 secondDigit = hex_char_to_value(str[strPos + i * 2 + 2]); + // If the sequence following the @ is not a valid RGBA32 color, interpret it as normal text. + if (firstDigit == -1 || secondDigit == -1) { + goto render_character; + } + color[i] = (firstDigit << 4) | secondDigit; + } + strPos += 6; + gDPSetEnvColor(gDisplayListHead++, color[0], color[1], color[2], gDialogTextAlpha); break; -#ifdef VERSION_JP - break; // ? needed to match -#endif -#endif + // Normal character rendering default: -#ifdef VERSION_EU - render_generic_char_at_pos(xCoord, yCoord, str[strPos]); - xCoord += gDialogCharWidths[str[strPos]]; -#else - render_generic_char(str[strPos]); - if (mark != DIALOG_MARK_NONE) { - create_dl_translation_matrix(MENU_MTX_PUSH, 5.0f, 5.0f, 0.0f); - render_generic_char(DIALOG_CHAR_MARK_START + mark); - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - mark = DIALOG_MARK_NONE; +render_character: + // Resolve queued spaces + if (queuedSpaces != 0) { + create_dl_translation_matrix(MENU_MTX_NOPUSH, queuedSpaces * SPACE_KERNING(segmented_to_virtual(main_font_lut)), 0.0f, 0.0f); + queuedSpaces = 0; } - create_dl_translation_matrix(MENU_MTX_NOPUSH, CHAR_WIDTH_DEFAULT, 0.0f, 0.0f); -#endif -#ifndef VERSION_JP - break; // what an odd difference. US (and probably later) versions added a useless break here. -#endif + if (!(c & 0x80)) { + kerning = render_generic_ascii_char(c); + } else { + kerning = render_generic_unicode_char(str, &strPos); + } + + create_dl_translation_matrix(MENU_MTX_NOPUSH, kerning, 0.0f, 0.0f); + break; } strPos++; } -#ifndef VERSION_EU gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); -#endif + gLastDialogLineNum = lineNum; // Used for rendering the choice triangle during dialog boxes + return -1; } -#ifdef VERSION_EU -void print_hud_char_umlaut(s16 x, s16 y, u8 chr) { - void **fontLUT = segmented_to_virtual(main_hud_lut); - - gDPPipeSync(gDisplayListHead++); - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, fontLUT[chr]); - gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block); - gSPTextureRectangle(gDisplayListHead++, x << 2, y << 2, (x + 16) << 2, (y + 16) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); - - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, fontLUT[GLYPH_UMLAUT]); - gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block); - gSPTextureRectangle(gDisplayListHead++, x << 2, (y - 4) << 2, (x + 16) << 2, (y + 12) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); +/** + * Prints a generic white string. + */ +void print_generic_string(s16 x, s16 y, char *str) { + print_generic_string_aligned(x, y, str, TEXT_ALIGN_LEFT); } -#endif /** - * Prints a hud string depending of the hud table list defined. + * Prints a hud string in the colorful font. */ -void print_hud_lut_string(s8 hudLUT, s16 x, s16 y, const u8 *str) { +void print_hud_lut_string(s16 x, s16 y, char *str) { s32 strPos = 0; - void **hudLUT1 = segmented_to_virtual(menu_hud_lut); // Japanese Menu HUD Color font - void **hudLUT2 = segmented_to_virtual(main_hud_lut); // 0-9 A-Z HUD Color Font + char c; + struct AsciiCharLUTEntry *hudLUT = segmented_to_virtual(main_hud_lut); // 0-9 A-Z HUD Color Font u32 curX = x; u32 curY = y; + u32 renderX, renderY; + struct Utf8CharLUTEntry *utf8Entry; + const Texture *texture; + u32 kerning; - u32 xStride; // X separation - - if (hudLUT == HUD_LUT_JPMENU) { - xStride = 16; - } else { // HUD_LUT_GLOBAL - xStride = HUD_LUT_STRIDE_GLOBAL; - } + while ((c = str[strPos]) != '\0') { + gDPPipeSync(gDisplayListHead++); - while (str[strPos] != GLOBAL_CHAR_TERMINATOR) { -#ifndef VERSION_JP - switch (str[strPos]) { -#ifdef VERSION_EU - case GLOBAL_CHAR_SPACE: - curX += xStride / 2; - break; - case HUD_CHAR_A_UMLAUT: - print_hud_char_umlaut(curX, curY, ASCII_TO_DIALOG('A')); - curX += xStride; - break; - case HUD_CHAR_O_UMLAUT: - print_hud_char_umlaut(curX, curY, ASCII_TO_DIALOG('O')); - curX += xStride; - break; - case HUD_CHAR_U_UMLAUT: - print_hud_char_umlaut(curX, curY, ASCII_TO_DIALOG('U')); - curX += xStride; - break; -#else - case GLOBAL_CHAR_SPACE: - curX += 8; - break; -#endif - default: -#endif + if (!(c & 0x80)) { + texture = hudLUT[ASCII_LUT_INDEX(c)].texture; + kerning = hudLUT[ASCII_LUT_INDEX(c)].kerning; + } else { + utf8Entry = utf8_lookup(&main_hud_utf8_lut, str, &strPos); + if ((utf8Entry->flags & TEXT_DIACRITIC_MASK) == TEXT_DIACRITIC_UMLAUT_UPPERCASE) { + renderX = curX; + renderY = curY - 4; + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, &texture_hud_char_umlaut); + gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block); + gSPTextureRectangle(gDisplayListHead++, renderX << 2, renderY << 2, (renderX + 16) << 2, + (renderY + 16) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); gDPPipeSync(gDisplayListHead++); + } + texture = utf8Entry->texture; + kerning = utf8Entry->kerning; + } - if (hudLUT == HUD_LUT_JPMENU) { - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, hudLUT1[str[strPos]]); - } - - if (hudLUT == HUD_LUT_GLOBAL) { - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, hudLUT2[str[strPos]]); - } - - gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block); - gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 16) << 2, - (curY + 16) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + if (texture != NULL) { + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, texture); + + renderX = curX; + renderY = curY; + if (c == '\'') { + renderX -= 2; + renderY -= 7; + } else if (c == '"') { + renderX += 1; + renderY -= 7; + } else if (c == ',') { + renderX -= 4; + renderY += 7; + } else if (c == '.') { + renderX -= 2; + renderY += 1; + } - curX += xStride; -#ifndef VERSION_JP + gSPDisplayList(gDisplayListHead++, dl_rgba16_load_tex_block); + gSPTextureRectangle(gDisplayListHead++, renderX << 2, renderY << 2, (renderX + 16) << 2, + (renderY + 16) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); } -#endif + + curX += kerning; strPos++; } } -#ifdef VERSION_EU -void print_menu_char_umlaut(s16 x, s16 y, u8 chr) { - void **fontLUT = segmented_to_virtual(menu_font_lut); +/** + * Renders a single ASCII character in the menu font. + */ +static u32 render_menu_ascii_char(char c, u32 curX, u32 curY) { + struct AsciiCharLUTEntry *fontLUT = segmented_to_virtual(menu_font_lut); + const Texture *texture = fontLUT[ASCII_LUT_INDEX(c)].texture; - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[chr]); - gDPLoadSync(gDisplayListHead++); - gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES)); - gSPTextureRectangle(gDisplayListHead++, x << 2, y << 2, (x + 8) << 2, (y + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + if (texture != NULL) { + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, texture); + gDPLoadSync(gDisplayListHead++); + gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES)); + gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 8) << 2, + (curY + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + } + + return fontLUT[ASCII_LUT_INDEX(c)].kerning; +} + +/** + * Renders a single UTF-8 character in the menu font. + */ +static u32 render_menu_unicode_char(char *str, s32 *strPos, u32 curX, u32 curY) { + struct Utf8CharLUTEntry *utf8Entry = utf8_lookup(&menu_font_utf8_lut, str, strPos); + + if (utf8Entry->texture == NULL) { + return utf8Entry->kerning; + } + + if (utf8Entry->flags & TEXT_DIACRITIC_MASK) { + struct DiacriticLUTEntry *diacriticLUT = segmented_to_virtual(&menu_font_diacritic_lut); + struct DiacriticLUTEntry *diacritic = &diacriticLUT[utf8Entry->flags & TEXT_DIACRITIC_MASK]; + + s32 fakeStrPos = 0; + render_menu_unicode_char(segmented_to_virtual(diacritic->str), &fakeStrPos, curX + diacritic->xOffset, curY - diacritic->yOffset); + } - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[DIALOG_CHAR_UMLAUT]); + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, utf8Entry->texture); gDPLoadSync(gDisplayListHead++); gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES)); - gSPTextureRectangle(gDisplayListHead++, x << 2, (y - 4) << 2, (x + 8) << 2, (y + 4) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 8) << 2, + (curY + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + return utf8Entry->kerning; } -#endif -void print_menu_generic_string(s16 x, s16 y, const u8 *str) { - UNUSED s8 mark = DIALOG_MARK_NONE; // unused in EU +/** + * Prints a menu white string in the smaller font. + * Only available in the file select and star select menus. + */ +void print_menu_generic_string(s16 x, s16 y, char *str) { s32 strPos = 0; + char c; u32 curX = x; u32 curY = y; - void **fontLUT = segmented_to_virtual(menu_font_lut); - - while (str[strPos] != DIALOG_CHAR_TERMINATOR) { - switch (str[strPos]) { -#ifdef VERSION_EU - case DIALOG_CHAR_UPPER_A_UMLAUT: - print_menu_char_umlaut(curX, curY, ASCII_TO_DIALOG('A')); - curX += gDialogCharWidths[str[strPos]]; - break; - case DIALOG_CHAR_UPPER_U_UMLAUT: - print_menu_char_umlaut(curX, curY, ASCII_TO_DIALOG('U')); - curX += gDialogCharWidths[str[strPos]]; - break; - case DIALOG_CHAR_UPPER_O_UMLAUT: - print_menu_char_umlaut(curX, curY, ASCII_TO_DIALOG('O')); - curX += gDialogCharWidths[str[strPos]]; - break; -#else - case DIALOG_CHAR_DAKUTEN: - mark = DIALOG_MARK_DAKUTEN; - break; - case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN: - mark = DIALOG_MARK_HANDAKUTEN; - break; -#endif - case DIALOG_CHAR_SPACE: - curX += 4; - break; - default: - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[str[strPos]]); - gDPLoadSync(gDisplayListHead++); - gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES)); - gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 8) << 2, - (curY + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); - -#ifndef VERSION_EU - if (mark != DIALOG_MARK_NONE) { - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, fontLUT[DIALOG_CHAR_MARK_START + mark]); - gDPLoadSync(gDisplayListHead++); - gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_8b_BYTES)); - gSPTextureRectangle(gDisplayListHead++, (curX + 6) << 2, (curY - 7) << 2, - (curX + 6 + 8) << 2, (curY - 7 + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); - - mark = DIALOG_MARK_NONE; - } -#endif -#if defined(VERSION_JP) || defined(VERSION_SH) - curX += JP_DIALOG_CHAR_WIDTH - 1; -#else - curX += gDialogCharWidths[str[strPos]]; -#endif + u32 kerning; + + while ((c = str[strPos]) != '\0') { + if (c & 0x80) { + kerning = render_menu_unicode_char(str, &strPos, curX, curY); + } else { + kerning = render_menu_ascii_char(c, curX, curY); } + + curX += kerning; strPos++; } } #if !CREDITS_TEXT_STRING_FONT -void print_credits_string(s16 x, s16 y, const u8 *str) { +/** + * Prints a string in the green credits font. + */ +void print_credits_string(s16 x, s16 y, char *str) { s32 strPos = 0; - void **fontLUT = segmented_to_virtual(main_credits_font_lut); + char c; + struct AsciiCharLUTEntry *fontLUT = segmented_to_virtual(main_credits_font_lut); u32 curX = x; u32 curY = y; @@ -762,138 +793,86 @@ void print_credits_string(s16 x, s16 y, const u8 *str) { G_TX_CLAMP, 3, G_TX_NOLOD, G_TX_CLAMP, 3, G_TX_NOLOD); gDPSetTileSize(gDisplayListHead++, G_TX_RENDERTILE, 0, 0, (8 - 1) << G_TEXTURE_IMAGE_FRAC, (8 - 1) << G_TEXTURE_IMAGE_FRAC); - while (str[strPos] != GLOBAL_CHAR_TERMINATOR) { - switch (str[strPos]) { - case GLOBAL_CHAR_SPACE: - curX += 4; - break; - default: - gDPPipeSync(gDisplayListHead++); - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, fontLUT[str[strPos]]); - gDPLoadSync(gDisplayListHead++); - gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_16b_BYTES)); - gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 8) << 2, - (curY + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); - curX += 7; - break; + while ((c = str[strPos]) != '\0') { + if (fontLUT[ASCII_LUT_INDEX(c)].texture != NULL) { + gDPPipeSync(gDisplayListHead++); + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, fontLUT[ASCII_LUT_INDEX(c)].texture); + gDPLoadSync(gDisplayListHead++); + gDPLoadBlock(gDisplayListHead++, G_TX_LOADTILE, 0, 0, 8 * 8 - 1, CALC_DXT(8, G_IM_SIZ_16b_BYTES)); + gSPTextureRectangle(gDisplayListHead++, curX << 2, curY << 2, (curX + 8) << 2, + (curY + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); } + + curX += fontLUT[ASCII_LUT_INDEX(c)].kerning; strPos++; } } + +void print_credits_string_aligned(s16 x, s16 y, char *str, u32 alignment) { + x += get_alignment_x_offset(str, alignment, main_credits_font_lut, NULL); + print_credits_string(x, y, str); +} #endif +/** + * Variants of the above that allow for text alignment. + */ +void print_generic_string_aligned(s16 x, s16 y, char *str, u32 alignment) { + sGenericFontLineHeight = DIALOG_LINE_HEIGHT_EN; + sGenericFontLineAlignment = alignment; + render_main_font_text(x, y, str, -1); +} + +void print_hud_lut_string_aligned(s16 x, s16 y, char *str, u32 alignment) { + x += get_alignment_x_offset(str, alignment, main_hud_lut, &main_hud_utf8_lut); + print_hud_lut_string(x, y, str); +} + +void print_menu_generic_string_aligned(s16 x, s16 y, char *str, u32 alignment) { + x += get_alignment_x_offset(str, alignment, menu_font_lut, &menu_font_utf8_lut); + print_menu_generic_string(x, y, str); +} + void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8 maxIndex) { u8 index = 0; if (scrollDirection == MENU_SCROLL_VERTICAL) { - if (gPlayer3Controller->rawStickY > 60) { - index |= 0b01; // Up - } - if (gPlayer3Controller->rawStickY < -60) { - index |= 0b10; // Down - } + if ((gPlayer3Controller->rawStickY > 60) || (gPlayer3Controller->buttonDown & (U_CBUTTONS | U_JPAD))) index++; + if ((gPlayer3Controller->rawStickY < -60) || (gPlayer3Controller->buttonDown & (D_CBUTTONS | D_JPAD))) index += 2; } else if (scrollDirection == MENU_SCROLL_HORIZONTAL) { - if (gPlayer3Controller->rawStickX > 60) { - index |= 0b10; // Right - } - - if (gPlayer3Controller->rawStickX < -60) { - index |= 0b01; // Left - } + if ((gPlayer3Controller->rawStickX > 60) || (gPlayer3Controller->buttonDown & (R_CBUTTONS | R_JPAD))) index += 2; + if ((gPlayer3Controller->rawStickX < -60) || (gPlayer3Controller->buttonDown & (L_CBUTTONS | L_JPAD))) index++; } - // Only increase/decrese if not holding that direction on the previous frame: - - if (((index ^ gMenuHoldKeyIndex) & index) == 0b10) { + if (((index ^ gMenuHoldKeyIndex) & index) == 2) { if (*currentIndex != maxIndex) { play_sound(SOUND_MENU_CHANGE_SELECT, gGlobalSoundSource); (*currentIndex)++; } } - if (((index ^ gMenuHoldKeyIndex) & index) == 0b01) { + if (((index ^ gMenuHoldKeyIndex) & index) == 1) { if (*currentIndex != minIndex) { play_sound(SOUND_MENU_CHANGE_SELECT, gGlobalSoundSource); (*currentIndex)--; } } - // If there has been input for 10 frames, set the timer to 8 and set gMenuHoldKeyIndex to 0 so the above becomes true. if (gMenuHoldKeyTimer == 10) { gMenuHoldKeyTimer = 8; - gMenuHoldKeyIndex = 0b00; + gMenuHoldKeyIndex = 0; } else { - // Otherwise, increment the timer while there is input. gMenuHoldKeyTimer++; gMenuHoldKeyIndex = index; } - if (index == 0) { + if ((index & 3) == 0) { gMenuHoldKeyTimer = 0; } } -// EU has both get_str_x_pos_from_center and get_str_x_pos_from_center_scale -// JP, US and Shindou only implement one or the other -#if defined(VERSION_US) || defined(VERSION_EU) -s16 get_str_x_pos_from_center(s16 centerPos, u8 *str, UNUSED f32 scale) { - s16 strPos = 0; - f32 spacesWidth = 0.0f; - - while (str[strPos] != DIALOG_CHAR_TERMINATOR) { - spacesWidth += gDialogCharWidths[str[strPos]]; - strPos++; - } - // return the x position of where the string starts as half the string's - // length from the position of the provided center. - return (s16)(centerPos - (s16)(spacesWidth / 2.0)); -} -#endif - -#if defined(VERSION_JP) || defined(VERSION_EU) || defined(VERSION_SH) -s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale) { - s16 strPos = 0; - f32 charsWidth = 0.0f; - f32 spacesWidth = 0.0f; - - while (str[strPos] != DIALOG_CHAR_TERMINATOR) { - //! EU checks for dakuten and handakuten despite dialog code unable to handle it - if (str[strPos] == DIALOG_CHAR_SPACE) { - spacesWidth += 1.0; - } else if (str[strPos] != DIALOG_CHAR_DAKUTEN - && str[strPos] != DIALOG_CHAR_PERIOD_OR_HANDAKUTEN) { - charsWidth += 1.0; - } - strPos++; - } - // return the x position of where the string starts as half the string's - // length from the position of the provided center. - return (f32) centerPos - (scale * (charsWidth / 2.0)) - ((scale / 2.0) * (spacesWidth / 2.0)); -} -#endif - -// ex-alo change -// Set a fixed value for JP regions -s16 get_string_width(u8 *str) { - s16 strPos = 0; - s16 width = 0; - - while (str[strPos] != DIALOG_CHAR_TERMINATOR) { - #if defined(VERSION_US) || defined(VERSION_EU) - width += gDialogCharWidths[str[strPos]]; - #else - width += JP_DIALOG_CHAR_WIDTH; - #endif - strPos++; - } - return width; -} - -u8 gHudSymCoin[] = { GLYPH_COIN, GLYPH_SPACE }; -u8 gHudSymX[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; - void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileIndex, s8 courseIndex, s16 x, s16 y) { - u8 strNumCoins[4]; + char strNumCoins[10]; s16 numCoins; if (!useCourseCoinScore) { @@ -903,62 +882,28 @@ void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileIndex, s8 courseInd } if (numCoins != 0) { - print_hud_lut_string(HUD_LUT_GLOBAL, x, y, gHudSymCoin); - print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, gHudSymX); - int_to_str(numCoins, strNumCoins); - print_hud_lut_string(HUD_LUT_GLOBAL, x + 32, y, strNumCoins); + sprintf(strNumCoins, "✪×%d", numCoins); + print_hud_lut_string(x, y, strNumCoins); } } void print_hud_my_score_stars(s8 fileIndex, s8 courseIndex, s16 x, s16 y) { - u8 strStarCount[4]; - s16 starCount; - u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE }; - UNUSED u16 unused; - u8 textSymX[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; - - starCount = save_file_get_course_star_count(fileIndex, courseIndex); + char strStarCount[10]; + s16 starCount = save_file_get_course_star_count(fileIndex, courseIndex); if (starCount != 0) { - print_hud_lut_string(HUD_LUT_GLOBAL, x, y, textSymStar); - print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, textSymX); - int_to_str(starCount, strStarCount); - print_hud_lut_string(HUD_LUT_GLOBAL, x + 32, y, strStarCount); + sprintf(strStarCount, "★×%d", starCount); + print_hud_lut_string(x, y, strStarCount); } } -void int_to_str(s32 num, u8 *dst) { - s32 digit1; - s32 digit2; - s32 digit3; - - s8 pos = 0; - - if (num > 999) { - dst[0] = 0x00; dst[1] = DIALOG_CHAR_TERMINATOR; - return; - } - - digit1 = num / 100; - digit2 = (num - digit1 * 100) / 10; - digit3 = (num - digit1 * 100) - (digit2 * 10); - - if (digit1 != 0) { - dst[pos++] = digit1; - } - - if (digit2 != 0 || digit1 != 0) { - dst[pos++] = digit2; - } - - dst[pos++] = digit3; - dst[pos] = DIALOG_CHAR_TERMINATOR; -} - -s16 get_dialog_id(void) { +s32 get_dialog_id(void) { return gDialogID; } +/** + * Initialise a dialog box. + */ void create_dialog_box(s16 dialog) { if (gDialogID == DIALOG_NONE) { gDialogID = dialog; @@ -966,7 +911,26 @@ void create_dialog_box(s16 dialog) { } } -void create_dialog_box_with_var(s16 dialog, s32 dialogVar) { +/** + * Initialise a dialog box with an integer variable to be displayed with %d. + */ +void create_dialog_box_with_int_var(s16 dialog, s32 dialogVar) { + DialogVariable var = { .asInt = dialogVar }; + create_dialog_box_with_var(dialog, var); +} + +/** + * Initialise a dialog box with a string variable to be displayed with %s. + */ +void create_dialog_box_with_str_var(s16 dialog, char *dialogVar) { + DialogVariable var = { .asStr = dialogVar }; + create_dialog_box_with_var(dialog, var); +} + +/** + * Initialise a dialog box with a general variable. + */ +void create_dialog_box_with_var(s16 dialog, DialogVariable dialogVar) { if (gDialogID == DIALOG_NONE) { gDialogID = dialog; gDialogVariable = dialogVar; @@ -974,6 +938,9 @@ void create_dialog_box_with_var(s16 dialog, s32 dialogVar) { } } +/** + * Initialise a dialog box with black text on a white background instead of white text on black. + */ void create_dialog_inverted_box(s16 dialog) { if (gDialogID == DIALOG_NONE) { gDialogID = dialog; @@ -981,638 +948,131 @@ void create_dialog_inverted_box(s16 dialog) { } } +/** + * Initialise a dialog box that asks for a response. + */ void create_dialog_box_with_response(s16 dialog) { if (gDialogID == DIALOG_NONE) { gDialogID = dialog; gDialogBoxType = DIALOG_TYPE_ROTATE; - gDialogWithChoice = TRUE; + gDialogHasResponse = TRUE; } } void reset_dialog_render_state(void) { level_set_transition(0, NULL); - if (gDialogBoxType == DIALOG_TYPE_ZOOM) { - trigger_cutscene_dialog(2); - } - - gDialogBoxScale = DIALOG_BOX_SCALE_DEFAULT; - gDialogBoxAngle = DIALOG_BOX_ANGLE_DEFAULT; - gMenuState = MENU_STATE_DEFAULT; + gDialogBoxScale = 19.0f; + gDialogBoxOpenTimer = 90.0f; + gDialogBoxState = DIALOG_STATE_OPENING; gDialogID = DIALOG_NONE; - gDialogPageStartStrIndex = 0; - gDialogWithChoice = FALSE; - gNextDialogPageStartStrIndex = 0; + gDialogTextPos = 0; + gDialogHasResponse = FALSE; + gLastDialogPageStrPos = 0; gDialogResponse = DIALOG_RESPONSE_NONE; } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define X_VAL1 -5.0f - #define Y_VAL1 2.0 - #define Y_VAL2 4 -#else - #define X_VAL1 -7.0f - #define Y_VAL1 5.0 - #define Y_VAL2 5.0f -#endif - void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) { - UNUSED u8 filler[4]; - create_dl_translation_matrix(MENU_MTX_NOPUSH, dialog->leftOffset, dialog->width, 0); switch (gDialogBoxType) { case DIALOG_TYPE_ROTATE: // Renders a dialog black box with zoom and rotation - if (gMenuState == MENU_STATE_DIALOG_OPENING || gMenuState == MENU_STATE_DIALOG_CLOSING) { -#ifdef HIGH_FPS_PC - sInterpolatedDialogRotationPos = gDisplayListHead; - if (gMenuState == MENU_STATE_DIALOG_OPENING) { - sInterpolatedDialogScale = gDialogBoxScale - 2 / 2; - sInterpolatedDialogRotation = gDialogBoxAngle - 7.5f / 2; - } else { - sInterpolatedDialogScale = gDialogBoxScale + 2 / 2; - sInterpolatedDialogRotation = gDialogBoxAngle + 7.5f / 2; - } -#endif - create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f); + if ((gDialogBoxState == DIALOG_STATE_OPENING) + || (gDialogBoxState == DIALOG_STATE_CLOSING)) { + create_dl_scale_matrix(MENU_MTX_NOPUSH, (1.0f / gDialogBoxScale), (1.0f / gDialogBoxScale), 1.0f); // convert the speed into angle - create_dl_rotation_matrix(MENU_MTX_NOPUSH, gDialogBoxAngle * 4.0f, 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, (gDialogBoxOpenTimer * 4.0f), 0, 0, 1.0f); } gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 150); break; case DIALOG_TYPE_ZOOM: // Renders a dialog white box with zoom - if (gMenuState == MENU_STATE_DIALOG_OPENING || gMenuState == MENU_STATE_DIALOG_CLOSING) { -#ifdef HIGH_FPS_PC - sInterpolatedDialogZoomPos = gDisplayListHead; - if (gMenuState == MENU_STATE_DIALOG_OPENING) { - sInterpolatedDialogScale = gDialogBoxScale - 2 / 2; - } else { - sInterpolatedDialogScale = gDialogBoxScale + 2 / 2; - } -#endif - create_dl_translation_matrix(MENU_MTX_NOPUSH, 65.0 - (65.0 / gDialogBoxScale), - (40.0 / gDialogBoxScale) - 40, 0); - create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.0 / gDialogBoxScale, 1.0 / gDialogBoxScale, 1.0f); + if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) { + create_dl_translation_matrix(MENU_MTX_NOPUSH, (65.0f - (65.0f / gDialogBoxScale)), ((40.0f / gDialogBoxScale) - 40), 0); + create_dl_scale_matrix(MENU_MTX_NOPUSH, (1.0f / gDialogBoxScale), (1.0f / gDialogBoxScale), 1.0f); } gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 150); break; } - create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL1, Y_VAL1, 0); - create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.1f, ((f32) linesPerBox / Y_VAL2) + 0.1, 1.0f); + create_dl_translation_matrix(MENU_MTX_PUSH, BOX_TRANS_X, BOX_TRANS_Y, 0); + create_dl_scale_matrix(MENU_MTX_NOPUSH, 1.1f, (((f32) linesPerBox / BOX_SCALE) + 0.1f), 1.0f); gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } -void change_and_flash_dialog_text_color_lines(s8 colorMode, s8 lineNum) { - u8 color; - - if (colorMode == 1) { // unused - if (lineNum == 1) { - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - } else { - if (lineNum == gMenuLineNum) { - color = sins(gMenuTextColorTransTimer) * 50.0f + 200.0f; - gDPSetEnvColor(gDisplayListHead++, color, color, color, 255); - } else { - gDPSetEnvColor(gDisplayListHead++, 200, 200, 200, 255); - } - } - } else { - switch (gDialogBoxType) { - case DIALOG_TYPE_ROTATE: - break; - case DIALOG_TYPE_ZOOM: - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); - break; - } - } -} - -#ifdef VERSION_EU -void render_generic_dialog_char_at_pos(struct DialogEntry *dialog, s16 x, s16 y, u8 c) { - s16 width = (8.0 - (gDialogBoxScale * 0.8)); - s16 height = (16.0 - (gDialogBoxScale * 0.8)); - s16 tmpX = (dialog->leftOffset + (65.0 - (65.0 / gDialogBoxScale))); - s16 tmpY = ((240 - dialog->width) - ((40.0 / gDialogBoxScale) - 40)); - s16 xCoord = (tmpX + (x / gDialogBoxScale)); - s16 yCoord = (tmpY + (y / gDialogBoxScale)); - - void **fontLUT = segmented_to_virtual(main_font_lut); - void *packedTexture = segmented_to_virtual(fontLUT[c]); - void *unpackedTexture = convert_ia4_char(c, packedTexture, 8, 8); - - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture)); - gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); - gSPTextureRectangleFlip(gDisplayListHead++, xCoord << 2, (yCoord - height) << 2, - (xCoord + width) << 2, yCoord << 2, G_TX_RENDERTILE, 8 << 6, 4 << 6, 1 << 10, 1 << 10); -} -#endif - -#if defined(VERSION_JP) || defined(VERSION_SH) - #define X_VAL3 5.0f - #define Y_VAL3 20 -#else - #define X_VAL3 0.0f - #define Y_VAL3 16 -#endif - -#ifdef VERSION_EU -void handle_dialog_scroll_page_state(s8 lineNum, s8 totalLines, s8 *pageState, s8 *xMatrix) -#else -void handle_dialog_scroll_page_state(s8 lineNum, s8 totalLines, s8 *pageState, s8 *xMatrix, s16 *linePos) -#endif -{ -#ifndef VERSION_EU - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); -#endif - - if (lineNum == totalLines) { - *pageState = DIALOG_PAGE_STATE_SCROLL; - return; - } -#ifdef VERSION_EU - gDialogY += 16; -#else - create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL3, 2 - (lineNum * Y_VAL3), 0); - - *linePos = 0; -#endif - *xMatrix = 1; -} - -#if defined(VERSION_JP) || defined(VERSION_SH) -void adjust_pos_and_print_period_char(s8 *xMatrix, s16 *linePos) { - if (*linePos != 0) { - create_dl_translation_matrix(MENU_MTX_NOPUSH, 10 * *xMatrix, 0, 0); - } - - create_dl_translation_matrix(MENU_MTX_PUSH, -2.0f, -5.0f, 0); - render_generic_char(DIALOG_CHAR_PERIOD_OR_HANDAKUTEN); - - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - - (*linePos)++; - *xMatrix = 1; -} -#endif - -#ifdef VERSION_EU -void render_star_count_dialog_text(struct DialogEntry *dialog, s8 *linePos) -#else -void render_star_count_dialog_text(s8 *xMatrix, s16 *linePos) -#endif -{ - s8 tensDigit = gDialogVariable / 10; - s8 onesDigit = gDialogVariable - (tensDigit * 10); // remainder - - if (tensDigit != 0) { -#if defined(VERSION_JP) || defined(VERSION_SH) - create_dl_translation_matrix(MENU_MTX_NOPUSH, 10 * *xMatrix, 0, 0); - render_generic_char(tensDigit); -#elif defined(VERSION_US) - if (*xMatrix != 1) { - create_dl_translation_matrix( - MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * *xMatrix), 0, 0); - } - - render_generic_char(tensDigit); - create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32) gDialogCharWidths[tensDigit], 0, 0); - *xMatrix = 1; - (*linePos)++; -#elif defined(VERSION_EU) - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, tensDigit); - gDialogX += gDialogCharWidths[tensDigit]; - *linePos = 1; -#endif - } -#ifndef VERSION_EU - else { -#if defined(VERSION_JP) || defined(VERSION_SH) - (*xMatrix)++; -#endif - } -#endif - -#ifndef VERSION_EU -#if defined(VERSION_JP) || defined(VERSION_SH) - create_dl_translation_matrix(MENU_MTX_NOPUSH, 10 * *xMatrix, 0, 0); - render_generic_char(onesDigit); -#elif defined(VERSION_US) - if (*xMatrix != 1) { - create_dl_translation_matrix( - MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * (*xMatrix - 1)), 0, 0); - } - - render_generic_char(onesDigit); - create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32) gDialogCharWidths[onesDigit], 0, 0); -#endif - (*linePos)++; - *xMatrix = 1; -#else // VERSION_EU - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, onesDigit); - gDialogX += gDialogCharWidths[onesDigit]; - *linePos = 1; -#endif -} - -#if defined(VERSION_US) || defined(VERSION_EU) -#ifdef VERSION_EU -void render_multi_text_string_lines(s8 multiTextId, s8 lineNum, s8 linesPerBox, UNUSED s8 xMatrix, s8 lowerBound, struct DialogEntry *dialog) -#else -void render_multi_text_string_lines(s8 multiTextId, s8 lineNum, s16 *linePos, s8 linesPerBox, s8 xMatrix, s8 lowerBound) -#endif -{ - s8 i; - struct MultiTextEntry textLengths[2] = { - { 3, { TEXT_THE_RAW } }, - { 3, { TEXT_YOU_RAW } }, - }; - - if (lineNum >= lowerBound && lineNum <= (lowerBound + linesPerBox)) { -#ifdef VERSION_US - if (*linePos != 0 || xMatrix != 1) { - create_dl_translation_matrix( - MENU_MTX_NOPUSH, (gDialogCharWidths[DIALOG_CHAR_SPACE] * (xMatrix - 1)), 0, 0); - } -#endif - for (i = 0; i < textLengths[multiTextId].length; i++) { -#ifdef VERSION_EU - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, textLengths[multiTextId].str[i]); - gDialogX += gDialogCharWidths[textLengths[multiTextId].str[i]]; -#else - render_generic_char(textLengths[multiTextId].str[i]); - create_dl_translation_matrix( - MENU_MTX_NOPUSH, (gDialogCharWidths[textLengths[multiTextId].str[i]]), 0, 0); -#endif - } - } - -#ifdef VERSION_US - linePos += textLengths[multiTextId].length; -#endif -} -#endif - -#ifdef VERSION_EU -void render_dialog_lowercase_diacritic(struct DialogEntry *dialog, u8 chr, u8 diacritic) { - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, chr); - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, diacritic + 0xE7); - gDialogX += gDialogCharWidths[chr]; -} - -void render_dialog_uppercase_diacritic(struct DialogEntry *dialog, u8 chr, u8 diacritic) { - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, chr); - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY - 4, diacritic + 0xE3); - gDialogX += gDialogCharWidths[chr]; -} -#endif - u32 ensure_nonnegative(s16 value) { - if (value < 0) { - value = 0; - } - - return value; + return ((value < 0) ? 0 : value); } -#ifdef VERSION_JP -void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog) -#else -void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 lowerBound) -#endif -{ - UNUSED u8 filler[8]; -#ifdef VERSION_EU - s16 startY = 14; -#endif - u8 strChar; - u8 *str = segmented_to_virtual(dialog->str); - s8 lineNum = 1; +static void handle_dialog_text_and_pages(struct DialogEntry *dialog) { + char *str = segmented_to_virtual(dialog->str); s8 totalLines; - s8 pageState = DIALOG_PAGE_STATE_NONE; - UNUSED s8 mark = DIALOG_MARK_NONE; // unused in US and EU - s8 xMatrix = 1; - s8 linesPerBox = dialog->linesPerBox; - s16 strIndex; -#ifndef VERSION_EU - s16 linePos = 0; -#endif + s32 printResult; + s16 yPos = 2 - DIALOG_LINE_HEIGHT; - if (gMenuState == MENU_STATE_DIALOG_SCROLLING) { + if (gDialogBoxState == DIALOG_STATE_HORIZONTAL) { // If scrolling, consider the number of lines for both // the current page and the page being scrolled to. - totalLines = linesPerBox * 2 + 1; + totalLines = dialog->linesPerBox * 2; + yPos += gDialogScrollOffsetY; } else { - totalLines = linesPerBox + 1; - } - - gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - - strIndex = gDialogPageStartStrIndex; - -#ifdef VERSION_EU - gDialogX = 0; - gDialogY = startY; -#endif - - if (gMenuState == MENU_STATE_DIALOG_SCROLLING) { -#ifdef VERSION_EU - gDialogY -= gDialogScrollOffsetY; -#else -#ifdef HIGH_FPS_PC - sInterpolatedDialogOffset = gDialogScrollOffsetY + dialog->linesPerBox; - sInterpolatedDialogOffsetPos = gDisplayListHead; -#endif - create_dl_translation_matrix(MENU_MTX_NOPUSH, 0, (f32) gDialogScrollOffsetY, 0); -#endif + totalLines = dialog->linesPerBox; } -#ifndef VERSION_EU - create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL3, 2 - lineNum * Y_VAL3, 0); -#endif - - while (pageState == DIALOG_PAGE_STATE_NONE) { - change_and_flash_dialog_text_color_lines(colorMode, lineNum); - strChar = str[strIndex]; - - switch (strChar) { - case DIALOG_CHAR_TERMINATOR: - pageState = DIALOG_PAGE_STATE_END; -#ifndef VERSION_EU - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); -#endif - break; - case DIALOG_CHAR_NEWLINE: - lineNum++; -#ifdef VERSION_EU - handle_dialog_scroll_page_state(lineNum, totalLines, &pageState, &xMatrix); - gDialogX = 0; -#else - handle_dialog_scroll_page_state(lineNum, totalLines, &pageState, &xMatrix, &linePos); -#ifdef VERSION_SH - mark = DIALOG_MARK_NONE; -#endif -#endif - break; - -#ifdef VERSION_EU - case DIALOG_CHAR_LOWER_A_GRAVE: - case DIALOG_CHAR_LOWER_A_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_A_UMLAUT: - render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('a'), strChar & 0xF); - break; - case DIALOG_CHAR_UPPER_A_GRAVE: - case DIALOG_CHAR_UPPER_A_CIRCUMFLEX: - case DIALOG_CHAR_UPPER_A_UMLAUT: - render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('A'), strChar & 0xF); - break; - case DIALOG_CHAR_LOWER_E_GRAVE: - case DIALOG_CHAR_LOWER_E_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_E_UMLAUT: - case DIALOG_CHAR_LOWER_E_ACUTE: - render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('e'), strChar & 0xF); - break; - case DIALOG_CHAR_UPPER_E_GRAVE: - case DIALOG_CHAR_UPPER_E_CIRCUMFLEX: - case DIALOG_CHAR_UPPER_E_UMLAUT: - case DIALOG_CHAR_UPPER_E_ACUTE: - render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('E'), strChar & 0xF); - break; - case DIALOG_CHAR_LOWER_U_GRAVE: - case DIALOG_CHAR_LOWER_U_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_U_UMLAUT: - render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('u'), strChar & 0xF); - break; - case DIALOG_CHAR_UPPER_U_GRAVE: - case DIALOG_CHAR_UPPER_U_CIRCUMFLEX: - case DIALOG_CHAR_UPPER_U_UMLAUT: - render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('U'), strChar & 0xF); - break; - case DIALOG_CHAR_LOWER_O_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_O_UMLAUT: - render_dialog_lowercase_diacritic(dialog, ASCII_TO_DIALOG('o'), strChar & 0xF); - break; - case DIALOG_CHAR_UPPER_O_CIRCUMFLEX: - case DIALOG_CHAR_UPPER_O_UMLAUT: - render_dialog_uppercase_diacritic(dialog, ASCII_TO_DIALOG('O'), strChar & 0xF); - break; - case DIALOG_CHAR_LOWER_I_CIRCUMFLEX: - case DIALOG_CHAR_LOWER_I_UMLAUT: - render_dialog_lowercase_diacritic(dialog, DIALOG_CHAR_I_NO_DIA, strChar & 0xF); - break; -#else - case DIALOG_CHAR_DAKUTEN: - mark = DIALOG_MARK_DAKUTEN; - break; - case DIALOG_CHAR_PERIOD_OR_HANDAKUTEN: - mark = DIALOG_MARK_HANDAKUTEN; - break; -#endif - - case DIALOG_CHAR_SPACE: -#ifdef VERSION_EU - gDialogX += gDialogCharWidths[DIALOG_CHAR_SPACE]; -#else -#if defined(VERSION_JP) || defined(VERSION_SH) - if (linePos != 0) { -#endif - xMatrix++; -#if defined(VERSION_JP) || defined(VERSION_SH) - } -#endif - linePos++; -#endif - break; - -#if defined(VERSION_JP) || defined(VERSION_SH) - case DIALOG_CHAR_PERIOD: - adjust_pos_and_print_period_char(&xMatrix, &linePos); - break; -#else - case DIALOG_CHAR_SLASH: -#ifdef VERSION_EU - gDialogX += gDialogCharWidths[DIALOG_CHAR_SPACE] * 2; -#else - xMatrix += 2; - linePos += 2; -#endif - break; - case DIALOG_CHAR_MULTI_THE: -#ifdef VERSION_EU - render_multi_text_string_lines(STRING_THE, lineNum, linesPerBox, xMatrix, lowerBound, dialog); -#else - render_multi_text_string_lines(STRING_THE, lineNum, &linePos, linesPerBox, xMatrix, lowerBound); -#endif - xMatrix = 1; - break; - case DIALOG_CHAR_MULTI_YOU: -#ifdef VERSION_EU - render_multi_text_string_lines(STRING_YOU, lineNum, linesPerBox, xMatrix, lowerBound, dialog); -#else - render_multi_text_string_lines(STRING_YOU, lineNum, &linePos, linesPerBox, xMatrix, lowerBound); -#endif - xMatrix = 1; - break; -#endif - - case DIALOG_CHAR_STAR_COUNT: -#ifdef VERSION_EU - render_star_count_dialog_text(dialog, &xMatrix); -#else - render_star_count_dialog_text(&xMatrix, &linePos); -#endif - break; - -#ifdef VERSION_EU - case DIALOG_CHAR_DOUBLE_LOW_QUOTE: - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY + 8, 0xF6); - gDialogX += gDialogCharWidths[0xF6]; - break; -#endif - - default: // any other character -#if defined(VERSION_JP) || defined(VERSION_SH) -#ifdef VERSION_SH - if (lineNum >= lowerBound && lineNum <= (lowerBound + linesPerBox)) { -#endif - if (linePos != 0) { - create_dl_translation_matrix(MENU_MTX_NOPUSH, 10 * xMatrix, 0, 0); - } - - render_generic_char(strChar); - xMatrix = 1; - linePos++; - - if (mark != DIALOG_MARK_NONE) { - create_dl_translation_matrix(MENU_MTX_PUSH, 5.0f, 7.0f, 0); - render_generic_char(DIALOG_CHAR_MARK_START + mark); - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - mark = DIALOG_MARK_NONE; - } -#ifdef VERSION_SH - } -#endif -#elif defined(VERSION_US) - if (lineNum >= lowerBound && lineNum <= (lowerBound + linesPerBox)) { - if (linePos != 0 || xMatrix != 1) { - create_dl_translation_matrix( - MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[DIALOG_CHAR_SPACE] * (xMatrix - 1)), 0, 0); - } - - render_generic_char(strChar); - create_dl_translation_matrix(MENU_MTX_NOPUSH, (f32)(gDialogCharWidths[strChar]), 0, 0); - xMatrix = 1; - linePos++; - } -#else // VERSION_EU - if (lineNum >= lowerBound && lineNum <= (lowerBound + linesPerBox)) { - render_generic_dialog_char_at_pos(dialog, gDialogX, gDialogY, strChar); - } - gDialogX += gDialogCharWidths[strChar]; -#endif - } - -#ifdef VERSION_JP - if (linePos == 12) { - if (str[strIndex + 1] == DIALOG_CHAR_PERIOD) { - adjust_pos_and_print_period_char(&xMatrix, &linePos); - strIndex++; - } - - if (str[strIndex + 1] == DIALOG_CHAR_COMMA) { - create_dl_translation_matrix(MENU_MTX_NOPUSH, 10 * xMatrix, 0, 0); - render_generic_char(DIALOG_CHAR_COMMA); - strIndex++; - } - - if (str[strIndex + 1] == DIALOG_CHAR_NEWLINE) { - strIndex++; - } - - if (str[strIndex + 1] == DIALOG_CHAR_TERMINATOR) { - pageState = DIALOG_PAGE_STATE_END; - gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - break; // exit loop - } else { - lineNum++; - handle_dialog_scroll_page_state(lineNum, totalLines, &pageState, &xMatrix, &linePos); - } - } -#endif - - strIndex++; + gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); + + gDialogTextAlpha = 255; + switch (gDialogBoxType) { + case DIALOG_TYPE_ROTATE: + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + break; + case DIALOG_TYPE_ZOOM: + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + break; } + sGenericFontLineHeight = DIALOG_LINE_HEIGHT; + sGenericFontLineAlignment = TEXT_ALIGN_LEFT; + printResult = render_main_font_text(0, yPos, str + gDialogTextPos, totalLines); + gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - if (gMenuState == MENU_STATE_DIALOG_OPEN) { - if (pageState == DIALOG_PAGE_STATE_END) { - gNextDialogPageStartStrIndex = -1; + if (gDialogBoxState == DIALOG_STATE_VERTICAL) { + if (printResult == -1) { // Reached end of dialog box + gLastDialogPageStrPos = -1; } else { - gNextDialogPageStartStrIndex = strIndex; + gLastDialogPageStrPos = gDialogTextPos + printResult; } } - - gLastDialogLineNum = lineNum; } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define X_VAL4_1 50 - #define X_VAL4_2 25 - #define Y_VAL4_1 1 - #define Y_VAL4_2 20 -#else - #define X_VAL4_1 56 - #define X_VAL4_2 47 - #define Y_VAL4_1 2 - #define Y_VAL4_2 16 -#endif - void render_dialog_triangle_choice(void) { - if (gMenuState == MENU_STATE_DIALOG_OPEN) { - handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &gMenuLineNum, 1, 2); + if (gDialogBoxState == DIALOG_STATE_VERTICAL) { + handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &gDialogLineNum, 1, 2); } - create_dl_translation_matrix(MENU_MTX_NOPUSH, (gMenuLineNum * X_VAL4_1) - X_VAL4_2, Y_VAL4_1 - (gLastDialogLineNum * Y_VAL4_2), 0); + create_dl_translation_matrix(MENU_MTX_NOPUSH, (gDialogLineNum * 56) - 47, 2 - (gLastDialogLineNum * DIALOG_LINE_HEIGHT), 0); - if (gDialogBoxType == DIALOG_TYPE_ROTATE) { // White Text + if (gDialogBoxType == DIALOG_TYPE_ROTATE) { gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - } else { // Black Text + } else { gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); } gSPDisplayList(gDisplayListHead++, dl_draw_triangle); } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define X_VAL5 123.0f - #define Y_VAL5_1 -20 - #define Y_VAL5_2 2 - #define X_Y_VAL6 0.8f -#elif defined(VERSION_US) - #define X_VAL5 118.0f - #define Y_VAL5_1 -16 - #define Y_VAL5_2 5 - #define X_Y_VAL6 0.8f -#elif defined(VERSION_EU) - #define X_VAL5 122.0f - #define Y_VAL5_1 -16 - #define Y_VAL5_2 3 - #define X_Y_VAL6 0.5f -#endif - void render_dialog_triangle_next(s8 linesPerBox) { s32 globalTimer = gGlobalTimer; - if (globalTimer & 8) { + if (globalTimer & 0x8) { return; } - create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL5, (linesPerBox * Y_VAL5_1) + Y_VAL5_2, 0); - create_dl_scale_matrix(MENU_MTX_NOPUSH, X_Y_VAL6, X_Y_VAL6, 1.0f); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, -90.0f, 0, 0, 1.0f); + create_dl_translation_matrix(MENU_MTX_PUSH, 118.f, (linesPerBox * -DIALOG_LINE_HEIGHT) + 5, 0); + create_dl_scale_matrix(MENU_MTX_NOPUSH, 0.8f, 0.8f, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, -DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); if (gDialogBoxType == DIALOG_TYPE_ROTATE) { // White Text gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); @@ -1624,47 +1084,42 @@ void render_dialog_triangle_next(s8 linesPerBox) { gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } +// King Bob-omb (Start), Whomp (Start), King Bob-omb (throw him out), Eyerock (Start), Wiggler (Start) +static s16 sDialogBossStart[] = { DIALOG_017, DIALOG_114, DIALOG_128, DIALOG_117, DIALOG_150 }; +// Koopa the Quick (BoB), Koopa the Quick (THI), Penguin Race, Fat Penguin Race (120 stars) +static s16 sDialogRaceSound[] = { DIALOG_005, DIALOG_009, DIALOG_055, DIALOG_164 }; +// Red Switch, Green Switch, Blue Switch, 100 coins star, Bowser Red Coin Star +static s16 sDialogStarSound[] = { DIALOG_010, DIALOG_011, DIALOG_012, DIALOG_013, DIALOG_014 }; +// King Bob-omb (Start), Whomp (Defeated), King Bob-omb (Defeated, missing in JP), Eyerock (Defeated), Wiggler (Defeated) +static s16 sDialogBossStop[] = { DIALOG_017, DIALOG_115, DIALOG_116, DIALOG_118, DIALOG_152 }; + void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order - // King Bob-omb (Start), Whomp (Start), King Bob-omb (throw him out), Eyerock (Start), Wiggler (Start) - s16 dialogBossStart[] = { DIALOG_017, DIALOG_114, DIALOG_128, DIALOG_117, DIALOG_150 }; - // Koopa the Quick (BoB), Koopa the Quick (THI), Penguin Race, Fat Penguin Race (120 stars) - s16 dialogRaceSound[] = { DIALOG_005, DIALOG_009, DIALOG_055, DIALOG_164 }; - // Red Switch, Green Switch, Blue Switch, 100 coins star, Bowser Red Coin Star - s16 dialogStarSound[] = { DIALOG_010, DIALOG_011, DIALOG_012, DIALOG_013, DIALOG_014 }; - // King Bob-omb (Start), Whomp (Defeated), King Bob-omb (Defeated, missing in JP), Eyerock (Defeated), Wiggler (Defeated) -#if BUGFIX_KING_BOB_OMB_FADE_MUSIC - s16 dialogBossStop[] = { DIALOG_017, DIALOG_115, DIALOG_116, DIALOG_118, DIALOG_152 }; -#else - //! @bug JP misses King Bob-omb defeated DIALOG_116, meaning that the boss music will still - //! play after King Bob-omb is defeated until BoB loads it's music after the star cutscene - s16 dialogBossStop[] = { DIALOG_017, DIALOG_115, DIALOG_118, DIALOG_152 }; -#endif s16 i; - for (i = 0; i < (s16) ARRAY_COUNT(dialogBossStart); i++) { - if (dialogBossStart[i] == dialogID) { + for (i = 0; i < (s16) ARRAY_COUNT(sDialogBossStart); i++) { + if (sDialogBossStart[i] == dialogID) { seq_player_unlower_volume(SEQ_PLAYER_LEVEL, 60); play_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, SEQ_EVENT_BOSS), 0); return; } } - for (i = 0; i < (s16) ARRAY_COUNT(dialogRaceSound); i++) { - if (dialogRaceSound[i] == dialogID && gMenuLineNum == DIALOG_RESPONSE_YES) { + for (i = 0; i < (s16) ARRAY_COUNT(sDialogRaceSound); i++) { + if (sDialogRaceSound[i] == dialogID && gDialogLineNum == 1) { play_race_fanfare(); return; } } - for (i = 0; i < (s16) ARRAY_COUNT(dialogStarSound); i++) { - if (dialogStarSound[i] == dialogID && gMenuLineNum == DIALOG_RESPONSE_YES) { + for (i = 0; i < (s16) ARRAY_COUNT(sDialogStarSound); i++) { + if (sDialogStarSound[i] == dialogID && gDialogLineNum == 1) { play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); return; } } - for (i = 0; i < (s16) ARRAY_COUNT(dialogBossStop); i++) { - if (dialogBossStop[i] == dialogID) { + for (i = 0; i < (s16) ARRAY_COUNT(sDialogBossStop); i++) { + if (sDialogBossStop[i] == dialogID) { seq_player_fade_out(SEQ_PLAYER_LEVEL, 1); return; } @@ -1673,132 +1128,82 @@ void handle_special_dialog_text(s16 dialogID) { // dialog ID tables, in order s16 gMenuMode = MENU_MODE_NONE; -u8 gEndCutsceneStrEn0[] = { TEXT_FILE_MARIO_EXCLAMATION }; -u8 gEndCutsceneStrEn1[] = { TEXT_POWER_STARS_RESTORED }; -u8 gEndCutsceneStrEn2[] = { TEXT_THANKS_TO_YOU }; -u8 gEndCutsceneStrEn3[] = { TEXT_THANK_YOU_MARIO }; -u8 gEndCutsceneStrEn4[] = { TEXT_SOMETHING_SPECIAL }; -u8 gEndCutsceneStrEn5[] = { TEXT_LISTEN_EVERYBODY }; -u8 gEndCutsceneStrEn6[] = { TEXT_LETS_HAVE_CAKE }; -u8 gEndCutsceneStrEn7[] = { TEXT_FOR_MARIO }; -u8 gEndCutsceneStrEn8[] = { TEXT_FILE_MARIO_QUESTION }; - -u8 *gEndCutsceneStringsEn[] = { - gEndCutsceneStrEn0, - gEndCutsceneStrEn1, - gEndCutsceneStrEn2, - gEndCutsceneStrEn3, - gEndCutsceneStrEn4, - gEndCutsceneStrEn5, - gEndCutsceneStrEn6, - gEndCutsceneStrEn7, - // This [8] string is actually unused. In the cutscene handler, the developers do not - // set the 8th one, but use the first string again at the very end, so Peach ends up - // saying "Mario!" twice. It is likely that she was originally meant to say "Mario?" at - // the end but the developers changed their mind, possibly because the line recorded - // sounded more like an exclamation than a question. - gEndCutsceneStrEn8, - NULL -}; - -#ifdef VERSION_EU -u8 gEndCutsceneStrFr0[] = { TEXT_FILE_MARIO_EXCLAMATION }; -u8 gEndCutsceneStrFr1[] = { TEXT_POWER_STARS_RESTORED_FR }; -u8 gEndCutsceneStrFr2[] = { TEXT_THANKS_TO_YOU_FR }; -u8 gEndCutsceneStrFr3[] = { TEXT_THANK_YOU_MARIO_FR }; -u8 gEndCutsceneStrFr4[] = { TEXT_SOMETHING_SPECIAL_FR }; -u8 gEndCutsceneStrFr5[] = { TEXT_COME_ON_EVERYBODY_FR }; -u8 gEndCutsceneStrFr6[] = { TEXT_LETS_HAVE_CAKE_FR }; -u8 gEndCutsceneStrFr7[] = { TEXT_FOR_MARIO_FR }; -u8 gEndCutsceneStrFr8[] = { TEXT_FILE_MARIO_QUESTION }; - -u8 *gEndCutsceneStringsFr[] = { - gEndCutsceneStrFr0, - gEndCutsceneStrFr1, - gEndCutsceneStrFr2, - gEndCutsceneStrFr3, - gEndCutsceneStrFr4, - gEndCutsceneStrFr5, - gEndCutsceneStrFr6, - gEndCutsceneStrFr7, - gEndCutsceneStrFr8, - NULL +LangArray textEndCutscene1 = DEFINE_LANGUAGE_ARRAY( + "Mario!", + "Mario!", + "Mario!", + "マリオ!!"); + +LangArray textEndCutscene2 = DEFINE_LANGUAGE_ARRAY( + "The power of the Stars is restored to the castle...", + "Grâce aux étoiles, le château a retrouvé ses pouvoirs...", + "Die Macht der Sterne ruht wieder sicher im Schloss...", + "おしろにスターが もどったのね"); + +LangArray textEndCutscene3 = DEFINE_LANGUAGE_ARRAY( + "...and it's all thanks to you!", + "...et ceci grâce à toi!", + "...und alles dank Deiner Hilfe!", + "みんな あなたのおかげだわ!"); + +LangArray textEndCutscene4 = DEFINE_LANGUAGE_ARRAY( + "Thank you, Mario!", + "Merci, Mario!", + "Vielen Dank, Mario!", + "ありがとう マリオ"); + +LangArray textEndCutscene5 = DEFINE_LANGUAGE_ARRAY( + "We have to do something special for you...", + "Tu mérites une récompense...", + "Wir haben eine Überraschung für Dich...", + "なにか おれいをしなくちゃ・・"); + +LangArray textEndCutscene6 = DEFINE_LANGUAGE_ARRAY( + "Listen, everybody,", + "Venez les amis...", + "Hört alle her...", + "さあ みんな"); + +LangArray textEndCutscene7 = DEFINE_LANGUAGE_ARRAY( + "let's bake a delicious cake...", + "Allons préparer un délicieux gâteau...", + "Laßt uns einen leckeren Kuchen backen...", + "おいしいケーキを やきましょう"); + +LangArray textEndCutscene8 = DEFINE_LANGUAGE_ARRAY( + "...for Mario...", + "...pour Mario...", + "...für Mario...", + "マリオの ために・・・"); + +LangArray textEndCutscene9 = DEFINE_LANGUAGE_ARRAY( + "Mario!", + "Mario!", + "Mario!", + "マリオ!!"); + +LangArray *gEndCutsceneStringsEn[] = { + &textEndCutscene1, + &textEndCutscene2, + &textEndCutscene3, + &textEndCutscene4, + &textEndCutscene5, + &textEndCutscene6, + &textEndCutscene7, + &textEndCutscene8, + &textEndCutscene9 }; -u8 gEndCutsceneStrDe0[] = { TEXT_FILE_MARIO_EXCLAMATION }; -u8 gEndCutsceneStrDe1[] = { TEXT_POWER_STARS_RESTORED_DE }; -u8 gEndCutsceneStrDe2[] = { TEXT_THANKS_TO_YOU_DE }; -u8 gEndCutsceneStrDe3[] = { TEXT_THANK_YOU_MARIO_DE }; -u8 gEndCutsceneStrDe4[] = { TEXT_SOMETHING_SPECIAL_DE }; -u8 gEndCutsceneStrDe5[] = { TEXT_COME_ON_EVERYBODY_DE }; -u8 gEndCutsceneStrDe6[] = { TEXT_LETS_HAVE_CAKE_DE }; -u8 gEndCutsceneStrDe7[] = { TEXT_FOR_MARIO_DE }; -u8 gEndCutsceneStrDe8[] = { TEXT_FILE_MARIO_QUESTION }; - -u8 *gEndCutsceneStringsDe[] = { - gEndCutsceneStrDe0, - gEndCutsceneStrDe1, - gEndCutsceneStrDe2, - gEndCutsceneStrDe3, - gEndCutsceneStrDe4, - gEndCutsceneStrDe5, - gEndCutsceneStrDe6, - gEndCutsceneStrDe7, - gEndCutsceneStrDe8, - NULL -}; -#endif - -u16 gCutsceneMsgFade = 0; -s16 gCutsceneMsgIndex = -1; -s16 gCutsceneMsgDuration = -1; -s16 gCutsceneMsgTimer = 0; -s8 gDialogCameraAngleIndex = CAM_SELECTION_MARIO; -s8 gDialogCourseActNum = 1; - -#if defined(VERSION_JP) || defined(VERSION_SH) - #define DIAG_VAL1 20 - #define DIAG_VAL2 240 - #define DIAG_VAL3 130 - #define DIAG_VAL4 4 -#else - #define DIAG_VAL1 16 -#ifdef VERSION_US - #define DIAG_VAL2 240 -#else - #define DIAG_VAL2 238 -#endif - #define DIAG_VAL3 132 - #define DIAG_VAL4 5 -#endif +u16 gCutsceneMsgFade = 0; +s16 gCutsceneMsgIndex = -1; +s16 gCutsceneMsgDuration = -1; +s16 gCutsceneMsgTimer = 0; +s8 gDialogCameraAngleIndex = CAM_SELECTION_MARIO; +s8 gDialogCourseActNum = 1; void render_dialog_entries(void) { -#ifdef VERSION_EU - s8 lowerBound; -#endif - void **dialogTable; - struct DialogEntry *dialog; -#if defined(VERSION_US) || defined(VERSION_SH) - s8 lowerBound; -#endif - -#ifdef VERSION_EU - gInGameLanguage = eu_get_language(); - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - dialogTable = segmented_to_virtual(dialog_table_eu_en); - break; - case LANGUAGE_FRENCH: - dialogTable = segmented_to_virtual(dialog_table_eu_fr); - break; - case LANGUAGE_GERMAN: - dialogTable = segmented_to_virtual(dialog_table_eu_de); - break; - } -#else - dialogTable = segmented_to_virtual(seg2_dialog_table); -#endif - dialog = segmented_to_virtual(dialogTable[gDialogID]); + void **dialogTable = segmented_to_virtual(languageTable[gInGameLanguage][0]); + struct DialogEntry *dialog = segmented_to_virtual(dialogTable[gDialogID]); // if the dialog entry is invalid, set the ID to DIALOG_NONE. if (segmented_to_virtual(NULL) == dialog) { @@ -1806,144 +1211,87 @@ void render_dialog_entries(void) { return; } -#ifdef VERSION_EU - gDialogX = 0; - gDialogY = 0; -#endif - - switch (gMenuState) { - case MENU_STATE_DIALOG_OPENING: - if (gDialogBoxAngle == DIALOG_BOX_ANGLE_DEFAULT) { + switch (gDialogBoxState) { + case DIALOG_STATE_OPENING: + if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) { play_dialog_sound(gDialogID); play_sound(SOUND_MENU_MESSAGE_APPEAR, gGlobalSoundSource); } if (gDialogBoxType == DIALOG_TYPE_ROTATE) { - gDialogBoxAngle -= 7.5; - gDialogBoxScale -= 1.5; + gDialogBoxOpenTimer -= 7.5f; + gDialogBoxScale -= 1.5f; } else { - gDialogBoxAngle -= 10.0; - gDialogBoxScale -= 2.0; + gDialogBoxOpenTimer -= 10.0f; + gDialogBoxScale -= 2.0f; } - if (gDialogBoxAngle == 0.0f) { - gMenuState = MENU_STATE_DIALOG_OPEN; - gMenuLineNum = 1; + if (gDialogBoxOpenTimer == 0.0f) { + gDialogBoxState = DIALOG_STATE_VERTICAL; + gDialogLineNum = 1; } -#ifndef VERSION_JP - lowerBound = 1; -#endif break; - case MENU_STATE_DIALOG_OPEN: - gDialogBoxAngle = 0.0f; + case DIALOG_STATE_VERTICAL: + gDialogBoxOpenTimer = 0.0f; - if ((gPlayer3Controller->buttonPressed & A_BUTTON) - || (gPlayer3Controller->buttonPressed & B_BUTTON)) { - if (gNextDialogPageStartStrIndex == -1) { + if (gPlayer3Controller->buttonPressed & (A_BUTTON | B_BUTTON | START_BUTTON | D_CBUTTONS | R_CBUTTONS | D_JPAD | R_JPAD)) { + if (gLastDialogPageStrPos == -1) { handle_special_dialog_text(gDialogID); - gMenuState = MENU_STATE_DIALOG_CLOSING; + gDialogBoxState = DIALOG_STATE_CLOSING; } else { - gMenuState = MENU_STATE_DIALOG_SCROLLING; + gDialogBoxState = DIALOG_STATE_HORIZONTAL; play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, gGlobalSoundSource); } } -#ifndef VERSION_JP - lowerBound = 1; -#endif break; + case DIALOG_STATE_HORIZONTAL: // scrolling + gDialogScrollOffsetY += (dialog->linesPerBox * 2); - case MENU_STATE_DIALOG_SCROLLING: - gDialogScrollOffsetY += dialog->linesPerBox * 2; - - if (gDialogScrollOffsetY >= dialog->linesPerBox * DIAG_VAL1) { - gDialogPageStartStrIndex = gNextDialogPageStartStrIndex; - gMenuState = MENU_STATE_DIALOG_OPEN; + if (gDialogScrollOffsetY >= dialog->linesPerBox * DIALOG_LINE_HEIGHT) { + gDialogTextPos = gLastDialogPageStrPos; + gDialogBoxState = DIALOG_STATE_VERTICAL; gDialogScrollOffsetY = 0; } -#ifndef VERSION_JP - lowerBound = (gDialogScrollOffsetY / DIAG_VAL1) + 1; -#endif break; - case MENU_STATE_DIALOG_CLOSING: - if (gDialogBoxAngle == 20.0f) { + case DIALOG_STATE_CLOSING: + if (gDialogBoxOpenTimer == 20.0f) { level_set_transition(0, NULL); play_sound(SOUND_MENU_MESSAGE_DISAPPEAR, gGlobalSoundSource); - if (gDialogBoxType == DIALOG_TYPE_ZOOM) { - trigger_cutscene_dialog(2); - } - - gDialogResponse = gMenuLineNum; + gDialogResponse = gDialogLineNum; } - gDialogBoxAngle += 10.0f; - gDialogBoxScale += 2.0f; + gDialogBoxOpenTimer = gDialogBoxOpenTimer + 10.0f; + gDialogBoxScale = gDialogBoxScale + 2.0f; - if (gDialogBoxAngle == DIALOG_BOX_ANGLE_DEFAULT) { - gMenuState = MENU_STATE_DEFAULT; + if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) { + gDialogBoxState = DIALOG_STATE_OPENING; gDialogID = DIALOG_NONE; - gDialogPageStartStrIndex = 0; - gDialogWithChoice = FALSE; - gNextDialogPageStartStrIndex = 0; + gDialogTextPos = 0; + gDialogHasResponse = FALSE; + gLastDialogPageStrPos = 0; gDialogResponse = DIALOG_RESPONSE_NONE; } -#ifndef VERSION_JP - lowerBound = 1; -#endif break; } render_dialog_box_type(dialog, dialog->linesPerBox); - gDPSetScissor( - gDisplayListHead++, G_SC_NON_INTERLACE, - // Horizontal scissoring isn't really required and can potentially mess up widescreen enhancements. -#ifdef WIDESCREEN - 0, -#else - ensure_nonnegative(dialog->leftOffset), -#endif - ensure_nonnegative(DIAG_VAL2 - dialog->width), -#ifdef VERSION_EU -#ifdef WIDESCREEN - SCREEN_WIDTH, -#else - ensure_nonnegative(dialog->leftOffset + (DIAG_VAL3 / gDialogBoxScale)), -#endif - ensure_nonnegative((240 - dialog->width) + (dialog->linesPerBox * 80 / DIAG_VAL4 / gDialogBoxScale)) -#else -#ifdef WIDESCREEN - SCREEN_WIDTH, -#else - ensure_nonnegative(DIAG_VAL3 + dialog->leftOffset), -#endif - ensure_nonnegative((240 - dialog->width) + (dialog->linesPerBox * 80 / DIAG_VAL4)) -#endif - ); - -#ifdef VERSION_JP - handle_dialog_text_and_pages(0, dialog); -#else - handle_dialog_text_and_pages(0, dialog, lowerBound); -#endif + gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, + // Horizontal scissoring isn't really required and can potentially mess up widescreen enhancements. + 0, + ensure_nonnegative(SCREEN_HEIGHT - dialog->width - 3), + SCREEN_WIDTH, + ensure_nonnegative(SCREEN_HEIGHT + (dialog->linesPerBox * DIALOG_LINE_HEIGHT) - dialog->width)); + handle_dialog_text_and_pages(dialog); - if (gNextDialogPageStartStrIndex == -1 && gDialogWithChoice == TRUE) { + if (gLastDialogPageStrPos == -1 && gDialogHasResponse) { render_dialog_triangle_choice(); } - - #ifdef VERSION_EU - #undef BORDER_HEIGHT - #define BORDER_HEIGHT 8 - #endif gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 2, 2, SCREEN_WIDTH - BORDER_HEIGHT / 2, SCREEN_HEIGHT - BORDER_HEIGHT / 2); - #ifdef VERSION_EU - #undef BORDER_HEIGHT - #define BORDER_HEIGHT 1 - #endif - - if (gNextDialogPageStartStrIndex != -1 && gMenuState == MENU_STATE_DIALOG_OPEN) { + if (gLastDialogPageStrPos != -1 && gDialogBoxState == DIALOG_STATE_VERTICAL) { render_dialog_triangle_next(dialog->linesPerBox); } } @@ -1959,20 +1307,13 @@ void reset_cutscene_msg_fade(void) { gCutsceneMsgFade = 0; } -#if CREDITS_TEXT_STRING_FONT -#define DL_CREDIT_TEXT_START dl_ia_text_begin -#define DL_CREDIT_TEXT_END dl_ia_text_end -#else -#define DL_CREDIT_TEXT_START dl_rgba16_text_begin -#define DL_CREDIT_TEXT_END dl_rgba16_text_end -#endif void dl_rgba16_begin_cutscene_msg_fade(void) { - gSPDisplayList(gDisplayListHead++, DL_CREDIT_TEXT_START); + gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gCutsceneMsgFade); } void dl_rgba16_stop_cutscene_msg_fade(void) { - gSPDisplayList(gDisplayListHead++, DL_CREDIT_TEXT_END); + gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); if (gCutsceneMsgFade < 250) { gCutsceneMsgFade += 25; @@ -1980,73 +1321,18 @@ void dl_rgba16_stop_cutscene_msg_fade(void) { gCutsceneMsgFade = 255; } } -#undef DL_CREDIT_TEXT_START -#undef DL_CREDIT_TEXT_END - -#if !CREDITS_TEXT_STRING_FONT -u8 ascii_to_credits_char(u8 c) { - if (c >= 'A' && c <= 'Z') { - return (c - ('A' - 0xA)); - } - - if (c >= 'a' && c <= 'z') { // remap lower to upper case - return (c - ('a' - 0xA)); - } - - if (c == ' ') { - return GLOBAL_CHAR_SPACE; - } - - if (c == '.') { - return 0x24; - } - - if (c == '3') { - return ASCII_TO_DIALOG('3'); - } - - if (c == '4') { - return ASCII_TO_DIALOG('4'); - } - - if (c == '6') { - return ASCII_TO_DIALOG('6'); - } - - return GLOBAL_CHAR_SPACE; -} - -void print_credits_str_ascii(s16 x, s16 y, const char *str) { - s32 pos = 0; - u8 c = str[pos]; - u8 creditStr[100]; - - while (c != '\0') { - creditStr[pos++] = ascii_to_credits_char(c); - c = str[pos]; - } - - creditStr[pos] = GLOBAL_CHAR_TERMINATOR; - - print_credits_string(x, y, creditStr); -} -#endif -void set_cutscene_message(s16 xOffset, s16 yOffset, s16 msgIndex, s16 msgDuration) { +void set_cutscene_message(s16 msgIndex, s16 msgDuration) { // is message done printing? if (gCutsceneMsgIndex == -1) { gCutsceneMsgIndex = msgIndex; gCutsceneMsgDuration = msgDuration; gCutsceneMsgTimer = 0; - gCutsceneMsgXOffset = xOffset; - gCutsceneMsgYOffset = yOffset; gCutsceneMsgFade = 0; } } void do_cutscene_handler(void) { - s16 x; - // is a cutscene playing? do not perform this handler's actions if so. if (gCutsceneMsgIndex == -1) { return; @@ -2055,28 +1341,10 @@ void do_cutscene_handler(void) { create_dl_ortho_matrix(); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gCutsceneMsgFade); + gDialogTextAlpha = gCutsceneMsgFade; + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); -#ifdef VERSION_EU - switch (eu_get_language()) { - case LANGUAGE_ENGLISH: - x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex], 10.0f); - print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex]); - break; - case LANGUAGE_FRENCH: - x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsFr[gCutsceneMsgIndex], 10.0f); - print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsFr[gCutsceneMsgIndex]); - break; - case LANGUAGE_GERMAN: - x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsDe[gCutsceneMsgIndex], 10.0f); - print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsDe[gCutsceneMsgIndex]); - break; - } -#else - // get the x coordinate of where the cutscene string starts. - x = get_str_x_pos_from_center(gCutsceneMsgXOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex], 10.0f); - print_generic_string(x, 240 - gCutsceneMsgYOffset, gEndCutsceneStringsEn[gCutsceneMsgIndex]); -#endif + print_generic_string_aligned(SCREEN_CENTER_X, 13, LANG_ARRAY(*gEndCutsceneStringsEn[gCutsceneMsgIndex]), TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); @@ -2108,63 +1376,28 @@ void do_cutscene_handler(void) { gCutsceneMsgTimer++; } -#ifdef VERSION_JP - #define PEACH_MESSAGE_TIMER 170 -#else - #define PEACH_MESSAGE_TIMER 250 -#endif - -#if defined(VERSION_JP) || defined(VERSION_SH) - #define STR_X 53 - #define STR_Y 136 -#else - #define STR_X 38 - #define STR_Y 142 -#endif +#define PEACH_MESSAGE_TIMER 250 // "Dear Mario" message handler void print_peach_letter_message(void) { - void **dialogTable; - struct DialogEntry *dialog; - u8 *str; - -#ifdef VERSION_EU - gInGameLanguage = eu_get_language(); - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - dialogTable = segmented_to_virtual(dialog_table_eu_en); - break; - case LANGUAGE_FRENCH: - dialogTable = segmented_to_virtual(dialog_table_eu_fr); - break; - case LANGUAGE_GERMAN: - dialogTable = segmented_to_virtual(dialog_table_eu_de); - break; - } -#else - dialogTable = segmented_to_virtual(seg2_dialog_table); -#endif - dialog = segmented_to_virtual(dialogTable[gDialogID]); - str = segmented_to_virtual(dialog->str); + void **dialogTable = segmented_to_virtual(languageTable[gInGameLanguage][0]); + struct DialogEntry *dialog = segmented_to_virtual(dialogTable[gDialogID]); + char *str = segmented_to_virtual(dialog->str); create_dl_translation_matrix(MENU_MTX_PUSH, 97.0f, 118.0f, 0); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gCutsceneMsgFade); + gDialogTextAlpha = gCutsceneMsgFade; + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, castle_grounds_seg7_dl_0700EA58); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 20, 20, 20, gCutsceneMsgFade); + gDPSetEnvColor(gDisplayListHead++, 20, 20, 20, gDialogTextAlpha); + + print_generic_string(38, 142, str); - print_generic_string(STR_X, STR_Y, str); -#if defined(VERSION_JP) - gSPDisplayList(gDisplayListHead++, dl_ia_text_end); -#endif - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); -#ifndef VERSION_JP gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - gDPSetEnvColor(gDisplayListHead++, 200, 80, 120, gCutsceneMsgFade); + gDPSetEnvColor(gDisplayListHead++, 200, 80, 120, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, castle_grounds_seg7_us_dl_0700F2E8); -#endif // at the start/end of message, reset the fade. if (gCutsceneMsgTimer == 0) { @@ -2212,12 +1445,12 @@ void render_hud_cannon_reticle(void) { gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); create_dl_translation_matrix(MENU_MTX_PUSH, 8.0f, -20.0f, 0); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, 90.0f, 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); create_dl_translation_matrix(MENU_MTX_PUSH, -8.0f, 20.0f, 0); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, -90.0f, 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, -DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); @@ -2287,176 +1520,118 @@ void render_pause_red_coins(void) { } } -#ifdef VERSION_EU -u8 gTextCourse[][7] = { - { TEXT_COURSE }, - { TEXT_COURSE_FR }, - { TEXT_COURSE_DE } -}; -#define textCourse gTextCourse -#endif +LangArray textCourseX = DEFINE_LANGUAGE_ARRAY( + "COURSE %s", + "NIVEAU %s", + "KURS %s", + "コース%s"); -#if defined(VERSION_JP) || defined(VERSION_SH) - #define CRS_NUM_X1 93 -#elif defined(VERSION_US) - #define CRS_NUM_X1 100 -#elif defined(VERSION_EU) - #define CRS_NUM_X1 get_string_width(LANGUAGE_ARRAY(textCourse)) + 51 -#endif +LangArray textMyScore = DEFINE_LANGUAGE_ARRAY( + "MY SCORE", + "MON SCORE", + "LEISTUNG", + "マイスコア"); -#ifdef VERSION_EU - #define TXT_COURSE_X 48 - #define TXT_STAR_X 89 - #define ACT_NAME_X 107 - #define LVL_NAME_X 108 - #define SECRET_LVL_NAME_X get_str_x_pos_from_center(159, &courseName[3], 10.0f) - #define MYSCORE_X 48 -#else - #define TXT_COURSE_X 63 - #define TXT_STAR_X 98 - #define ACT_NAME_X 116 - #define LVL_NAME_X 117 - #define SECRET_LVL_NAME_X 94 - #define MYSCORE_X 62 -#endif +#define PAUSE_MENU_LEFT_X 106 +#define PAUSE_MENU_RIGHT_X 117 + +#define PAUSE_MENU_COURSE_Y 157 +#define PAUSE_MENU_ACT_Y 140 +#define PAUSE_MENU_MY_SCORE_Y 121 void render_pause_my_score_coins(void) { -#ifdef VERSION_EU - u8 textMyScore[][10] = { - { TEXT_MY_SCORE }, - { TEXT_MY_SCORE_FR }, - { TEXT_MY_SCORE_DE } - }; -#else - u8 textCourse[] = { TEXT_COURSE }; - u8 textMyScore[] = { TEXT_MY_SCORE }; -#endif - u8 textStar[] = { TEXT_STAR }; - u8 textUnfilledStar[] = { TEXT_UNFILLED_STAR }; - - u8 strCourseNum[4]; - void **courseNameTbl; - u8 *courseName; - void **actNameTbl; - u8 *actName; - u8 courseIndex; - u8 starFlags; - -#ifndef VERSION_EU - courseNameTbl = segmented_to_virtual(seg2_course_name_table); - actNameTbl = segmented_to_virtual(seg2_act_name_table); -#endif + char str[20]; - courseIndex = COURSE_NUM_TO_INDEX(gCurrCourseNum); - starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum)); + void **courseNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]); + void **actNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][2]); -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#endif + u8 courseIndex = COURSE_NUM_TO_INDEX(gCurrCourseNum); + u8 starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum)); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); if (courseIndex <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { - print_hud_my_score_coins(1, gCurrSaveFileNum - 1, courseIndex, 178, 103); - print_hud_my_score_stars(gCurrSaveFileNum - 1, courseIndex, 118, 103); + print_hud_my_score_coins(1, gCurrSaveFileNum - 1, courseIndex, PAUSE_MENU_RIGHT_X + 61, PAUSE_MENU_MY_SCORE_Y - 18); + print_hud_my_score_stars( gCurrSaveFileNum - 1, courseIndex, PAUSE_MENU_RIGHT_X, PAUSE_MENU_MY_SCORE_Y - 18); } gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); - - if (courseIndex <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX) - && save_file_get_course_star_count(gCurrSaveFileNum - 1, courseIndex) != 0) { - print_generic_string(MYSCORE_X, 121, LANGUAGE_ARRAY(textMyScore)); - } + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - courseName = segmented_to_virtual(courseNameTbl[courseIndex]); + char *courseName = segmented_to_virtual(courseNameTbl[courseIndex]); if (courseIndex <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { - print_generic_string(TXT_COURSE_X, 157, LANGUAGE_ARRAY(textCourse)); - int_to_str(gCurrCourseNum, strCourseNum); - print_generic_string(CRS_NUM_X1, 157, strCourseNum); + char courseNumText[8]; + format_int_to_string(courseNumText, gCurrCourseNum); + sprintf(str, LANG_ARRAY(textCourseX), courseNumText); + print_generic_string_aligned(PAUSE_MENU_LEFT_X, PAUSE_MENU_COURSE_Y, str, TEXT_ALIGN_RIGHT); - actName = segmented_to_virtual(actNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum) * 6 + gDialogCourseActNum - 1]); + char *actName = segmented_to_virtual(actNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum) * 6 + gDialogCourseActNum - 1]); if (starFlags & (1 << (gDialogCourseActNum - 1))) { - print_generic_string(TXT_STAR_X, 140, textStar); + print_generic_string_aligned(PAUSE_MENU_LEFT_X, PAUSE_MENU_ACT_Y, "★", TEXT_ALIGN_RIGHT); + } else { + print_generic_string_aligned(PAUSE_MENU_LEFT_X, PAUSE_MENU_ACT_Y, "☆", TEXT_ALIGN_RIGHT); + } + + print_generic_string(PAUSE_MENU_RIGHT_X, PAUSE_MENU_ACT_Y, actName); + if (check_number_string_in_course_name(courseName)) { + print_generic_string(PAUSE_MENU_RIGHT_X, PAUSE_MENU_COURSE_Y, &courseName[3]); } else { - print_generic_string(TXT_STAR_X, 140, textUnfilledStar); + print_generic_string(PAUSE_MENU_RIGHT_X, PAUSE_MENU_COURSE_Y, courseName); } - print_generic_string(ACT_NAME_X, 140, actName); -#ifndef VERSION_JP - print_generic_string(LVL_NAME_X, 157, &courseName[3]); + if (save_file_get_course_star_count(gCurrSaveFileNum - 1, courseIndex) != 0) { + print_generic_string_aligned(PAUSE_MENU_LEFT_X + 3, PAUSE_MENU_MY_SCORE_Y, LANG_ARRAY(textMyScore), TEXT_ALIGN_RIGHT); + } } else { - print_generic_string(SECRET_LVL_NAME_X, 157, &courseName[3]); -#endif + print_generic_string_aligned(SCREEN_CENTER_X, PAUSE_MENU_COURSE_Y, courseName, TEXT_ALIGN_CENTER); } -#ifdef VERSION_JP - print_generic_string(LVL_NAME_X, 157, &courseName[3]); -#endif - gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define TXT1_X 4 - #define TXT2_X 116 - #define Y_VAL7 0 -#else - #define TXT1_X 3 - #define TXT2_X 119 - #define Y_VAL7 2 -#endif +LangArray textLakituMario = DEFINE_LANGUAGE_ARRAY( + "LAKITU ↔ MARIO", + "LAKITU ↔ MARIO", + "LAKITU ↔ MARIO", + "ジュゲム↔マリオ"); -void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) { - u8 textLakituMario[] = { TEXT_LAKITU_MARIO }; - u8 textLakituStop[] = { TEXT_LAKITU_STOP }; -#ifdef VERSION_EU - u8 textNormalUpClose[][20] = { - { TEXT_NORMAL_UPCLOSE }, - { TEXT_NORMAL_UPCLOSE_FR }, - { TEXT_NORMAL_UPCLOSE_DE } - }; - u8 textNormalFixed[][17] = { - { TEXT_NORMAL_FIXED }, - { TEXT_NORMAL_FIXED_FR }, - { TEXT_NORMAL_FIXED_DE }, - }; -#else - u8 textNormalUpClose[] = { TEXT_NORMAL_UPCLOSE }; - u8 textNormalFixed[] = { TEXT_NORMAL_FIXED }; -#endif +LangArray textLakituStop = DEFINE_LANGUAGE_ARRAY( + "LAKITU ↔ STOP", + "LAKITU ↔ STOP", + "LAKITU ↔ STOP", + "ジュゲム↔ストップ"); + +LangArray textNormalUpClose = DEFINE_LANGUAGE_ARRAY( + "(NORMAL)(UP-CLOSE)", + "(NORMAL)(GROS-PLAN)", + "(NORMAL)(WEIT-ZOOM)", + "(おすすめ)(リアル)"); +LangArray textNormalFixed = DEFINE_LANGUAGE_ARRAY( + "(NORMAL)(FIXED)", + "(NORMAL)(FIXE)", + "(NORMAL)(STATIV)", + "(おすすめ)(とまる)"); + +void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) { handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, index, 1, 2); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - print_generic_string(x + 14, y + 2, textLakituMario); - print_generic_string(x + TXT1_X, y - 13, LANGUAGE_ARRAY(textNormalUpClose)); - print_generic_string(x + 124, y + 2, textLakituStop); - print_generic_string(x + TXT2_X, y - 13, LANGUAGE_ARRAY(textNormalFixed)); + print_generic_string_aligned(x + 54, y, LANG_ARRAY(textLakituMario), TEXT_ALIGN_CENTER); + print_generic_string_aligned(x + 54, y - 15, LANG_ARRAY(textNormalUpClose), TEXT_ALIGN_CENTER); + print_generic_string_aligned(x + 160, y, LANG_ARRAY(textLakituStop), TEXT_ALIGN_CENTER); + print_generic_string_aligned(x + 160, y - 15, LANG_ARRAY(textNormalFixed), TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - create_dl_translation_matrix(MENU_MTX_PUSH, ((*index - 1) * xIndex) + x, y + Y_VAL7, 0); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + create_dl_translation_matrix(MENU_MTX_PUSH, ((*index - 1) * xIndex) + x, y, 0); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); @@ -2470,57 +1645,46 @@ void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) { } } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define X_VAL8 0 - #define Y_VAL8 4 -#else - #define X_VAL8 4 - #define Y_VAL8 2 -#endif +LangArray textContinue = DEFINE_LANGUAGE_ARRAY( + "CONTINUE", + "CONTINUER", + "WEITER", + "つづけて マリオする?"); -void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { -#ifdef VERSION_EU - u8 textContinue[][10] = { - { TEXT_CONTINUE }, - { TEXT_CONTINUE_FR }, - { TEXT_CONTINUE_DE } - }; - u8 textExitCourse[][15] = { - { TEXT_EXIT_COURSE }, - { TEXT_EXIT_COURSE_FR }, - { TEXT_EXIT_COURSE_DE } - }; - - u8 textCameraAngleR[][24] = { - { TEXT_CAMERA_ANGLE_R }, - { TEXT_CAMERA_ANGLE_R_FR }, - { TEXT_CAMERA_ANGLE_R_DE } - }; -#else - u8 textContinue[] = { TEXT_CONTINUE }; - u8 textExitCourse[] = { TEXT_EXIT_COURSE }; - u8 textCameraAngleR[] = { TEXT_CAMERA_ANGLE_R }; -#endif +LangArray textExitCourse = DEFINE_LANGUAGE_ARRAY( + "EXIT COURSE", + "QUITTER NIVEAU", + "KURS VERLASSEN", + "コースからでる?"); + +LangArray textCameraAngleR = DEFINE_LANGUAGE_ARRAY( + "SET CAMERA ANGLE WITH Ⓡ", + "RÉGLAGE CAMÉRA AVEC Ⓡ", + "KAMERA MIT Ⓡ VERSTELLEN", + "Rボタンのカメラきりかえ"); +void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 3); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - print_generic_string(x + 10, y - 2, LANGUAGE_ARRAY(textContinue)); - print_generic_string(x + 10, y - 17, LANGUAGE_ARRAY(textExitCourse)); + print_generic_string(x, y, LANG_ARRAY(textContinue)); + print_generic_string(x, y - 15, LANG_ARRAY(textExitCourse)); if (*index != MENU_OPT_CAMERA_ANGLE_R) { - print_generic_string(x + 10, y - 33, LANGUAGE_ARRAY(textCameraAngleR)); + print_generic_string(x, y - 31, LANG_ARRAY(textCameraAngleR)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - create_dl_translation_matrix(MENU_MTX_PUSH, x - X_VAL8, (y - ((*index - 1) * yIndex)) - Y_VAL8, 0); + create_dl_translation_matrix(MENU_MTX_PUSH, x - 14, (y - ((*index - 1) * yIndex)), 0); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); - } else { // MENU_OPT_CAMERA_ANGLE_R - render_pause_camera_options(x - 42, y - 42, &gDialogCameraAngleIndex, 110); + } + + if (*index == MENU_OPT_CAMERA_ANGLE_R) { + render_pause_camera_options(x - 52, y - 38, &gDialogCameraAngleIndex, 110); } } @@ -2532,8 +1696,9 @@ void render_pause_castle_menu_box(s16 x, s16 y) { gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); create_dl_translation_matrix(MENU_MTX_PUSH, x + 6, y - 28, 0); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, 90.0f, 0, 0, 1.0f); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); + gDPPipeSync(gDisplayListHead++); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); @@ -2544,34 +1709,26 @@ void render_pause_castle_menu_box(s16 x, s16 y) { } void highlight_last_course_complete_stars(void) { - u8 completedCourseIndex; + u8 doneCourseIndex; if (gLastCompletedCourseNum == COURSE_NONE) { - completedCourseIndex = 0; + doneCourseIndex = COURSE_NUM_TO_INDEX(COURSE_MIN); } else { - completedCourseIndex = COURSE_NUM_TO_INDEX(gLastCompletedCourseNum); + doneCourseIndex = COURSE_NUM_TO_INDEX(gLastCompletedCourseNum); - if (completedCourseIndex >= COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES)) { - completedCourseIndex = COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES); + if (doneCourseIndex >= COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES)) { + doneCourseIndex = COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES); } } - gMenuLineNum = completedCourseIndex; + gDialogLineNum = doneCourseIndex; } -#ifdef VERSION_EU - #define PAUSE_X get_str_x_pos_from_center_scale(SCREEN_WIDTH / 2, textPause, 12.0f) -#else - #define PAUSE_X 123 -#endif - void print_hud_pause_colorful_str(void) { - u8 textPause[] = { TEXT_PAUSE }; - gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - print_hud_lut_string(HUD_LUT_GLOBAL, PAUSE_X, 81, textPause); + print_hud_lut_string_aligned(SCREEN_CENTER_X, 81, "PAUSE", TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); } @@ -2579,198 +1736,174 @@ void print_hud_pause_colorful_str(void) { void render_pause_castle_course_stars(s16 x, s16 y, s16 fileIndex, s16 courseIndex) { s16 hasStar = 0; - u8 str[30]; - - u8 textStar[] = { TEXT_STAR }; + char str[30]; + char *entries[6]; u8 starFlags = save_file_get_star_flags(fileIndex, courseIndex); u16 starCount = save_file_get_course_star_count(fileIndex, courseIndex); u16 nextStar = 0; - if (starFlags & (1 << 6)) { + if (starFlags & STAR_FLAG_ACT_100_COINS) { starCount--; - print_generic_string(x + 89, y - 5, textStar); + print_generic_string(x + 98, y, "★"); } while (hasStar != starCount) { if (starFlags & (1 << nextStar)) { - str[nextStar * 2] = DIALOG_CHAR_STAR_FILLED; + entries[nextStar] = "★"; hasStar++; } else { - str[nextStar * 2] = DIALOG_CHAR_STAR_OPEN; + entries[nextStar] = "☆"; } - - str[nextStar * 2 + 1] = DIALOG_CHAR_SPACE; nextStar++; } if (starCount == nextStar && starCount != 6) { - str[nextStar * 2] = DIALOG_CHAR_STAR_OPEN; - str[nextStar * 2 + 1] = DIALOG_CHAR_SPACE; + entries[nextStar] = "☆"; + nextStar++; + } + while (nextStar < 6) { + entries[nextStar] = ""; nextStar++; } - str[nextStar * 2] = DIALOG_CHAR_TERMINATOR; - - print_generic_string(x + 14, y + 13, str); + sprintf(str, "%s %s %s %s %s %s", entries[0], entries[1], entries[2], entries[3], entries[4], entries[5]); + print_generic_string(x + 23, y + 18, str); } -void render_pause_castle_main_strings(s16 x, s16 y) { -#ifdef VERSION_EU - void **courseNameTbl; -#else - void **courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif +LangArray textCoinX = DEFINE_LANGUAGE_ARRAY( + "✪× %s", + "✪× %s", + "✪× %s", + "✪x%s"); -#ifdef VERSION_EU - u8 textCoin[] = { TEXT_COIN }; - u8 textX[] = { TEXT_VARIABLE_X }; -#else - u8 textCoin[] = { TEXT_COIN_X }; -#endif +LangArray textStarX = DEFINE_LANGUAGE_ARRAY( + "★× %s", + "★× %s", + "★× %s", + "★x%s"); - void *courseName; +void render_pause_castle_main_strings(s16 x, s16 y) { + void **courseNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]); - u8 strVal[8]; - s16 prevCourseIndex = gMenuLineNum; + char *courseName; + + char str[8]; + char countText[10]; + s16 prevCourseIndex = gDialogLineNum; -#ifdef VERSION_EU - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#endif handle_menu_scrolling( - MENU_SCROLL_VERTICAL, &gMenuLineNum, + MENU_SCROLL_VERTICAL, &gDialogLineNum, COURSE_NUM_TO_INDEX(COURSE_MIN) - 1, COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES) + 1 ); - if (gMenuLineNum == COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES) + 1) { - gMenuLineNum = COURSE_NUM_TO_INDEX(COURSE_MIN); // Exceeded max, set to min + if (gDialogLineNum == COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES) + 1) { + gDialogLineNum = COURSE_NUM_TO_INDEX(COURSE_MIN); // Exceeded max, set to min } - if (gMenuLineNum == COURSE_NUM_TO_INDEX(COURSE_MIN) - 1) { - gMenuLineNum = COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES); // Exceeded min, set to max + if (gDialogLineNum == COURSE_NUM_TO_INDEX(COURSE_MIN) - 1) { + gDialogLineNum = COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES); // Exceeded min, set to max } - if (gMenuLineNum != COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES)) { - while (save_file_get_course_star_count(gCurrSaveFileNum - 1, gMenuLineNum) == 0) { - if (gMenuLineNum >= prevCourseIndex) { - gMenuLineNum++; + if (gDialogLineNum != COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES)) { + while (save_file_get_course_star_count(gCurrSaveFileNum - 1, gDialogLineNum) == 0) { + if (gDialogLineNum >= prevCourseIndex) { + gDialogLineNum++; } else { - gMenuLineNum--; + gDialogLineNum--; } - if (gMenuLineNum == COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX) + 1 - || gMenuLineNum == COURSE_NUM_TO_INDEX(COURSE_MIN) - 1) { - gMenuLineNum = COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES); + if (gDialogLineNum == COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX) + 1 + || gDialogLineNum == COURSE_NUM_TO_INDEX(COURSE_MIN) - 1) { + gDialogLineNum = COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES); break; } } } gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); - - if (gMenuLineNum <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { // Main courses - courseName = segmented_to_virtual(courseNameTbl[gMenuLineNum]); - render_pause_castle_course_stars(x, y, gCurrSaveFileNum - 1, gMenuLineNum); - print_generic_string(x + 34, y - 5, textCoin); -#ifdef VERSION_EU - print_generic_string(x + 44, y - 5, textX); -#endif - int_to_str(save_file_get_course_coin_score(gCurrSaveFileNum - 1, gMenuLineNum), strVal); - print_generic_string(x + 54, y - 5, strVal); -#ifdef VERSION_EU - print_generic_string(x - 17, y + 30, courseName); -#endif + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + + if (gDialogLineNum <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { // Main courses + courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]); + if (check_number_string_in_course_name(courseName)) { + print_generic_string(x - 50, y + 35, &courseName[3]); + } else { + print_generic_string(x - 50, y + 35, courseName); + } + + render_pause_castle_course_stars(x - 65, y, gCurrSaveFileNum - 1, gDialogLineNum); + + format_int_to_string(countText, save_file_get_course_coin_score(gCurrSaveFileNum - 1, gDialogLineNum)); + sprintf(str, LANG_ARRAY(textCoinX), countText); + print_generic_string(x - 22, y, str); + + format_int_to_string(str, gDialogLineNum + 1); + print_generic_string_aligned(x - 55, y + 35, str, TEXT_ALIGN_RIGHT); } else { // Castle secret stars - u8 textStarX[] = { TEXT_STAR_X }; courseName = segmented_to_virtual(courseNameTbl[COURSE_MAX]); - print_generic_string(x + 40, y + 13, textStarX); - int_to_str(save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_BONUS_STAGES - 1, COURSE_MAX - 1), strVal); - print_generic_string(x + 60, y + 13, strVal); -#ifdef VERSION_EU - print_generic_string(get_str_x_pos_from_center(x + 51, courseName, 10.0f), y + 30, courseName); -#endif - } + print_generic_string_aligned(x, y + 35, courseName, TEXT_ALIGN_CENTER); -#ifndef VERSION_EU - print_generic_string(x - 9, y + 30, courseName); -#endif + format_int_to_string(countText, save_file_get_total_star_count(gCurrSaveFileNum - 1, + COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES), + COURSE_NUM_TO_INDEX(COURSE_MAX))); + sprintf(str, LANG_ARRAY(textStarX), countText); + print_generic_string_aligned(x, y + 18, str, TEXT_ALIGN_CENTER); + } gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } s8 gCourseCompleteCoinsEqual = FALSE; -s32 gCourseCompleteScreenTimer = 0; +s32 gCourseDoneMenuTimer = 0; s32 gCourseCompleteCoins = 0; -s8 gHudFlash = 0; +s8 gHudFlash = HUD_FLASH_NONE; -s16 render_pause_screen(void) { +s32 render_pause_courses_and_castle(void) { s16 index; -#ifdef VERSION_EU - gInGameLanguage = eu_get_language(); -#endif -#ifdef EXT_OPTIONS_MENU - if (optmenu_open == 0) { -#endif - switch (gMenuState) { - case MENU_STATE_PAUSE_SCREEN_OPENING: - gMenuLineNum = MENU_OPT_DEFAULT; - gMenuTextAlpha = 0; + switch (gDialogBoxState) { + case DIALOG_STATE_OPENING: + gDialogLineNum = MENU_OPT_DEFAULT; + gDialogTextAlpha = 0; level_set_transition(-1, NULL); play_sound(SOUND_MENU_PAUSE, gGlobalSoundSource); - if (gCurrCourseNum >= COURSE_MIN && gCurrCourseNum <= COURSE_MAX) { + if (gCurrCourseNum >= COURSE_MIN + && gCurrCourseNum <= COURSE_MAX) { change_dialog_camera_angle(); - gMenuState = MENU_STATE_PAUSE_SCREEN_COURSE; + gDialogBoxState = DIALOG_STATE_VERTICAL; } else { highlight_last_course_complete_stars(); - gMenuState = MENU_STATE_PAUSE_SCREEN_CASTLE; + gDialogBoxState = DIALOG_STATE_HORIZONTAL; } break; - case MENU_STATE_PAUSE_SCREEN_COURSE: + case DIALOG_STATE_VERTICAL: shade_screen(); render_pause_my_score_coins(); render_pause_red_coins(); - -#if !EXIT_COURSE_ANYWHERE -/* Added support for the "Exit course at any time" cheat */ - if ((gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) -#ifdef CHEATS_ACTIONS - || (Cheats.EnableCheats && Cheats.ExitAnywhere) +#ifndef DISABLE_EXIT_COURSE +#ifdef EXIT_COURSE_WHILE_MOVING + if ((gMarioStates[0].action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER | ACT_FLAG_PAUSE_EXIT)) + || (gMarioStates[0].pos[1] <= gMarioStates[0].floorHeight)) { +#else + if (gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) { #endif - ) { - render_pause_course_options(99, 93, &gMenuLineNum, 15); + render_pause_course_options(109, 91, &gDialogLineNum, 15); } #endif -#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION - if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | Z_TRIG)) -#else - if (gPlayer3Controller->buttonPressed & A_BUTTON - || (gPlayer3Controller->buttonPressed & START_BUTTON)) -#endif - { + if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON)) { level_set_transition(0, NULL); play_sound(SOUND_MENU_PAUSE_2, gGlobalSoundSource); - gMenuState = MENU_STATE_DEFAULT; + gDialogBoxState = DIALOG_STATE_OPENING; gMenuMode = MENU_MODE_NONE; - if (gMenuLineNum == MENU_OPT_EXIT_COURSE) { - index = gMenuLineNum; + if (gDialogLineNum == MENU_OPT_EXIT_COURSE) { + index = gDialogLineNum; } else { // MENU_OPT_CONTINUE or MENU_OPT_CAMERA_ANGLE_R index = MENU_OPT_DEFAULT; } @@ -2779,109 +1912,70 @@ s16 render_pause_screen(void) { } break; - case MENU_STATE_PAUSE_SCREEN_CASTLE: + case DIALOG_STATE_HORIZONTAL: shade_screen(); print_hud_pause_colorful_str(); render_pause_castle_menu_box(160, 143); - render_pause_castle_main_strings(104, 60); + render_pause_castle_main_strings(SCREEN_CENTER_X, 55); -#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION - if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | Z_TRIG)) -#else - if ((gPlayer3Controller->buttonPressed & A_BUTTON) - || (gPlayer3Controller->buttonPressed & START_BUTTON)) -#endif - { + if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | Z_TRIG)) { level_set_transition(0, NULL); play_sound(SOUND_MENU_PAUSE_2, gGlobalSoundSource); gMenuMode = MENU_MODE_NONE; - gMenuState = MENU_STATE_DEFAULT; + gDialogBoxState = DIALOG_STATE_OPENING; return MENU_OPT_DEFAULT; } break; } - if (gMenuTextAlpha < 250) { - gMenuTextAlpha += 25; - } -#ifdef EXT_OPTIONS_MENU - } else { - shade_screen(); - optmenu_draw(); + if (gDialogTextAlpha < 250) { + gDialogTextAlpha += 25; } - optmenu_check_buttons(); - optmenu_draw_prompt(); -#endif return MENU_OPT_NONE; } -#if defined(VERSION_JP) - #define TXT_HISCORE_X 112 - #define TXT_HISCORE_Y 48 - #define TXT_CONGRATS_X 60 -#elif defined(VERSION_US) - #define TXT_HISCORE_X 109 - #define TXT_HISCORE_Y 36 - #define TXT_CONGRATS_X 70 -#elif defined(VERSION_EU) - #define TXT_HISCORE_X get_str_x_pos_from_center_scale(160, LANGUAGE_ARRAY(textHiScore), 12.0f) - #define TXT_HISCORE_Y 36 - #define TXT_CONGRATS_X get_str_x_pos_from_center_scale(160, LANGUAGE_ARRAY(textCongratulations), 12.0f) -#elif defined(VERSION_SH) - #define TXT_HISCORE_X 118 - #define TXT_HISCORE_Y 48 - #define TXT_CONGRATS_X 70 -#endif +enum HUDCourseCompleteStringIDs { + HUD_PRINT_HISCORE, + HUD_PRINT_CONGRATULATIONS +}; -#define HUD_PRINT_HISCORE 0 -#define HUD_PRINT_CONGRATULATIONS 1 +LangArray textHudHiScore = DEFINE_LANGUAGE_ARRAY( + "HI SCORE", + "MEILLEUR SCORE", + "BESTLEISTUNG", + "HISCORE"); -void print_hud_course_complete_string(s8 str) { -#ifdef VERSION_EU - u8 textHiScore[][15] = { - { TEXT_HUD_HI_SCORE }, - { TEXT_HUD_HI_SCORE_FR }, - { TEXT_HUD_HI_SCORE_DE } - }; - u8 textCongratulations[][16] = { - { TEXT_HUD_CONGRATULATIONS }, - { TEXT_HUD_CONGRATULATIONS_FR }, - { TEXT_HUD_CONGRATULATIONS_DE } - }; -#else - u8 textHiScore[] = { TEXT_HUD_HI_SCORE }; - u8 textCongratulations[] = { TEXT_HUD_CONGRATULATIONS }; -#endif +LangArray textCongratulations = DEFINE_LANGUAGE_ARRAY( + "CONGRATULATIONS", + "FELICITATIONS", + "GRATULATION", + "CONGRATULATIONS"); - u8 color = sins(gMenuTextColorTransTimer) * 50.0f + 200.0f; +void print_hud_course_complete_string(s8 str) { + u8 colorFade = sins(gDialogColorFadeTimer) * 50.0f + 200.0f; gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, color, color, color, 255); + gDPSetEnvColor(gDisplayListHead++, colorFade, colorFade, colorFade, 255); if (str == HUD_PRINT_HISCORE) { - print_hud_lut_string(HUD_LUT_GLOBAL, TXT_HISCORE_X, TXT_HISCORE_Y, LANGUAGE_ARRAY(textHiScore)); + print_hud_lut_string_aligned(SCREEN_CENTER_X, 36, LANG_ARRAY(textHudHiScore), TEXT_ALIGN_CENTER); } else { // HUD_PRINT_CONGRATULATIONS - print_hud_lut_string(HUD_LUT_GLOBAL, TXT_CONGRATS_X, 67, LANGUAGE_ARRAY(textCongratulations)); + print_hud_lut_string_aligned(SCREEN_CENTER_X, 67, LANG_ARRAY(textCongratulations), TEXT_ALIGN_CENTER); } gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); } void print_hud_course_complete_coins(s16 x, s16 y) { - u8 courseCompleteCoinsStr[4]; - u8 hudTextSymCoin[] = { GLYPH_COIN, GLYPH_SPACE }; - u8 hudTextSymX[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; + char courseCompleteCoinsStr[10]; gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - print_hud_lut_string(HUD_LUT_GLOBAL, x, y, hudTextSymCoin); - print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, hudTextSymX); - - int_to_str(gCourseCompleteCoins, courseCompleteCoinsStr); - print_hud_lut_string(HUD_LUT_GLOBAL, x + 32, y, courseCompleteCoinsStr); + sprintf(courseCompleteCoinsStr, "✪×%d", gCourseCompleteCoins); + print_hud_lut_string(x, y, courseCompleteCoinsStr); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); @@ -2893,100 +1987,61 @@ void print_hud_course_complete_coins(s16 x, s16 y) { print_hud_course_complete_string(HUD_PRINT_HISCORE); } } else { - if ((gCourseCompleteScreenTimer & 1) || gHudDisplay.coins > 70) { + if ((gCourseDoneMenuTimer & 1) || gHudDisplay.coins > 70) { gCourseCompleteCoins++; play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gGlobalSoundSource); -#if QOL_FIX_COMPLETE_COURSE_50_COINS - if (gCourseCompleteCoins % 50 == 0) -#else - if (gCourseCompleteCoins == 50 || gCourseCompleteCoins == 100 || gCourseCompleteCoins == 150) -#endif - { +#ifdef ENABLE_LIVES + if (gCourseCompleteCoins && ((gCourseCompleteCoins % 50) == 0)) { play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource); gMarioState->numLives++; } +#endif } - if (gHudDisplay.coins == gCourseCompleteCoins && gGotFileCoinHiScore) { + if ((gHudDisplay.coins == gCourseCompleteCoins) && gGotFileCoinHiScore) { play_sound(SOUND_MENU_MARIO_CASTLE_WARP2, gGlobalSoundSource); } } } -void play_star_fanfare_and_flash_hud(s32 arg, u8 starFlag) { - if (gHudDisplay.coins == gCourseCompleteCoins && !(gCurrCourseStarFlags & starFlag) && gHudFlash == 0) { +void play_star_fanfare_and_flash_hud(s32 arg, u8 starNum) { + if (gHudDisplay.coins == gCourseCompleteCoins && (gCurrCourseStarFlags & starNum) == 0 && gHudFlash == HUD_FLASH_NONE) { play_star_fanfare(); gHudFlash = arg; } } -#ifdef VERSION_EU - #define TXT_NAME_X1 centerX - #define TXT_NAME_X2 centerX - 1 -#else - #define TXT_NAME_X1 71 - #define TXT_NAME_X2 TXT_NAME_X1 - 2 -#endif +LangArray textClear = DEFINE_LANGUAGE_ARRAY( + "CLEAR", + "CLEAR", + "CLEAR", + "クリア!"); -#if defined(VERSION_JP) || defined(VERSION_SH) - #define CRS_NUM_X2 95 - #define CRS_NUM_X3 CRS_NUM_X2 - 2 - #define TXT_CLEAR_X1 205 - #define TXT_CLEAR_X2 TXT_CLEAR_X1 - 2 -#else - #define CRS_NUM_X2 104 - #define CRS_NUM_X3 CRS_NUM_X2 - 2 - #define TXT_CLEAR_X1 get_string_width(name) + 81 - #define TXT_CLEAR_X2 TXT_CLEAR_X1 - 2 -#endif +#define COURSE_COMPLETE_COURSE_X 63 +#define COURSE_COMPLETE_COURSE_Y 167 +#define COURSE_COMPLETE_ACT_X 74 +#define COURSE_COMPLETE_ACT_Y 147 -void render_course_complete_lvl_info_and_hud_str(void) { -#if defined(VERSION_JP) - u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE }; - u8 textCourse[] = { TEXT_COURSE }; - u8 textCatch[] = { TEXT_CATCH }; - u8 textClear[] = { TEXT_CLEAR }; -#elif defined(VERSION_EU) - UNUSED u8 textCatch[] = { TEXT_CATCH }; // unused in EU - u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE }; -#else - u8 textCourse[] = { TEXT_COURSE }; - UNUSED u8 textCatch[] = { TEXT_CATCH }; // unused in US - UNUSED u8 textClear[] = { TEXT_CLEAR }; - u8 textSymStar[] = { GLYPH_STAR, GLYPH_SPACE }; -#endif +#define CONGRATULATIONS_COURSE_X 69 +#define CONGRATULATIONS_COURSE_Y 132 - void **actNameTbl; - void **courseNameTbl; - u8 *name; +#define COURSE_COMPLETE_COINS_X 118 +#define COURSE_COMPLETE_COINS_Y 103 +#define CONGRATULATIONS_COINS_Y 111 - u8 strCourseNum[4]; +void render_course_complete_lvl_info_and_hud_str(void) { + char *name; -#ifdef VERSION_EU - s16 centerX; - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#else - actNameTbl = segmented_to_virtual(seg2_act_name_table); - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#endif + char str[20]; + char courseNumText[8]; + + void **actNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][2]); + void **courseNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]); if (gLastCompletedCourseNum <= COURSE_STAGES_MAX) { // Main courses - print_hud_course_complete_coins(118, 103); - play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1)); + print_hud_course_complete_coins(COURSE_COMPLETE_COINS_X, COURSE_COMPLETE_COINS_Y); + play_star_fanfare_and_flash_hud(HUD_FLASH_STARS, (1 << (gLastCompletedStarNum - 1))); if (gLastCompletedStarNum == 7) { name = segmented_to_virtual(actNameTbl[COURSE_STAGES_MAX * 6 + 1]); @@ -2997,266 +2052,182 @@ void render_course_complete_lvl_info_and_hud_str(void) { // Print course number gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - int_to_str(gLastCompletedCourseNum, strCourseNum); - - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gMenuTextAlpha); - print_generic_string(65, 165, LANGUAGE_ARRAY(textCourse)); - print_generic_string(CRS_NUM_X2, 165, strCourseNum); + format_int_to_string(courseNumText, gLastCompletedCourseNum); + sprintf(str, LANG_ARRAY(textCourseX), courseNumText); + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + print_generic_string(COURSE_COMPLETE_COURSE_X + 2, COURSE_COMPLETE_COURSE_Y - 2, str); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); - print_generic_string(63, 167, LANGUAGE_ARRAY(textCourse)); - print_generic_string(CRS_NUM_X3, 167, strCourseNum); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string(COURSE_COMPLETE_COURSE_X, COURSE_COMPLETE_COURSE_Y, str); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } else if (gLastCompletedCourseNum == COURSE_BITDW || gLastCompletedCourseNum == COURSE_BITFS) { // Bowser courses name = segmented_to_virtual(courseNameTbl[COURSE_NUM_TO_INDEX(gLastCompletedCourseNum)]); + u32 clearX = get_string_width(name, main_font_lut, &main_font_utf8_lut) + COURSE_COMPLETE_COURSE_X + 16; // Print course name and clear text gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gMenuTextAlpha); -#ifdef VERSION_EU - centerX = get_str_x_pos_from_center(153, name, 12.0f); -#endif - print_generic_string(TXT_NAME_X1, 130, name); -#ifndef VERSION_EU - print_generic_string(TXT_CLEAR_X1, 130, textClear); -#endif - - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); - print_generic_string(TXT_NAME_X2, 132, name); -#ifndef VERSION_EU - print_generic_string(TXT_CLEAR_X2, 132, textClear); -#endif - + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + print_generic_string(CONGRATULATIONS_COURSE_X + 2, CONGRATULATIONS_COURSE_Y - 2, name); + print_generic_string(clearX + 2, CONGRATULATIONS_COURSE_Y - 2, LANG_ARRAY(textClear)); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string(CONGRATULATIONS_COURSE_X, CONGRATULATIONS_COURSE_Y, name); + print_generic_string(clearX, CONGRATULATIONS_COURSE_Y, LANG_ARRAY(textClear)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); print_hud_course_complete_string(HUD_PRINT_CONGRATULATIONS); - print_hud_course_complete_coins(118, 111); - play_star_fanfare_and_flash_hud(2, 0); //! 2 isn't defined, originally for key hud? - + print_hud_course_complete_coins(COURSE_COMPLETE_COINS_X, CONGRATULATIONS_COINS_Y); + play_star_fanfare_and_flash_hud(HUD_FLASH_KEYS, 0); return; } else { // Castle secret stars name = segmented_to_virtual(actNameTbl[COURSE_STAGES_MAX * 6]); - print_hud_course_complete_coins(118, 103); - play_star_fanfare_and_flash_hud(1, 1 << (gLastCompletedStarNum - 1)); + print_hud_course_complete_coins(COURSE_COMPLETE_COINS_X, COURSE_COMPLETE_COINS_Y); + play_star_fanfare_and_flash_hud(HUD_FLASH_STARS, 1 << (gLastCompletedStarNum - 1)); } // Print star glyph gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); - print_hud_lut_string(HUD_LUT_GLOBAL, 55, 77, textSymStar); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_hud_lut_string(COURSE_COMPLETE_ACT_X - 19, SCREEN_HEIGHT - COURSE_COMPLETE_ACT_Y - 16, "★"); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); // Print act name and catch text gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gMenuTextAlpha); - print_generic_string(76, 145, name); -#if defined(VERSION_JP) || defined(VERSION_SH) - print_generic_string(220, 145, textCatch); -#endif + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + print_generic_string(COURSE_COMPLETE_ACT_X + 2, COURSE_COMPLETE_ACT_Y - 2, name); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); - print_generic_string(74, 147, name); -#if defined(VERSION_JP) || defined(VERSION_SH) - print_generic_string(218, 147, textCatch); -#endif + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string(COURSE_COMPLETE_ACT_X, COURSE_COMPLETE_ACT_Y, name); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define X_VAL9 x - #define TXT_SAVEOPTIONS_X x + 10 - #define TXT_SAVECONT_Y +2-0 - #define TXT_SAVEQUIT_Y +2-20 - #ifdef TARGET_N64 - #define TXT_CONTNOSAVE_Y +2-40 - #else - #define TXT_SAVE_EXIT_GAME_Y +2-40 - #define TXT_CONTNOSAVE_Y +2-60 - #endif -#else -#ifdef VERSION_EU - #define X_VAL9 xOffset - 12 - #define TXT_SAVEOPTIONS_X xOffset -#else - #define X_VAL9 x - #define TXT_SAVEOPTIONS_X x + 12 -#endif - #define TXT_SAVECONT_Y 0 - #define TXT_SAVEQUIT_Y 20 - #ifdef TARGET_N64 - #define TXT_CONTNOSAVE_Y 40 - #else - #define TXT_SAVE_EXIT_GAME_Y 40 - #define TXT_CONTNOSAVE_Y 60 - #endif -#endif - -#ifndef TARGET_N64 -#define SAVE_CONFIRM_INDEX 4 // Increased to '4' to handle Exit Game -#else -#define SAVE_CONFIRM_INDEX 3 -#endif +LangArray textSaveAndContinue = DEFINE_LANGUAGE_ARRAY( + "SAVE & CONTINUE", + "SAUVEGARDER & CONTINUER", + "SPEICHERN & WEITER", + "セーブしてつづける?"); -#ifdef VERSION_EU -void render_save_confirmation(s16 y, s8 *index, s16 yOffset) -#else -void render_save_confirmation(s16 x, s16 y, s8 *index, s16 yOffset) -#endif -{ -#ifdef VERSION_EU - u8 textSaveAndContinue[][24] = { - { TEXT_SAVE_AND_CONTINUE }, - { TEXT_SAVE_AND_CONTINUE_FR }, - { TEXT_SAVE_AND_CONTINUE_DE } - }; - u8 textSaveAndQuit[][22] = { - { TEXT_SAVE_AND_QUIT }, - { TEXT_SAVE_AND_QUIT_FR }, - { TEXT_SAVE_AND_QUIT_DE } - }; - -#ifndef TARGET_N64 - u8 textSaveExitGame[][28] = { // New text to exit game - { TEXT_SAVE_EXIT_GAME }, - { TEXT_SAVE_EXIT_GAME_FR }, - { TEXT_SAVE_EXIT_GAME_DE } - }; -#endif +LangArray textSaveAndQuit = DEFINE_LANGUAGE_ARRAY( + "SAVE & QUIT", + "SAUVEGARDER & QUITTER", + "SPEICHERN & ENDE", + "セーブしておわる?"); - u8 textContinueWithoutSave[][27] = { - { TEXT_CONTINUE_WITHOUT_SAVING }, - { TEXT_CONTINUE_WITHOUT_SAVING_FR }, - { TEXT_CONTINUE_WITHOUT_SAVING_DE } - }; - s16 xOffset = get_str_x_pos_from_center(160, LANGUAGE_ARRAY(textContinueWithoutSave), 12.0f); -#else - u8 textSaveAndContinue[] = { TEXT_SAVE_AND_CONTINUE }; - u8 textSaveAndQuit[] = { TEXT_SAVE_AND_QUIT }; -#ifndef TARGET_N64 - u8 textSaveExitGame[] = { TEXT_SAVE_EXIT_GAME }; // New text to exit game -#endif - u8 textContinueWithoutSave[] = { TEXT_CONTINUE_WITHOUT_SAVING }; -#endif +LangArray textContinueWithoutSave = DEFINE_LANGUAGE_ARRAY( + "CONTINUE, DON'T SAVE", + "CONTINUER SANS SAUVEGARDER", + "WEITER OHNE ZU SPEICHERN", + "セーブしないでつづける?"); - handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, SAVE_CONFIRM_INDEX); +void render_save_confirmation(s16 x, s16 y, s8 *index, s16 yPos) { + handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 3); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - print_generic_string(TXT_SAVEOPTIONS_X, y + TXT_SAVECONT_Y, LANGUAGE_ARRAY(textSaveAndContinue)); - print_generic_string(TXT_SAVEOPTIONS_X, y - TXT_SAVEQUIT_Y, LANGUAGE_ARRAY(textSaveAndQuit)); -#ifndef TARGET_N64 - print_generic_string(TXT_SAVEOPTIONS_X, y - TXT_SAVE_EXIT_GAME_Y, LANGUAGE_ARRAY(textSaveExitGame)); -#endif - print_generic_string(TXT_SAVEOPTIONS_X, y - TXT_CONTNOSAVE_Y, LANGUAGE_ARRAY(textContinueWithoutSave)); + print_generic_string(x + 12, y, LANG_ARRAY(textSaveAndContinue)); + print_generic_string(x + 12, y - 20, LANG_ARRAY(textSaveAndQuit)); + print_generic_string(x + 12, y - 40, LANG_ARRAY(textContinueWithoutSave)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL9, y - ((*index - 1) * yOffset), 0); + create_dl_translation_matrix(MENU_MTX_PUSH, x, y - ((*index - 1) * yPos), 0); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gMenuTextAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } -#undef SAVE_CONFIRM_INDEX -s16 render_course_complete_screen(void) { - s16 index; -#ifdef VERSION_EU - gInGameLanguage = eu_get_language(); +// Save option strings are longer in French, so render them further to the left. +#define SAVE_CONFIRMATION_X_EN 100 +#define SAVE_CONFIRMATION_X_FR 80 + +#ifdef ENABLE_FRENCH +#define SAVE_CONFIRMATION_X ((gInGameLanguage == LANGUAGE_FRENCH) ? SAVE_CONFIRMATION_X_FR : SAVE_CONFIRMATION_X_EN) +#else +#define SAVE_CONFIRMATION_X SAVE_CONFIRMATION_X_EN #endif - switch (gMenuState) { - case MENU_STATE_COURSE_COMPLETE_SCREEN_OPENING: +s32 render_course_complete_screen(void) { + switch (gDialogBoxState) { + case DIALOG_STATE_OPENING: render_course_complete_lvl_info_and_hud_str(); - if (gCourseCompleteScreenTimer > 100 && gCourseCompleteCoinsEqual == TRUE) { - gMenuState = MENU_STATE_COURSE_COMPLETE_SCREEN_OPEN; + if (gCourseDoneMenuTimer > 100 && gCourseCompleteCoinsEqual) { + gDialogBoxState = DIALOG_STATE_VERTICAL; level_set_transition(-1, NULL); - gMenuTextAlpha = 0; - gMenuLineNum = MENU_OPT_DEFAULT; + gDialogTextAlpha = 0; + gDialogLineNum = MENU_OPT_DEFAULT; } break; - case MENU_STATE_COURSE_COMPLETE_SCREEN_OPEN: + case DIALOG_STATE_VERTICAL: shade_screen(); render_course_complete_lvl_info_and_hud_str(); -#ifdef VERSION_EU - render_save_confirmation(86, &gMenuLineNum, 20); -#else - render_save_confirmation(100, 86, &gMenuLineNum, 20); -#endif + render_save_confirmation(SAVE_CONFIRMATION_X, 86, &gDialogLineNum, 20); - if (gCourseCompleteScreenTimer > 110 - && (gPlayer3Controller->buttonPressed & A_BUTTON - || gPlayer3Controller->buttonPressed & START_BUTTON -#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION - || gPlayer3Controller->buttonPressed & Z_TRIG -#endif - )) { + if (gCourseDoneMenuTimer > 110 && (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON))) { level_set_transition(0, NULL); play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); - gMenuState = MENU_STATE_DEFAULT; + gDialogBoxState = DIALOG_STATE_OPENING; gMenuMode = MENU_MODE_NONE; - index = gMenuLineNum; - gCourseCompleteScreenTimer = 0; + gCourseDoneMenuTimer = 0; gCourseCompleteCoins = 0; gCourseCompleteCoinsEqual = FALSE; - gHudFlash = 0; + gHudFlash = HUD_FLASH_NONE; - return index; + return gDialogLineNum; } break; } - if (gMenuTextAlpha < 250) { - gMenuTextAlpha += 25; + if (gDialogTextAlpha < 250) { + gDialogTextAlpha += 25; } - gCourseCompleteScreenTimer++; + gCourseDoneMenuTimer++; return MENU_OPT_NONE; } -s16 render_menus_and_dialogs(void) { - s16 index = MENU_OPT_NONE; +s32 render_menus_and_dialogs(void) { + s32 mode = MENU_OPT_NONE; create_dl_ortho_matrix(); if (gMenuMode != MENU_MODE_NONE) { switch (gMenuMode) { case MENU_MODE_UNUSED_0: - index = render_pause_screen(); + mode = render_pause_courses_and_castle(); break; case MENU_MODE_RENDER_PAUSE_SCREEN: - index = render_pause_screen(); + mode = render_pause_courses_and_castle(); break; case MENU_MODE_RENDER_COURSE_COMPLETE_SCREEN: - index = render_course_complete_screen(); + mode = render_course_complete_screen(); break; case MENU_MODE_UNUSED_3: - index = render_course_complete_screen(); + mode = render_course_complete_screen(); break; } - gMenuTextColorTransTimer = (s16) gMenuTextColorTransTimer + 0x1000; + gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000; } else if (gDialogID != DIALOG_NONE) { // The Peach "Dear Mario" message needs to be repositioned separately if (gDialogID == DIALOG_020) { print_peach_letter_message(); - return index; + return mode; } render_dialog_entries(); - gMenuTextColorTransTimer = (s16) gMenuTextColorTransTimer + 0x1000; + gDialogColorFadeTimer = (s16) gDialogColorFadeTimer + 0x1000; } - return index; + return mode; } diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index 9357a9b07..df0f4a05d 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -2,39 +2,19 @@ #define INGAME_MENU_H #include +#include "types.h" -#define ASCII_TO_DIALOG(asc) \ - (((asc) >= '0' && (asc) <= '9') ? ((asc) - '0') : \ - ((asc) >= 'A' && (asc) <= 'Z') ? ((asc) - 'A' + 0x0A) : \ - ((asc) >= 'a' && (asc) <= 'z') ? ((asc) - 'a' + 0x24) : 0x00) - - -#define MENU_MTX_PUSH 1 -#define MENU_MTX_NOPUSH 2 - -#define MENU_SCROLL_VERTICAL 1 -#define MENU_SCROLL_HORIZONTAL 2 - -// Japanese File Select uses an unique table -// to print specific Japanese HUD chars -#define HUD_LUT_JPMENU 1 -#define HUD_LUT_GLOBAL 2 - -// For file select JP HUD difference -#if defined(VERSION_JP) || defined(VERSION_SH) -#define HUD_LUT_DIFF HUD_LUT_JPMENU -#else -#define HUD_LUT_DIFF HUD_LUT_GLOBAL -#endif - -// Japanese font use the same width string size -#define JP_DIALOG_CHAR_WIDTH 10 +enum MenuMtxPushOp { + MENU_MTX_NONE, + MENU_MTX_PUSH, + MENU_MTX_NOPUSH, +}; -#ifdef VERSION_JP -#define HUD_LUT_STRIDE_GLOBAL 14 -#else -#define HUD_LUT_STRIDE_GLOBAL 12 -#endif +enum MenuScrollAxis { + MENU_SCROLL_NONE, + MENU_SCROLL_VERTICAL, + MENU_SCROLL_HORIZONTAL, +}; enum MenuMode { MENU_MODE_NONE = -1, @@ -44,84 +24,91 @@ enum MenuMode { MENU_MODE_UNUSED_3 }; -extern s8 gDialogCourseActNum; +enum HUDFlashModes { + HUD_FLASH_NONE, + HUD_FLASH_STARS, + HUD_FLASH_KEYS +}; + extern s8 gHudFlash; -struct DialogEntry { - /*0x00*/ u32 unused; - /*0x04*/ s8 linesPerBox; - /*0x06*/ s16 leftOffset; - /*0x08*/ s16 width; - /*0x0C*/ const u8 *str; +extern s8 gDialogCourseActNum; +extern u8 gInGameLanguage; +extern void *languageTable[][3]; + +struct AsciiCharLUTEntry { + const Texture *texture; + const s8 kerning; }; -// EU only -enum HudSpecialHUDChars { - HUD_CHAR_A_UMLAUT = 0x3A, - HUD_CHAR_O_UMLAUT = 0x3B, - HUD_CHAR_U_UMLAUT = 0x3C +// Convert an ASCII char to the index in the ASCII LUT. ASCII LUTs start at the space character. +#define ASCII_LUT_INDEX(c) ((c) - ' ') + +// Macro to quickly get the kerning of the space character from an ASCII LUT. +#define SPACE_KERNING(lut) (((struct AsciiCharLUTEntry *)(lut))[ASCII_LUT_INDEX(' ')].kerning) + +// The character used to indicate a color code in a generic string. +// As of now, must be an ASCII character. +#define CHAR_COLOR_CODE '@' + +struct Utf8CharLUTEntry { + u32 codepoint; + s8 kerning; + u16 flags; // used for diacritics and packed textures + Texture *texture; }; -enum SpecialFontChars { - GLOBAL_CHAR_SPACE = 0x9E, - GLOBAL_CHAR_TERMINATOR = 0xFF +struct Utf8LUT { + struct Utf8CharLUTEntry *lut2Bytes; + struct Utf8CharLUTEntry *lut3Bytes; + struct Utf8CharLUTEntry *lut4Bytes; + u16 length2Bytes; // set these with the ARRAY_COUNT macro + u16 length3Bytes; + u16 length4Bytes; + struct Utf8CharLUTEntry *missingChar; }; -enum DialogMark { - DIALOG_MARK_NONE, - DIALOG_MARK_DAKUTEN, - DIALOG_MARK_HANDAKUTEN +struct DiacriticLUTEntry { + s8 xOffset; + s8 yOffset; + char *str; }; -// definitions for some of the special characters defined in charmap.txt -enum DialogSpecialChars { -#ifdef VERSION_EU - DIALOG_CHAR_LOWER_A_GRAVE = 0x60, // 'a' grave - DIALOG_CHAR_LOWER_A_CIRCUMFLEX = 0x61, // 'a' circumflex - DIALOG_CHAR_LOWER_A_UMLAUT = 0x62, // 'a' umlaut - DIALOG_CHAR_UPPER_A_GRAVE = 0x64, // 'A' grave - DIALOG_CHAR_UPPER_A_CIRCUMFLEX = 0x65, // 'A' circumflex - DIALOG_CHAR_UPPER_A_UMLAUT = 0x66, // 'A' umlaut - DIALOG_CHAR_LOWER_E_GRAVE = 0x70, // 'e' grave - DIALOG_CHAR_LOWER_E_CIRCUMFLEX = 0x71, // 'e' circumflex - DIALOG_CHAR_LOWER_E_UMLAUT = 0x72, // 'e' umlaut - DIALOG_CHAR_LOWER_E_ACUTE = 0x73, // 'e' acute - DIALOG_CHAR_UPPER_E_GRAVE = 0x74, // 'E' grave - DIALOG_CHAR_UPPER_E_CIRCUMFLEX = 0x75, // 'E' circumflex - DIALOG_CHAR_UPPER_E_UMLAUT = 0x76, // 'E' umlaut - DIALOG_CHAR_UPPER_E_ACUTE = 0x77, // 'E' acute - DIALOG_CHAR_LOWER_U_GRAVE = 0x80, // 'u' grave - DIALOG_CHAR_LOWER_U_CIRCUMFLEX = 0x81, // 'u' circumflex - DIALOG_CHAR_LOWER_U_UMLAUT = 0x82, // 'u' umlaut - DIALOG_CHAR_UPPER_U_GRAVE = 0x84, // 'U' grave - DIALOG_CHAR_UPPER_U_CIRCUMFLEX = 0x85, // 'U' circumflex - DIALOG_CHAR_UPPER_U_UMLAUT = 0x86, // 'U' umlaut - DIALOG_CHAR_LOWER_O_CIRCUMFLEX = 0x91, // 'o' circumflex - DIALOG_CHAR_LOWER_O_UMLAUT = 0x92, // 'o' umlaut - DIALOG_CHAR_UPPER_O_CIRCUMFLEX = 0x95, // 'O' circumflex - DIALOG_CHAR_UPPER_O_UMLAUT = 0x96, // 'O' umlaut - DIALOG_CHAR_LOWER_I_CIRCUMFLEX = 0xA1, // 'i' circumflex - DIALOG_CHAR_LOWER_I_UMLAUT = 0xA2, // 'i' umlaut - DIALOG_CHAR_I_NO_DIA = 0xEB, // 'i' without diacritic - DIALOG_CHAR_DOUBLE_LOW_QUOTE = 0xF0, // German opening quotation mark +enum TextDiacriticMarks { + TEXT_DIACRITIC_NONE, + TEXT_DIACRITIC_CIRCUMFLEX, + TEXT_DIACRITIC_CIRCUMFLEX_UPPERCASE, + TEXT_DIACRITIC_ACUTE, + TEXT_DIACRITIC_ACUTE_UPPERCASE, + TEXT_DIACRITIC_GRAVE, + TEXT_DIACRITIC_GRAVE_UPPERCASE, + TEXT_DIACRITIC_TILDE, + TEXT_DIACRITIC_TILDE_UPPERCASE, + TEXT_DIACRITIC_UMLAUT, + TEXT_DIACRITIC_UMLAUT_UPPERCASE, + TEXT_DIACRITIC_CEDILLA, +#ifdef JAPANESE_CHARACTERS + TEXT_DIACRITIC_DAKUTEN, + TEXT_DIACRITIC_HANDAKUTEN, #endif -#if defined(VERSION_US) || defined(VERSION_EU) - DIALOG_CHAR_SLASH = 0xD0, - DIALOG_CHAR_MULTI_THE = 0xD1, // 'the' - DIALOG_CHAR_MULTI_YOU = 0xD2, // 'you' -#endif - DIALOG_CHAR_PERIOD = 0x6E, - DIALOG_CHAR_COMMA = 0x6F, - DIALOG_CHAR_SPACE = 0x9E, - DIALOG_CHAR_STAR_COUNT = 0xE0, // number of stars - DIALOG_CHAR_UMLAUT = 0xE9, - DIALOG_CHAR_MARK_START = 0xEF, - DIALOG_CHAR_DAKUTEN = DIALOG_CHAR_MARK_START + DIALOG_MARK_DAKUTEN, - DIALOG_CHAR_PERIOD_OR_HANDAKUTEN = DIALOG_CHAR_MARK_START + DIALOG_MARK_HANDAKUTEN, - DIALOG_CHAR_STAR_FILLED = 0xFA, - DIALOG_CHAR_STAR_OPEN = 0xFD, - DIALOG_CHAR_NEWLINE = 0xFE, - DIALOG_CHAR_TERMINATOR = 0xFF +}; + +enum TextAlignments { + TEXT_ALIGN_LEFT, + TEXT_ALIGN_CENTER, + TEXT_ALIGN_RIGHT, +}; + +#define TEXT_FLAG_PACKED 0x8000 +#define TEXT_DIACRITIC_MASK 0x00FF +// bits 0x0100 through 0x4000 are free for use, and the mask can be reduced if necessary + +struct DialogEntry { + /*0x00*/ s32 voice; + /*0x04*/ s8 linesPerBox; + /*0x06*/ s16 leftOffset; + /*0x08*/ s16 width; + /*0x0C*/ const char *str; }; // gDialogResponse @@ -129,42 +116,81 @@ enum DialogResponseDefines { DIALOG_RESPONSE_NONE, DIALOG_RESPONSE_YES, DIALOG_RESPONSE_NO, - DIALOG_RESPONSE_NOT_DEFINED + DIALOG_RESPONSE_NOT_DEFINED, + DIALOG_RESPONSE_MAXIMUM = 32 }; +// Types and defines for handling language arrays +#ifdef MULTILANG + +enum MultilangLanguages { + LANGUAGE_ENGLISH, + LANGUAGE_FRENCH, + LANGUAGE_GERMAN, + LANGUAGE_JAPANESE, + LANGUAGE_COUNT +}; + +typedef char * LangArray[LANGUAGE_COUNT]; +#define LANG_ARRAY(cmd) ((cmd)[gInGameLanguage]) +#define DEFINE_LANGUAGE_ARRAY(english, french, german, japanese) {english, french, german, japanese} + +#else + +// If multilang is off, ignore all other languages and only include English. +#define LANGUAGE_ENGLISH 0 + +typedef char * LangArray; +#define LANG_ARRAY(cmd) (cmd) +#define DEFINE_LANGUAGE_ARRAY(english, french, german, japanese) english + +#endif + +typedef union { + s32 asInt; + char *asStr; +} DialogVariable; + extern s32 gDialogResponse; -extern u16 gMenuTextColorTransTimer; -extern s8 gLastDialogLineNum; -extern s32 gDialogVariable; -extern u16 gMenuTextAlpha; -extern s16 gCutsceneMsgXOffset; -extern s16 gCutsceneMsgYOffset; -extern s8 gRedCoinsCollected; +extern u16 gDialogColorFadeTimer; +extern s8 gLastDialogLineNum; +extern DialogVariable gDialogVariable; +extern u16 gDialogTextAlpha; +extern s8 gRedCoinsCollected; + +/* + * Regarding get_str_x_pos_from_center / get_str_x_pos_from_center_scale: + * They cannot use a macro due to the new print_generic_string function. + * Instead as a replacement you can use print_generic_string_aligned and + * set TEXT_ALIGN_CENTER as it's alignment value. +*/ + +u8 check_number_string_in_course_name(char *courseName); void create_dl_identity_matrix(void); void create_dl_translation_matrix(s8 pushOp, f32 x, f32 y, f32 z); -void create_dl_rotation_matrix(s8 pushOp, f32 a, f32 x, f32 y, f32 z); -void create_dl_scale_matrix(s8 pushOp, f32 x, f32 y, f32 z); void create_dl_ortho_matrix(void); -void print_generic_string(s16 x, s16 y, const u8 *str); -void print_hud_lut_string(s8 hudLUT, s16 x, s16 y, const u8 *str); -void print_menu_generic_string(s16 x, s16 y, const u8 *str); +void create_dl_scale_matrix(s8 pushOp, f32 x, f32 y, f32 z); + +s32 get_string_width(char *str, struct AsciiCharLUTEntry *asciiLut, struct Utf8LUT *utf8LUT); +void format_int_to_string(char *buf, s32 value); +#define int_to_str(int, str) format_int_to_string(str, int); // backwards compatibility +void print_generic_string(s16 x, s16 y, char *str); +void print_hud_lut_string(s16 x, s16 y, char *str); +void print_menu_generic_string(s16 x, s16 y, char *str); +void print_credits_string(s16 x, s16 y, char *str); +void print_generic_string_aligned(s16 x, s16 y, char *str, u32 alignment); +void print_hud_lut_string_aligned(s16 x, s16 y, char *str, u32 alignment); +void print_menu_generic_string_aligned(s16 x, s16 y, char *str, u32 alignment); +void print_credits_string_aligned(s16 x, s16 y, char *str, u32 alignment); + void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8 maxIndex); -#if defined(VERSION_US) || defined(VERSION_EU) -s16 get_str_x_pos_from_center(s16 centerPos, u8 *str, f32 scale); -#endif -#if defined(VERSION_JP) || defined(VERSION_SH) -#define get_str_x_pos_from_center get_str_x_pos_from_center_scale -#endif -#if defined(VERSION_JP) || defined(VERSION_EU) || defined(VERSION_SH) -s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale); -#endif -s16 get_string_width(u8 *str); void print_hud_my_score_coins(s32 useCourseCoinScore, s8 fileIndex, s8 courseIndex, s16 x, s16 y); -void int_to_str(s32 num, u8 *dst); -s16 get_dialog_id(void); +s32 get_dialog_id(void); void create_dialog_box(s16 dialog); -void create_dialog_box_with_var(s16 dialog, s32 dialogVar); +void create_dialog_box_with_int_var(s16 dialog, s32 dialogVar); +void create_dialog_box_with_str_var(s16 dialog, char *dialogVar); +void create_dialog_box_with_var(s16 dialog, DialogVariable dialogVar); void create_dialog_inverted_box(s16 dialog); void create_dialog_box_with_response(s16 dialog); void reset_dialog_render_state(void); @@ -172,11 +198,10 @@ void set_menu_mode(s16 mode); void reset_cutscene_msg_fade(void); void dl_rgba16_begin_cutscene_msg_fade(void); void dl_rgba16_stop_cutscene_msg_fade(void); -void print_credits_str_ascii(s16 x, s16 y, const char *str); -void set_cutscene_message(s16 xOffset, s16 yOffset, s16 msgIndex, s16 msgDuration); +void set_cutscene_message(s16 msgIndex, s16 msgDuration); void do_cutscene_handler(void); void render_hud_cannon_reticle(void); void reset_red_coins_collected(void); -s16 render_menus_and_dialogs(void); +s32 render_menus_and_dialogs(void); #endif // INGAME_MENU_H diff --git a/src/game/level_update.c b/src/game/level_update.c index a0d76e583..a89ad115d 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -24,9 +24,8 @@ #include "save_file.h" #include "debug_course.h" #include "interaction.h" -#ifdef VERSION_EU +#ifdef MULTILANG #include "memory.h" -#include "eu_translation.h" #include "segment_symbols.h" #endif #include "level_table.h" @@ -1329,23 +1328,34 @@ s32 lvl_init_or_update(s16 initOrUpdate, UNUSED s32 unused) { return result; } -s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) { -#ifdef VERSION_EU - s16 language = eu_get_language(); - switch (language) { +#ifdef MULTILANG +void load_language_text(void) { + switch (gInGameLanguage) { case LANGUAGE_ENGLISH: - load_segment_decompress(0x19, _translation_en_mio0SegmentRomStart, - _translation_en_mio0SegmentRomEnd); + load_segment_decompress(SEGMENT_EU_TRANSLATION, _translation_en_yay0SegmentRomStart, _translation_en_yay0SegmentRomEnd); break; +#ifdef ENABLE_FRENCH case LANGUAGE_FRENCH: - load_segment_decompress(0x19, _translation_fr_mio0SegmentRomStart, - _translation_fr_mio0SegmentRomEnd); + load_segment_decompress(SEGMENT_EU_TRANSLATION, _translation_fr_yay0SegmentRomStart, _translation_fr_yay0SegmentRomEnd); break; +#endif +#ifdef ENABLE_GERMAN case LANGUAGE_GERMAN: - load_segment_decompress(0x19, _translation_de_mio0SegmentRomStart, - _translation_de_mio0SegmentRomEnd); + load_segment_decompress(SEGMENT_EU_TRANSLATION, _translation_de_yay0SegmentRomStart, _translation_de_yay0SegmentRomEnd); break; +#endif +#ifdef ENABLE_JAPANESE + case LANGUAGE_JAPANESE: + load_segment_decompress(SEGMENT_EU_TRANSLATION, _translation_jp_yay0SegmentRomStart, _translation_jp_yay0SegmentRomEnd); + break; +#endif } +} +#endif + +s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) { +#ifdef MULTILANG + load_language_text(); #endif sWarpDest.type = WARP_TYPE_NOT_WARPING; sDelayedWarpOp = WARP_OP_NONE; diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 73227cc92..b50cb7a01 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -84,40 +84,20 @@ static Vec4s sJumboStarKeyframes[27] = { { 0, -3500, 2100, -2000 }, { 0, -2000, 2200, -3500 }, { 0, 0, 2300, -4000 }, }; -#if !CREDITS_TEXT_STRING_FONT -/** - * get_credits_str_width: Calculate width of a Credits String - * Loop over each character in a credits string and increment the length. If the - * character is a space, increment by 4; otherwise increment by 7. Once the next - * character is a null character (equal to 0), stop counting the length since - * that's the end of the string. - */ -s32 get_credits_str_width(char *str) { - u32 c; - s32 length = 0; - - while ((c = *str++) != 0) { - length += (c == ' ' ? 4 : 7); - } - - return length; -} -#endif - #define CREDIT_TEXT_MARGIN_X ((s32)(GFX_DIMENSIONS_ASPECT_RATIO * 21)) #define CREDIT_TEXT_X_LEFT GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(CREDIT_TEXT_MARGIN_X) #define CREDIT_TEXT_X_RIGHT GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(CREDIT_TEXT_MARGIN_X) #if CREDITS_TEXT_STRING_FONT #include "extras/draw_util.h" -#define PRINT_CREDITS(x, y, str) print_generic_string_ascii(x, y, str) -#define STRING_WIDTH(str) get_string_width_ascii(str) +#define PRINT_CREDITS(x, y, str) print_generic_string(x, y, str) +#define PRINT_CREDITS_ALIGNED(x, y, str, alignment) print_generic_string_aligned(x, y, str, alignment) #define ADD_OR_SUB(a, b) (a - b) #define INIT_Y_UP 196 #define INIT_Y_DOWN 52 #else -#define PRINT_CREDITS(x, y, str) print_credits_str_ascii(x, y, str) -#define STRING_WIDTH(str) get_credits_str_width(str) +#define PRINT_CREDITS(x, y, str) print_credits_string(x, y, str) +#define PRINT_CREDITS_ALIGNED(x, y, str, alignment) print_credits_string_aligned(x, y, str, alignment) #define ADD_OR_SUB(a, b) (a + b) #define INIT_Y_UP 28 #define INIT_Y_DOWN 172 @@ -175,7 +155,7 @@ void print_displaying_credits_entry(void) { } while (numLines-- > 0) { - PRINT_CREDITS(CREDIT_TEXT_X_RIGHT - STRING_WIDTH(*currStrPtr), strY, *currStrPtr); + PRINT_CREDITS_ALIGNED(CREDIT_TEXT_X_RIGHT, strY, *currStrPtr, TEXT_ALIGN_RIGHT); #if CREDITS_TEXT_STRING_FONT strY -= lineHeight; #else @@ -189,7 +169,7 @@ void print_displaying_credits_entry(void) { } } #undef PRINT_CREDITS -#undef STRING_WIDTH +#undef PRINT_CREDITS_ALIGNED #undef ADD_OR_SUB #undef INIT_Y_UP #undef INIT_Y_DOWN @@ -496,7 +476,7 @@ s32 act_reading_automatic_dialog(struct MarioState *m) { if (GET_HIGH_U16_OF_32(actionArg) == 0) { create_dialog_box(GET_LOW_U16_OF_32(actionArg)); } else { - create_dialog_box_with_var(GET_HIGH_U16_OF_32(actionArg), GET_LOW_U16_OF_32(actionArg)); + create_dialog_box_with_int_var(GET_HIGH_U16_OF_32(actionArg), GET_LOW_U16_OF_32(actionArg)); } } // wait until dialog is done @@ -2406,7 +2386,7 @@ static void end_peach_cutscene_dialog_1(struct MarioState *m) { #else case 230: #endif - set_cutscene_message(160, 227, 0, 30); + set_cutscene_message(0, 30); #ifndef VERSION_JP seq_player_lower_volume(SEQ_PLAYER_LEVEL, 60, 40); play_sound(SOUND_PEACH_MARIO, sEndPeachObj->header.gfx.cameraToObject); @@ -2427,7 +2407,7 @@ static void end_peach_cutscene_dialog_1(struct MarioState *m) { #else case 290: #endif - set_cutscene_message(160, 227, 1, 60); + set_cutscene_message(1, 60); #ifndef VERSION_JP play_sound(SOUND_PEACH_POWER_OF_THE_STARS, sEndPeachObj->header.gfx.cameraToObject); #endif @@ -2467,7 +2447,7 @@ static void end_peach_cutscene_dialog_2(struct MarioState *m) { #else case 29: #endif - set_cutscene_message(160, 227, 2, 30); + set_cutscene_message(2, 30); #ifndef VERSION_JP play_sound(SOUND_PEACH_THANKS_TO_YOU, sEndPeachObj->header.gfx.cameraToObject); #endif @@ -2486,14 +2466,14 @@ static void end_peach_cutscene_dialog_2(struct MarioState *m) { #else case 75: #endif - set_cutscene_message(160, 227, 3, 30); + set_cutscene_message(3, 30); #ifndef VERSION_JP play_sound(SOUND_PEACH_THANK_YOU_MARIO, sEndPeachObj->header.gfx.cameraToObject); #endif break; case TIMER_SOMETHING_SPECIAL: - set_cutscene_message(160, 227, 4, 40); + set_cutscene_message(4, 40); #ifndef VERSION_JP play_sound(SOUND_PEACH_SOMETHING_SPECIAL, sEndPeachObj->header.gfx.cameraToObject); #endif @@ -2624,18 +2604,18 @@ static void end_peach_cutscene_dialog_3(struct MarioState *m) { sEndToadAnims[0] = 0; sEndToadAnims[1] = 2; D_8032CBE8 = 1; - set_cutscene_message(160, 227, 5, 30); + set_cutscene_message(5, 30); #ifndef VERSION_JP play_sound(SOUND_PEACH_BAKE_A_CAKE, sEndPeachObj->header.gfx.cameraToObject); #endif break; case 55: - set_cutscene_message(160, 227, 6, 40); + set_cutscene_message(6, 40); break; case 130: - set_cutscene_message(160, 227, 7, 50); + set_cutscene_message(7, 50); #ifndef VERSION_JP play_sound(SOUND_PEACH_FOR_MARIO, sEndPeachObj->header.gfx.cameraToObject); #endif @@ -2659,7 +2639,7 @@ static void end_peach_cutscene_run_to_castle(struct MarioState *m) { } if (m->actionTimer == 95) { - set_cutscene_message(160, 227, 0, 40); + set_cutscene_message(0, 40); #ifndef VERSION_JP play_sound(SOUND_PEACH_MARIO2, sEndPeachObj->header.gfx.cameraToObject); #endif diff --git a/src/game/print.c b/src/game/print.c index 3269ec3f5..254ce59f2 100644 --- a/src/game/print.c +++ b/src/game/print.c @@ -1,229 +1,47 @@ -#include -#include +#include #include "config.h" #include "game_init.h" #include "memory.h" #include "print.h" #include "segment2.h" +#include "ingame_menu.h" /** * This file handles printing and formatting the colorful text that * appears when printing things such as "PRESS START". */ +// The maximum number of characters in a single text label. +#define MAX_TEXT_LABEL_SIZE 50 + struct TextLabel { u32 x; u32 y; - s16 length; - char buffer[50]; + char buffer[MAX_TEXT_LABEL_SIZE]; }; /** * Stores the text to be rendered on screen * and how they are to be rendered. */ -struct TextLabel *sTextLabels[256]; +struct TextLabel *sTextLabels[52]; s16 sTextLabelsCount = 0; /** - * Returns n to the exponent power, only for non-negative powers. - */ -s32 int_pow(s32 n, s32 exponent) { - s32 result = 1; - s32 i; - - for (i = 0; i < exponent; i++) { - result = n * result; - } - - return result; -} - -/** - * Formats an integer n for print by fitting it to width, prefixing with a negative, - * and converting the base. - */ -void format_integer(s32 n, s32 base, char *dest, s32 *totalLength, u8 width, s8 zeroPad) { - u32 powBase; - s32 numDigits = 0; - s32 i; - s32 len = 0; - s8 digit; - s8 negative = FALSE; - char pad; - - if (zeroPad == TRUE) { - pad = '0'; - } else { - pad = -1; - } - - if (n != 0) { - // Formats a negative number for negative prefix. - if (n < 0) { - n = -n; - negative = TRUE; - } - - // Increments the number of digits until length is long enough. - while (TRUE) { - powBase = int_pow(base, numDigits); - - if (powBase > (u32) n) { - break; - } - - numDigits++; - } - - // Add leading pad to fit width. - if (width > numDigits) { - for (len = 0; len < width - numDigits; len++) dest[len] = pad; - - // Needs 1 length to print negative prefix. - if (negative == TRUE) { - len--; - } - } - - // Use 'M' prefix to indicate negative numbers. - if (negative == TRUE) { - dest[len] = 'M'; - len++; - } - - // Transfer the digits into the proper base. - for (i = numDigits - 1; i >= 0; i--) { - powBase = int_pow(base, i); - digit = n / powBase; - - // FIXME: Why doesn't [] match? - if (digit < 10) { - *(dest + len + numDigits - 1 - i) = digit + '0'; - } else { - *(dest + len + numDigits - 1 - i) = digit + '7'; - } - - n -= digit * powBase; - } - } else { // n is zero. - numDigits = 1; - if (width > numDigits) { - for (len = 0; len < width - numDigits; len++) dest[len] = pad; - } - dest[len] = '0'; - } - - *totalLength += numDigits + len; -} - -/** - * Determines the width of the number for printing, writing to 'width'. - * Additionally, this determines if a number should be zero-padded, - * writing to 'zeroPad'. - */ -void parse_width_field(const char *str, s32 *srcIndex, u8 *width, s8 *zeroPad) { - s8 digits[12]; // unknown length - s8 digitsLen = 0; - s16 i; - - // If first character is 0, then the string should be zero padded. - if (str[*srcIndex] == '0') { - *zeroPad = TRUE; - } - - // Read width digits up until the 'd' or 'x' format specifier. - while (str[*srcIndex] != 'd' && str[*srcIndex] != 'x') { - digits[digitsLen] = str[*srcIndex] - '0'; - - if (digits[digitsLen] < 0 || digits[digitsLen] >= 10) { // not a valid digit - *width = 0; - return; - } - - digitsLen++; - (*srcIndex)++; - } - - // No digits - if (digitsLen == 0) { - return; - } - - // Sum the digits to calculate the total width. - for (i = 0; i < digitsLen - 1; i++) { - *width = *width + digits[i] * ((digitsLen - i - 1) * 10); - } - - *width = *width + digits[digitsLen - 1]; -} - -/** - * Takes a number, finds the intended base, formats the number, and prints it + * Takes a number, formats the number, and prints it * at the given X & Y coordinates. - * - * Warning: this fails on too large numbers, because format_integer has bugs - * related to overflow. For romhacks, prefer sprintf + print_text. */ -void print_text_fmt_int(s32 x, s32 y, const char *str, s32 n) { - char c = 0; - s8 zeroPad = FALSE; - u8 width = 0; - s32 base = 0; - s32 len = 0; - s32 srcIndex = 0; - - // Don't continue if there is no memory to do so. - if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool, - sizeof(struct TextLabel))) == NULL) { - return; - } - - sTextLabels[sTextLabelsCount]->x = x; - sTextLabels[sTextLabelsCount]->y = y; - - c = str[srcIndex]; - - while (c != '\0') { - if (c == '%') { - srcIndex++; - - parse_width_field(str, &srcIndex, &width, &zeroPad); - - if (str[srcIndex] != 'd' && str[srcIndex] != 'x') { - break; - } - if (str[srcIndex] == 'd') { - base = 10; - } - if (str[srcIndex] == 'x') { - base = 16; - } - - srcIndex++; - - format_integer(n, base, sTextLabels[sTextLabelsCount]->buffer + len, &len, width, zeroPad); - } else { // straight copy - sTextLabels[sTextLabelsCount]->buffer[len] = c; - len++; - srcIndex++; - } - c = str[srcIndex]; - } - - sTextLabels[sTextLabelsCount]->length = len; - sTextLabelsCount++; +void print_text_fmt_int(s32 x, s32 y, char *str, s32 n) { + char buffer[MAX_TEXT_LABEL_SIZE]; + sprintf(buffer, str, n); + print_text(x, y, buffer); } /** * Prints text in the colorful lettering at given X, Y coordinates. */ -void print_text(s32 x, s32 y, const char *str) { - char c = 0; - s32 length = 0; - s32 srcIndex = 0; - +void print_text(s32 x, s32 y, char *str) { // Don't continue if there is no memory to do so. if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool, sizeof(struct TextLabel))) == NULL) { @@ -233,143 +51,27 @@ void print_text(s32 x, s32 y, const char *str) { sTextLabels[sTextLabelsCount]->x = x; sTextLabels[sTextLabelsCount]->y = y; - c = str[srcIndex]; - - // Set the array with the text to print while finding length. - while (c != '\0') { - sTextLabels[sTextLabelsCount]->buffer[length] = c; - length++; - srcIndex++; - c = str[srcIndex]; + u32 i = 0; + while (str[i] != '\0') { + sTextLabels[sTextLabelsCount]->buffer[i] = str[i]; + i++; } + sTextLabels[sTextLabelsCount]->buffer[i] = '\0'; - sTextLabels[sTextLabelsCount]->length = length; sTextLabelsCount++; } /** - * Prints text in the colorful lettering centered at given X, Y coordinates. + * Prints text in the colorful lettering, allowing for text alignment. */ -void print_text_centered(s32 x, s32 y, const char *str) { - char c = 0; - UNUSED s8 unused1 = 0; - UNUSED s32 unused2 = 0; - s32 length = 0; - s32 srcIndex = 0; - - // Don't continue if there is no memory to do so. - if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool, - sizeof(struct TextLabel))) == NULL) { - return; - } - - c = str[srcIndex]; - - // Set the array with the text to print while finding length. - while (c != '\0') { - sTextLabels[sTextLabelsCount]->buffer[length] = c; - length++; - srcIndex++; - c = str[srcIndex]; - } - - sTextLabels[sTextLabelsCount]->length = length; - sTextLabels[sTextLabelsCount]->x = x - length * 12 / 2; - sTextLabels[sTextLabelsCount]->y = y; - sTextLabelsCount++; -} - -/** - * Converts a char into the proper colorful glyph for the char. - */ -s8 char_to_glyph_index(char c) { - if (c >= 'A' && c <= 'Z') { - return c - 55; - } - - if (c >= 'a' && c <= 'z') { - return c - 87; - } - - if (c >= '0' && c <= '9') { - return c - 48; - } - - if (c == ' ') { - return GLYPH_SPACE; - } - - if (c == '!') { - return GLYPH_EXCLAMATION_PNT; // !, JP only - } - - if (c == '#') { - return GLYPH_TWO_EXCLAMATION; // !!, JP only - } - - if (c == '?') { - return GLYPH_QUESTION_MARK; // ?, JP only - } - - if (c == '&') { - return GLYPH_AMPERSAND; // &, JP only - } - - if (c == '%') { - return GLYPH_PERCENT; // %, JP only - } - - if (c == '*') { - return GLYPH_MULTIPLY; // x - } - - if (c == '+') { - return GLYPH_COIN; // coin - } - - if (c == ',') { - return GLYPH_MARIO_HEAD; // Imagine I drew Mario's head - } - - if (c == '-') { - return GLYPH_STAR; // star - } - - if (c == '.') { - return GLYPH_PERIOD; // large shaded dot, JP only - } - - if (c == '/') { - return GLYPH_BETA_KEY; // beta key, JP only. Reused for Ü in EU. - } - - return GLYPH_SPACE; -} - -/** - * Adds an individual glyph to be rendered. - */ -void add_glyph_texture(s8 glyphIndex) { - const u8 *const *glyphs = segmented_to_virtual(main_hud_lut); - - gDPPipeSync(gDisplayListHead++); - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, glyphs[glyphIndex]); - gSPDisplayList(gDisplayListHead++, dl_hud_img_load_tex_block); -} - -/** - * Renders the glyph that's set at the given position. - */ -void render_textrect(s32 x, s32 y, s32 pos) { - s32 rectBaseX = x + pos * 12; - s32 rectBaseY = 224 - y; - s32 rectX; - s32 rectY; - - rectX = rectBaseX; - rectY = rectBaseY; - gSPTextureRectangle(gDisplayListHead++, rectX << 2, rectY << 2, (rectX + 15) << 2, - (rectY + 15) << 2, G_TX_RENDERTILE, 0, 0, 4 << 10, 1 << 10); +void print_text_aligned(s32 x, s32 y, char *str, u32 alignment) { + s32 strLength = get_string_width(str, main_hud_lut, &main_hud_utf8_lut); + if (alignment == TEXT_ALIGN_RIGHT) { + x -= strLength; + } else if (alignment == TEXT_ALIGN_CENTER) { + x -= strLength / 2; + } + print_text(x, y, str); } /** @@ -378,8 +80,6 @@ void render_textrect(s32 x, s32 y, s32 pos) { */ void render_text_labels(void) { s32 i; - s32 j; - s8 glyphIndex; Mtx *mtx; if (sTextLabelsCount == 0) { @@ -394,39 +94,16 @@ void render_text_labels(void) { } guOrtho(mtx, 0.0f, SCREEN_WIDTH, 0.0f, SCREEN_HEIGHT, -10.0f, 10.0f, 1.0f); - gSPPerspNormalize((Gfx *) (gDisplayListHead++), 0xFFFF); + gSPPerspNormalize(gDisplayListHead++, 0xFFFF); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(mtx), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH); - gSPDisplayList(gDisplayListHead++, dl_hud_img_begin); + gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); for (i = 0; i < sTextLabelsCount; i++) { - for (j = 0; j < sTextLabels[i]->length; j++) { - glyphIndex = char_to_glyph_index(sTextLabels[i]->buffer[j]); - - if (glyphIndex != GLYPH_SPACE) { -#ifdef VERSION_EU - // Beta Key was removed by EU, so glyph slot reused. - // This produces a colorful Ü. - if (glyphIndex == GLYPH_BETA_KEY) { - add_glyph_texture(GLYPH_U); - render_textrect(sTextLabels[i]->x, sTextLabels[i]->y, j); - - add_glyph_texture(GLYPH_UMLAUT); - render_textrect(sTextLabels[i]->x, sTextLabels[i]->y + 3, j); - } else { - add_glyph_texture(glyphIndex); - render_textrect(sTextLabels[i]->x, sTextLabels[i]->y, j); - } -#else - add_glyph_texture(glyphIndex); - render_textrect(sTextLabels[i]->x, sTextLabels[i]->y, j); -#endif - } - } - + print_hud_lut_string(sTextLabels[i]->x, 224 - sTextLabels[i]->y, sTextLabels[i]->buffer); mem_pool_free(gEffectsMemoryPool, sTextLabels[i]); } - gSPDisplayList(gDisplayListHead++, dl_hud_img_end); + gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); sTextLabelsCount = 0; } diff --git a/src/game/print.h b/src/game/print.h index 95597e8ab..f3c23e746 100644 --- a/src/game/print.h +++ b/src/game/print.h @@ -3,31 +3,11 @@ #include -#define TEXRECT_MIN_X 10 -#define TEXRECT_MAX_X 300 -#define TEXRECT_MIN_Y 5 -#define TEXRECT_MAX_Y 220 - -#define GLYPH_SPACE -1 -#define GLYPH_U 30 -#define GLYPH_EXCLAMATION_PNT 36 -#define GLYPH_TWO_EXCLAMATION 37 -#define GLYPH_QUESTION_MARK 38 -#define GLYPH_AMPERSAND 39 -#define GLYPH_PERCENT 40 -#define GLYPH_MULTIPLY 50 -#define GLYPH_COIN 51 -#define GLYPH_MARIO_HEAD 52 -#define GLYPH_STAR 53 -#define GLYPH_PERIOD 54 -#define GLYPH_BETA_KEY 55 -#define GLYPH_APOSTROPHE 56 -#define GLYPH_DOUBLE_QUOTE 57 -#define GLYPH_UMLAUT 58 - -void print_text_fmt_int(s32 x, s32 y, const char *str, s32 n); -void print_text(s32 x, s32 y, const char *str); -void print_text_centered(s32 x, s32 y, const char *str); +void print_text_fmt_int(s32 x, s32 y, char *str, s32 n); +void print_text(s32 x, s32 y, char *str); +void print_text_aligned(s32 x, s32 y, char *str, u32 alignment); +// Backwards compatibility, 1 is TEXT_ALIGN_CENTER +#define print_text_centered(x, y, str) print_text_aligned(x, y, str, 1); void render_text_labels(void); #endif // PRINT_H diff --git a/src/game/save_file.c b/src/game/save_file.c index 4c6bb0cf0..efbf933ab 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -498,6 +498,9 @@ void save_file_load_all(void) { break; } } +#ifdef MULTILANG // TODO TEXTSAVES support + gInGameLanguage = multilang_get_language(); +#endif #endif // TEXTSAVES stub_save_file_1(); } @@ -759,17 +762,18 @@ void save_file_move_cap_to_default_location(void) { } } -#ifdef VERSION_EU -void eu_set_language(u16 language) { +#ifdef MULTILANG +void multilang_set_language(u16 language) { gSaveBuffer.menuData[0].language = language; + gInGameLanguage = language; gMainMenuDataModified = TRUE; save_main_menu_data(); } -u16 eu_get_language(void) { +u16 multilang_get_language(void) { // check if the language is in range, in case we loaded a US save with garbage padding or something if (gSaveBuffer.menuData[0].language >= LANGUAGE_MAX) - eu_set_language(LANGUAGE_ENGLISH); // reset it to english if not + multilang_set_language(LANGUAGE_ENGLISH); // reset it to english if not return gSaveBuffer.menuData[0].language; } #endif diff --git a/src/game/save_file.h b/src/game/save_file.h index b6e525d39..82f98f643 100644 --- a/src/game/save_file.h +++ b/src/game/save_file.h @@ -50,7 +50,7 @@ struct MainMenuSaveData { u32 coinScoreAges[NUM_SAVE_FILES]; u16 soundMode; -#ifdef VERSION_EU +#ifdef MULTILANG u16 language; #define SUBTRAHEND 8 #else @@ -106,6 +106,18 @@ extern s8 gLevelToCourseNumTable[]; #define SAVE_FLAG_COLLECTED_MIPS_STAR_1 /* 0x08000000 */ (1 << 27) #define SAVE_FLAG_COLLECTED_MIPS_STAR_2 /* 0x10000000 */ (1 << 28) +enum StarFlags { + STAR_FLAGS_NONE = (0 << 0), // 0x00 + STAR_FLAG_ACT_1 = (1 << 0), // 0x01 + STAR_FLAG_ACT_2 = (1 << 1), // 0x02 + STAR_FLAG_ACT_3 = (1 << 2), // 0x04 + STAR_FLAG_ACT_4 = (1 << 3), // 0x08 + STAR_FLAG_ACT_5 = (1 << 4), // 0x10 + STAR_FLAG_ACT_6 = (1 << 5), // 0x20 + STAR_FLAG_ACT_100_COINS = (1 << 6), // 0x40 + STAR_FLAG_LAST = STAR_FLAG_ACT_100_COINS +}; + #define SAVE_FLAG_TO_STAR_FLAG(cmd) (((cmd) >> 24) & 0x7F) #define STAR_FLAG_TO_SAVE_FLAG(cmd) ((cmd) << 24) @@ -154,16 +166,9 @@ void disable_warp_checkpoint(void); void check_if_should_set_warp_checkpoint(struct WarpNode *warpNode); s32 check_warp_checkpoint(struct WarpNode *warpNode); -#ifdef VERSION_EU -enum EuLanguages { - LANGUAGE_ENGLISH, - LANGUAGE_FRENCH, - LANGUAGE_GERMAN, - LANGUAGE_MAX -}; - -void eu_set_language(u16 language); -u16 eu_get_language(void); +#ifdef MULTILANG +void multilang_set_language(u16 language); +u32 multilang_get_language(void); #endif #ifdef EXT_DEBUG_MENU diff --git a/src/game/segment2.h b/src/game/segment2.h index ea6c41ba1..b4b28f240 100644 --- a/src/game/segment2.h +++ b/src/game/segment2.h @@ -3,6 +3,7 @@ #include #include +#include "ingame_menu.h" extern u8 seg2_course_name_table[]; extern u8 seg2_act_name_table[]; @@ -44,14 +45,19 @@ extern Gfx dl_paintings_env_mapped_begin[]; extern Gfx dl_paintings_env_mapped_end[]; extern u8 seg2_painting_triangle_mesh[]; extern u8 seg2_painting_mesh_neighbor_tris[]; -extern u8* main_hud_lut[58]; +extern struct AsciiCharLUTEntry main_hud_lut[]; +extern struct Utf8LUT main_hud_utf8_lut; +extern Texture texture_hud_char_umlaut[]; extern Gfx dl_hud_img_load_tex_block[]; extern Gfx dl_hud_img_begin[]; extern Gfx dl_hud_img_end[]; -extern void *main_font_lut[]; +extern struct DiacriticLUTEntry main_font_diacritic_lut[]; +extern struct AsciiCharLUTEntry main_font_lut[]; +extern struct Utf8LUT main_font_utf8_lut; extern Gfx dl_ia_text_tex_settings[]; +extern Gfx dl_ia_text_tex_settings_packed[]; extern Gfx dl_rgba16_load_tex_block[]; -extern void *main_credits_font_lut[]; +extern struct AsciiCharLUTEntry main_credits_font_lut[]; extern u8* main_hud_camera_lut[6]; extern Gfx dl_draw_text_bg_box[]; extern Gfx dl_draw_triangle[]; diff --git a/src/game/segment7.h b/src/game/segment7.h index 6692ac6b4..364669c51 100644 --- a/src/game/segment7.h +++ b/src/game/segment7.h @@ -5,28 +5,9 @@ #include // from main menu segment 7 -extern u8 dl_menu_idle_hand[]; -extern u8 dl_menu_grabbing_hand[]; -extern u8 menu_hud_lut[]; -extern u8 menu_font_lut[]; -extern u8 dl_menu_ia8_text_begin[]; -extern u8 dl_menu_ia8_text_end[]; -extern u8 dl_menu_rgba16_wood_course[]; -#ifdef VERSION_EU -extern u8 dl_menu_rgba16_wood_course_end[]; -extern u8 dl_menu_texture_course_upper[]; -extern u8 dl_menu_texture_niveau_upper[]; -extern u8 dl_menu_texture_kurs_upper[]; - -extern const u8 eu_course_strings_en_table[]; -extern const u8 eu_course_strings_fr_table[]; -extern const u8 eu_course_strings_de_table[]; -#endif +#include "levels/menu/header.h" // from intro_segment7 -extern Gfx *intro_seg7_dl_0700B3A0; -extern Gfx *intro_seg7_dl_0700C6A0; -extern f32 intro_seg7_table_0700C790[]; -extern f32 intro_seg7_table_0700C880[]; +#include "levels/intro/header.h" #endif // SEGMENT7_H diff --git a/src/menu/file_select.c b/src/menu/file_select.c index 26323304e..c202f55b5 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -8,35 +8,29 @@ #include "engine/graph_node.h" #include "engine/math_util.h" #include "file_select.h" -#include "gfx_dimensions.h" #include "game/area.h" #include "game/game_init.h" #include "game/ingame_menu.h" #include "game/object_helpers.h" #include "game/object_list_processor.h" #include "game/print.h" -#include "game/rumble_init.h" #include "game/save_file.h" #include "game/segment2.h" #include "game/segment7.h" #include "game/spawn_object.h" +#include "game/rumble_init.h" #include "sm64.h" -#include "text_strings.h" - -#ifdef MOUSE_ACTIONS -#include "pc/controller/controller_mouse.h" -#include "pc/configfile.h" -#endif +#include // non-n64 -#ifdef COMMAND_LINE_OPTIONS -#include "pc/cliopts.h" -#endif +// from hackersm64 +#define o gCurrentObject -#include "eu_translation.h" -#ifdef VERSION_EU -#undef LANGUAGE_FUNCTION -#define LANGUAGE_FUNCTION sLanguageMode -#endif +enum CurrSaveFileNum { + SAVE_FILE_NUM_A = 0x1, + SAVE_FILE_NUM_B, + SAVE_FILE_NUM_C, + SAVE_FILE_NUM_D, +}; /** * @file file_select.c @@ -45,23 +39,9 @@ * special menu messages and phases, button states and button clicked checks. */ -#ifdef VERSION_US -// The current sound mode is automatically centered on US and Shindou. -static s16 sSoundTextX; -#endif - -//! @Bug (UB Array Access) For EU, more buttons were added than the array was extended. -//! This causes no currently known issues on console (as the other variables are not changed -//! while this is used) but can cause issues with other compilers. -#if defined(VERSION_EU) && !defined(AVOID_UB) -#define NUM_BUTTONS (MENU_BUTTON_OPTION_MAX - 1) -#else -#define NUM_BUTTONS MENU_BUTTON_OPTION_MAX -#endif - // Amount of main menu buttons defined in the code called by spawn_object_rel_with_rot. // See file_select.h for the names in MenuButtonTypes. -static struct Object *sMainMenuButtons[NUM_BUTTONS]; +static struct Object *sMainMenuButtons[MENU_BUTTON_OPTION_MAX]; // Used to defined yes/no fade colors after a file is selected in the erase menu. // sYesNoColor[0]: YES | sYesNoColor[1]: NO @@ -73,9 +53,6 @@ static s8 sSelectedButtonID = MENU_BUTTON_NONE; // Whether we are on the main menu or one of the submenus. static s8 sCurrentMenuLevel = MENU_LAYER_MAIN; -// Used for text opacifying. If it is below 250, it is constantly incremented. -static u8 sTextBaseAlpha = 0; - // 2D position of the cursor on the screen. // sCursorPos[0]: X | sCursorPos[1]: Y static f32 sCursorPos[] = {0, 0}; @@ -96,7 +73,7 @@ static s8 sFadeOutText = FALSE; static s8 sStatusMessageID = 0; // Used for text fading. The alpha value of text is calculated as -// sTextBaseAlpha - sTextFadeAlpha. +// gDialogTextAlpha - sTextFadeAlpha. static u8 sTextFadeAlpha = 0; // File select timer that keeps counting until it reaches 1000. @@ -111,9 +88,6 @@ static s8 sSoundMode = 0; // Active language for EU arrays, values defined similar to sSoundMode // 0: English | 1: French | 2: German -#ifdef VERSION_EU -static s8 sLanguageMode = LANGUAGE_ENGLISH; -#endif // Tracks which button will be pressed in the erase confirmation prompt (yes/no). static s8 sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE; @@ -130,169 +104,29 @@ static s8 sSelectedFileNum = 0; // coin high score, 1 for high score across all files. static s8 sScoreFileCoinScoreMode = 0; -// In EU, if no save file exists, open the language menu so the user can find it. -#ifdef VERSION_EU -static s8 sOpenLangSettings = FALSE; -#endif - -#ifndef VERSION_EU -static unsigned char textReturn[] = { TEXT_RETURN }; -#else -static unsigned char textReturn[][8] = {{ TEXT_RETURN }, { TEXT_RETURN_FR }, { TEXT_RETURN_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textViewScore[] = { TEXT_CHECK_SCORE }; -#else -static unsigned char textViewScore[][12] = {{ TEXT_CHECK_SCORE }, {TEXT_CHECK_SCORE_FR}, {TEXT_CHECK_SCORE_DE}}; -#endif - -#ifndef VERSION_EU -static unsigned char textCopyFileButton[] = { TEXT_COPY_FILE_BUTTON }; -#else -static unsigned char textCopyFileButton[][15] = {{ TEXT_COPY_FILE }, { TEXT_COPY_FILE_FR }, { TEXT_COPY_FILE_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textEraseFileButton[] = { TEXT_ERASE_FILE_BUTTON }; -#else -static unsigned char textEraseFileButton[][16] = { {TEXT_ERASE_FILE}, {TEXT_ERASE_FILE_FR}, {TEXT_ERASE_FILE_DE} }; -#endif - -#ifndef VERSION_EU -static unsigned char textSoundModes[][8] = { { TEXT_STEREO }, { TEXT_MONO }, { TEXT_HEADSET } }; -#endif - -static unsigned char textMarioA[] = { TEXT_FILE_MARIO_A }; -static unsigned char textMarioB[] = { TEXT_FILE_MARIO_B }; -static unsigned char textMarioC[] = { TEXT_FILE_MARIO_C }; -static unsigned char textMarioD[] = { TEXT_FILE_MARIO_D }; - -#ifndef VERSION_EU -static unsigned char textNew[] = { TEXT_NEW }; -static unsigned char starIcon[] = { GLYPH_STAR, GLYPH_SPACE }; -static unsigned char xIcon[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; -#endif - -#ifndef VERSION_EU -static unsigned char textSelectFile[] = { TEXT_SELECT_FILE }; -#else -static unsigned char textSelectFile[][17] = {{ TEXT_SELECT_FILE }, { TEXT_SELECT_FILE_FR }, { TEXT_SELECT_FILE_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textScore[] = { TEXT_SCORE }; -#else -static unsigned char textScore[][9] = {{ TEXT_SCORE }, { TEXT_SCORE_FR }, { TEXT_SCORE_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textCopy[] = { TEXT_COPY }; -#else -static unsigned char textCopy[][9] = {{ TEXT_COPY }, { TEXT_COPY_FR }, { TEXT_COPY_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textErase[] = { TEXT_ERASE }; -#else -static unsigned char textErase[][8] = {{ TEXT_ERASE }, { TEXT_ERASE_FR }, { TEXT_ERASE_DE }}; -#endif - -#ifdef VERSION_EU -static unsigned char textOption[][9] = {{ TEXT_OPTION }, { TEXT_OPTION_FR }, { TEXT_OPTION_DE } }; -#endif - -#ifndef VERSION_EU -static unsigned char textCheckFile[] = { TEXT_CHECK_FILE }; -#else -static unsigned char textCheckFile[][18] = {{ TEXT_CHECK_FILE }, { TEXT_CHECK_FILE_FR }, { TEXT_CHECK_FILE_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textNoSavedDataExists[] = { TEXT_NO_SAVED_DATA_EXISTS }; -#else -static unsigned char textNoSavedDataExists[][30] = {{ TEXT_NO_SAVED_DATA_EXISTS }, { TEXT_NO_SAVED_DATA_EXISTS_FR }, { TEXT_NO_SAVED_DATA_EXISTS_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textCopyFile[] = { TEXT_COPY_FILE }; -#else -static unsigned char textCopyFile[][16] = {{ TEXT_COPY_FILE_BUTTON }, { TEXT_COPY_FILE_BUTTON_FR }, { TEXT_COPY_FILE_BUTTON_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textCopyItToWhere[] = { TEXT_COPY_IT_TO_WHERE }; -#else -static unsigned char textCopyItToWhere[][18] = {{ TEXT_COPY_IT_TO_WHERE }, { TEXT_COPY_IT_TO_WHERE_FR }, { TEXT_COPY_IT_TO_WHERE_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textNoSavedDataExistsCopy[] = { TEXT_NO_SAVED_DATA_EXISTS }; -#endif - -#ifndef VERSION_EU -static unsigned char textCopyCompleted[] = { TEXT_COPYING_COMPLETED }; -#else -static unsigned char textCopyCompleted[][18] = {{ TEXT_COPYING_COMPLETED }, { TEXT_COPYING_COMPLETED_FR }, { TEXT_COPYING_COMPLETED_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textSavedDataExists[] = { TEXT_SAVED_DATA_EXISTS }; -#else -static unsigned char textSavedDataExists[][20] = {{ TEXT_SAVED_DATA_EXISTS }, { TEXT_SAVED_DATA_EXISTS_FR }, { TEXT_SAVED_DATA_EXISTS_DE }}; -#endif - -#ifndef VERSION_EU -static unsigned char textNoFileToCopyFrom[] = { TEXT_NO_FILE_TO_COPY_FROM }; -#else -static unsigned char textNoFileToCopyFrom[][21] = {{ TEXT_NO_FILE_TO_COPY_FROM }, { TEXT_NO_FILE_TO_COPY_FROM_FR }, { TEXT_NO_FILE_TO_COPY_FROM_DE }}; +// Determines which languages are available for the language selector, +// since the value of the language enums are always constant. +#ifdef MULTILANG +const u8 gDefinedLanguages[] = { + LANGUAGE_ENGLISH, +#ifdef ENABLE_FRENCH + LANGUAGE_FRENCH, #endif - -#ifndef VERSION_EU -static unsigned char textYes[] = { TEXT_YES }; -#else -static unsigned char textYes[][4] = {{ TEXT_YES }, { TEXT_YES_FR }, { TEXT_YES_DE }}; +#ifdef ENABLE_GERMAN + LANGUAGE_GERMAN, #endif - -#ifndef VERSION_EU -static unsigned char textNo[] = { TEXT_NO }; -#else -static unsigned char textNo[][5] = {{ TEXT_NO }, { TEXT_NO_FR }, { TEXT_NO_DE }}; +#ifdef ENABLE_JAPANESE + LANGUAGE_JAPANESE, #endif - -#ifdef VERSION_EU -// In EU, Erase File and Sound Select strings are outside it's print string function -static unsigned char textEraseFile[][17] = { - { TEXT_ERASE_FILE_BUTTON }, { TEXT_ERASE_FILE_BUTTON_FR }, { TEXT_ERASE_FILE_BUTTON_DE } -}; -static unsigned char textSure[][8] = {{ TEXT_SURE }, { TEXT_SURE_FR }, { TEXT_SURE_DE }}; -static unsigned char textMarioAJustErased[][20] = { - { TEXT_FILE_MARIO_A_JUST_ERASED }, { TEXT_FILE_MARIO_A_JUST_ERASED_FR }, { TEXT_FILE_MARIO_A_JUST_ERASED_DE } -}; - -static unsigned char textSoundSelect[][13] = { - { TEXT_SOUND_SELECT }, { TEXT_SOUND_SELECT_FR }, { TEXT_SOUND_SELECT_DE } -}; - -static unsigned char textLanguageSelect[][17] = { - { TEXT_LANGUAGE_SELECT }, { TEXT_LANGUAGE_SELECT_FR }, { TEXT_LANGUAGE_SELECT_DE } -}; - -static unsigned char textSoundModes[][10] = { - { TEXT_STEREO }, { TEXT_MONO }, { TEXT_HEADSET }, - { TEXT_STEREO_FR }, { TEXT_MONO_FR }, { TEXT_HEADSET_FR }, - { TEXT_STEREO_DE }, { TEXT_MONO_DE }, { TEXT_HEADSET_DE } }; -static unsigned char textLanguage[][9] = {{ TEXT_ENGLISH }, { TEXT_FRENCH }, { TEXT_GERMAN }}; +// Index of the selected language in the above array. +static s8 sSelectedLanguageIndex = 0; -static unsigned char textMario[] = { TEXT_MARIO }; -static unsigned char textHiScore[][15] = {{ TEXT_HI_SCORE }, { TEXT_HI_SCORE_FR }, { TEXT_HI_SCORE_DE }}; -static unsigned char textMyScore[][10] = {{ TEXT_MY_SCORE }, { TEXT_MY_SCORE_FR }, { TEXT_MY_SCORE_DE }}; +// Whether to open the language menu when the game is booted. +static s8 sOpenLangSettings = FALSE; -static unsigned char textNew[][5] = {{ TEXT_NEW }, { TEXT_NEW_FR }, { TEXT_NEW_DE }}; -static unsigned char starIcon[] = { GLYPH_STAR, GLYPH_SPACE }; -static unsigned char xIcon[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; +#define NUM_DEFINED_LANGUAGES ARRAY_COUNT(gDefinedLanguages) #endif /** @@ -303,9 +137,6 @@ static unsigned char xIcon[] = { GLYPH_MULTIPLY, GLYPH_SPACE }; void beh_yellow_background_menu_init(void) { gCurrentObject->oFaceAngleYaw = 0x8000; gCurrentObject->oMenuButtonScale = 9.0f; -#ifdef WIDESCREEN - gCurrentObject->oAnimState = 1; -#endif } /** @@ -321,14 +152,14 @@ void beh_yellow_background_menu_loop(void) { * depth = 200.0 for main menu, 22.0 for submenus. */ s32 check_clicked_button(s16 x, s16 y, f32 depth) { - f32 a = 52.4213; - f32 newX = ((f32) x * 160.0) / (a * depth); - f32 newY = ((f32) y * 120.0) / (a * 3 / 4 * depth); + f32 a = 52.4213f; + f32 newX = ((f32) x * 160.0f) / (a * depth); + f32 newY = ((f32) y * 120.0f) / (a * 3 / 4 * depth); s16 maxX = newX + 25.0f; s16 minX = newX - 25.0f; s16 maxY = newY + 21.0f; s16 minY = newY - 21.0f; - + if (sClickPos[0] < maxX && minX < sClickPos[0] && sClickPos[1] < maxY && minY < sClickPos[1]) { return TRUE; } @@ -338,7 +169,7 @@ s32 check_clicked_button(s16 x, s16 y, f32 depth) { /** * Grow from main menu, used by selecting files and menus. */ -static void bhv_menu_button_growing_from_main_menu(struct Object *button) { +void bhv_menu_button_growing_from_main_menu(struct Object *button) { if (button->oMenuButtonTimer < 16) { button->oFaceAngleYaw += 0x800; } @@ -348,19 +179,16 @@ static void bhv_menu_button_growing_from_main_menu(struct Object *button) { if (button->oMenuButtonTimer >= 8 && button->oMenuButtonTimer < 16) { button->oFaceAnglePitch -= 0x800; } - button->oParentRelativePosX -= button->oMenuButtonOrigPosX / 16.0; - button->oParentRelativePosY -= button->oMenuButtonOrigPosY / 16.0; - if (button->oPosZ < button->oMenuButtonOrigPosZ + 17800.0) { - button->oParentRelativePosZ += 1112.5; + button->oParentRelativePosX -= button->oMenuButtonOrigPosX / 16.0f; + button->oParentRelativePosY -= button->oMenuButtonOrigPosY / 16.0f; + if (button->oPosZ < button->oMenuButtonOrigPosZ + 17800.0f) { + button->oParentRelativePosZ += 1112.5f; } button->oMenuButtonTimer++; if (button->oMenuButtonTimer == 16) { button->oParentRelativePosX = 0.0f; button->oParentRelativePosY = 0.0f; button->oMenuButtonState = MENU_BUTTON_STATE_FULLSCREEN; -#ifdef WIDESCREEN - button->oAnimState = 1; -#endif button->oMenuButtonTimer = 0; } } @@ -368,7 +196,7 @@ static void bhv_menu_button_growing_from_main_menu(struct Object *button) { /** * Shrink back to main menu, used to return back while inside menus. */ -static void bhv_menu_button_shrinking_to_main_menu(struct Object *button) { +void bhv_menu_button_shrinking_to_main_menu(struct Object *button) { if (button->oMenuButtonTimer < 16) { button->oFaceAngleYaw -= 0x800; } @@ -378,16 +206,12 @@ static void bhv_menu_button_shrinking_to_main_menu(struct Object *button) { if (button->oMenuButtonTimer >= 8 && button->oMenuButtonTimer < 16) { button->oFaceAnglePitch += 0x800; } - button->oParentRelativePosX += button->oMenuButtonOrigPosX / 16.0; - button->oParentRelativePosY += button->oMenuButtonOrigPosY / 16.0; + button->oParentRelativePosX += button->oMenuButtonOrigPosX / 16.0f; + button->oParentRelativePosY += button->oMenuButtonOrigPosY / 16.0f; if (button->oPosZ > button->oMenuButtonOrigPosZ) { - button->oParentRelativePosZ -= 1112.5; + button->oParentRelativePosZ -= 1112.5f; } button->oMenuButtonTimer++; -#ifdef WIDESCREEN - button->oAnimState = 0; -#endif - if (button->oMenuButtonTimer == 16) { button->oParentRelativePosX = button->oMenuButtonOrigPosX; button->oParentRelativePosY = button->oMenuButtonOrigPosY; @@ -399,7 +223,7 @@ static void bhv_menu_button_shrinking_to_main_menu(struct Object *button) { /** * Grow from submenu, used by selecting a file in the score menu. */ -static void bhv_menu_button_growing_from_submenu(struct Object *button) { +void bhv_menu_button_growing_from_submenu(struct Object *button) { if (button->oMenuButtonTimer < 16) { button->oFaceAngleYaw += 0x800; } @@ -409,9 +233,9 @@ static void bhv_menu_button_growing_from_submenu(struct Object *button) { if (button->oMenuButtonTimer >= 8 && button->oMenuButtonTimer < 16) { button->oFaceAnglePitch -= 0x800; } - button->oParentRelativePosX -= button->oMenuButtonOrigPosX / 16.0; - button->oParentRelativePosY -= button->oMenuButtonOrigPosY / 16.0; - button->oParentRelativePosZ -= 116.25; + button->oParentRelativePosX -= button->oMenuButtonOrigPosX / 16.0f; + button->oParentRelativePosY -= button->oMenuButtonOrigPosY / 16.0f; + button->oParentRelativePosZ -= 116.25f; button->oMenuButtonTimer++; if (button->oMenuButtonTimer == 16) { button->oParentRelativePosX = 0.0f; @@ -424,7 +248,7 @@ static void bhv_menu_button_growing_from_submenu(struct Object *button) { /** * Shrink back to submenu, used to return back while inside a score save menu. */ -static void bhv_menu_button_shrinking_to_submenu(struct Object *button) { +void bhv_menu_button_shrinking_to_submenu(struct Object *button) { if (button->oMenuButtonTimer < 16) { button->oFaceAngleYaw -= 0x800; } @@ -434,10 +258,10 @@ static void bhv_menu_button_shrinking_to_submenu(struct Object *button) { if (button->oMenuButtonTimer >= 8 && button->oMenuButtonTimer < 16) { button->oFaceAnglePitch += 0x800; } - button->oParentRelativePosX += button->oMenuButtonOrigPosX / 16.0; - button->oParentRelativePosY += button->oMenuButtonOrigPosY / 16.0; + button->oParentRelativePosX += button->oMenuButtonOrigPosX / 16.0f; + button->oParentRelativePosY += button->oMenuButtonOrigPosY / 16.0f; if (button->oPosZ > button->oMenuButtonOrigPosZ) { - button->oParentRelativePosZ += 116.25; + button->oParentRelativePosZ += 116.25f; } button->oMenuButtonTimer++; if (button->oMenuButtonTimer == 16) { @@ -452,7 +276,7 @@ static void bhv_menu_button_shrinking_to_submenu(struct Object *button) { * A small increase and decrease in size. * Used by failed copy/erase/score operations and sound mode select. */ -static void bhv_menu_button_zoom_in_out(struct Object *button) { +void bhv_menu_button_zoom_in_out(struct Object *button) { if (sCurrentMenuLevel == MENU_LAYER_MAIN) { if (button->oMenuButtonTimer < 4) { button->oParentRelativePosZ -= 20.0f; @@ -471,9 +295,6 @@ static void bhv_menu_button_zoom_in_out(struct Object *button) { button->oMenuButtonTimer++; if (button->oMenuButtonTimer == 8) { button->oMenuButtonState = MENU_BUTTON_STATE_DEFAULT; -#ifdef WIDESCREEN - button->oAnimState = 0; -#endif button->oMenuButtonTimer = 0; } } @@ -482,14 +303,11 @@ static void bhv_menu_button_zoom_in_out(struct Object *button) { * A small temporary increase in size. * Used while selecting a target copy/erase file or yes/no erase confirmation prompt. */ -static void bhv_menu_button_zoom_in(struct Object *button) { - button->oMenuButtonScale += 0.0022; +void bhv_menu_button_zoom_in(struct Object *button) { + button->oMenuButtonScale += 0.0022f; button->oMenuButtonTimer++; if (button->oMenuButtonTimer == 10) { button->oMenuButtonState = MENU_BUTTON_STATE_DEFAULT; -#ifdef WIDESCREEN - button->oAnimState = 0; -#endif button->oMenuButtonTimer = 0; } } @@ -499,14 +317,11 @@ static void bhv_menu_button_zoom_in(struct Object *button) { * Used after selecting a target copy/erase file or * yes/no erase confirmation prompt to undo the zoom in. */ -static void bhv_menu_button_zoom_out(struct Object *button) { - button->oMenuButtonScale -= 0.0022; +void bhv_menu_button_zoom_out(struct Object *button) { + button->oMenuButtonScale -= 0.0022f; button->oMenuButtonTimer++; if (button->oMenuButtonTimer == 10) { button->oMenuButtonState = MENU_BUTTON_STATE_DEFAULT; -#ifdef WIDESCREEN - button->oAnimState = 0; -#endif button->oMenuButtonTimer = 0; } } @@ -519,9 +334,6 @@ static void bhv_menu_button_zoom_out(struct Object *button) { void bhv_menu_button_init(void) { gCurrentObject->oMenuButtonOrigPosX = gCurrentObject->oParentRelativePosX; gCurrentObject->oMenuButtonOrigPosY = gCurrentObject->oParentRelativePosY; -#ifdef WIDESCREEN - gCurrentObject->oAnimState = 0; -#endif } /** @@ -541,7 +353,7 @@ void bhv_menu_button_loop(void) { if (sCurrentMenuLevel == MENU_LAYER_SUBMENU) { bhv_menu_button_growing_from_submenu(gCurrentObject); // Only used for score files } - sTextBaseAlpha = 0; + gDialogTextAlpha = 0; sCursorClickingTimer = 4; break; case MENU_BUTTON_STATE_FULLSCREEN: // Menu state @@ -553,7 +365,7 @@ void bhv_menu_button_loop(void) { if (sCurrentMenuLevel == MENU_LAYER_SUBMENU) { bhv_menu_button_shrinking_to_submenu(gCurrentObject); // Only used for score files } - sTextBaseAlpha = 0; + gDialogTextAlpha = 0; sCursorClickingTimer = 4; break; case MENU_BUTTON_STATE_ZOOM_IN_OUT: @@ -580,7 +392,7 @@ void exit_score_file_to_score_menu(struct Object *scoreFileButton, s8 scoreButto if (scoreFileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN && sCursorClickingTimer == 2) { play_sound(SOUND_MENU_CAMERA_ZOOM_OUT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif scoreFileButton->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING; @@ -594,72 +406,66 @@ void exit_score_file_to_score_menu(struct Object *scoreFileButton, s8 scoreButto } } +static const Vec3s sSaveFileButtonPositions[] = { + { 711, 311, -100 }, // SAVE_FILE_A + { -166, 311, -100 }, // SAVE_FILE_B + { 711, 0, -100 }, // SAVE_FILE_C + { -166, 0, -100 }, // SAVE_FILE_D +}; + +#define SPAWN_FILE_SELECT_FILE_BUTTON(parent, saveFile) \ + spawn_object_rel_with_rot((parent), \ + (save_file_exists(saveFile) ? MODEL_MAIN_MENU_MARIO_SAVE_BUTTON : MODEL_MAIN_MENU_MARIO_NEW_BUTTON),\ + bhvMenuButton, \ + sSaveFileButtonPositions[saveFile][0], \ + sSaveFileButtonPositions[saveFile][1], \ + sSaveFileButtonPositions[saveFile][2], \ + 0x0, -0x8000, 0x0) + +#define MENU_BUTTON_SCALE 0.11111111f + /** - * Render buttons for the score menu. + * Render buttons for the menu. * Also check if the save file exists to render a different Mario button. */ -void render_score_menu_buttons(struct Object *scoreButton) { +void render_menu_buttons(s32 selectedButtonID) { + struct Object *button = sMainMenuButtons[selectedButtonID]; + // MENU_BUTTON_SCORE -> 7 + // MENU_BUTTON_COPY -> 14 + // MENU_BUTTON_ERASE -> 21 + s32 idx = (selectedButtonID - 3) * 7; + // File A - if (save_file_exists(SAVE_FILE_A) == TRUE) { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A] = - spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, - 711, 311, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A] = - spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, - 311, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[idx + 0] = SPAWN_FILE_SELECT_FILE_BUTTON(button, SAVE_FILE_A); + sMainMenuButtons[idx + 0]->oMenuButtonScale = MENU_BUTTON_SCALE; // File B - if (save_file_exists(SAVE_FILE_B) == TRUE) { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B] = - spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, - -166, 311, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B] = - spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, - -166, 311, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[idx + 1] = SPAWN_FILE_SELECT_FILE_BUTTON(button, SAVE_FILE_B); + sMainMenuButtons[idx + 1]->oMenuButtonScale = MENU_BUTTON_SCALE; // File C - if (save_file_exists(SAVE_FILE_C) == TRUE) { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C] = spawn_object_rel_with_rot( - scoreButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C] = spawn_object_rel_with_rot( - scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[idx + 2] = SPAWN_FILE_SELECT_FILE_BUTTON(button, SAVE_FILE_C); + sMainMenuButtons[idx + 2]->oMenuButtonScale = MENU_BUTTON_SCALE; // File D - if (save_file_exists(SAVE_FILE_D) == TRUE) { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D] = - spawn_object_rel_with_rot(scoreButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, - -166, 0, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D] = spawn_object_rel_with_rot( - scoreButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[idx + 3] = SPAWN_FILE_SELECT_FILE_BUTTON(button, SAVE_FILE_D); + sMainMenuButtons[idx + 3]->oMenuButtonScale = MENU_BUTTON_SCALE; + // Return to main menu button - sMainMenuButtons[MENU_BUTTON_SCORE_RETURN] = spawn_object_rel_with_rot( - scoreButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 711, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_SCORE_RETURN]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[idx + 4] = + spawn_object_rel_with_rot(button, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, + bhvMenuButton, 711, -388, -100, 0x0, -0x8000, 0x0); + sMainMenuButtons[idx + 4]->oMenuButtonScale = MENU_BUTTON_SCALE; // Switch to copy menu button - sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE] = spawn_object_rel_with_rot( - scoreButton, MODEL_MAIN_MENU_BLUE_COPY_BUTTON, bhvMenuButton, 0, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[idx + 5] = + spawn_object_rel_with_rot(button, selectedButtonID == MENU_BUTTON_SCORE ? MODEL_MAIN_MENU_BLUE_COPY_BUTTON : MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, + bhvMenuButton, 0, -388, -100, 0x0, -0x8000, 0x0); + sMainMenuButtons[idx + 5]->oMenuButtonScale = MENU_BUTTON_SCALE; // Switch to erase menu button - sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE] = spawn_object_rel_with_rot( - scoreButton, MODEL_MAIN_MENU_RED_ERASE_BUTTON, bhvMenuButton, -711, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[idx + 6] = + spawn_object_rel_with_rot(button, selectedButtonID == MENU_BUTTON_ERASE ? MODEL_MAIN_MENU_BLUE_COPY_BUTTON : MODEL_MAIN_MENU_RED_ERASE_BUTTON, + bhvMenuButton, -711, -388, -100, 0x0, -0x8000, 0x0); + sMainMenuButtons[idx + 6]->oMenuButtonScale = MENU_BUTTON_SCALE; } -#ifdef VERSION_EU - #define SCORE_TIMER 46 -#else - #define SCORE_TIMER 31 -#endif - +#define SCORE_TIMER 31 /** * In the score menu, checks if a button was clicked to play a sound, button state and other functions. */ @@ -676,7 +482,7 @@ void check_score_menu_clicked_buttons(struct Object *scoreButton) { if (buttonID == MENU_BUTTON_SCORE_RETURN || buttonID == MENU_BUTTON_SCORE_COPY_FILE || buttonID == MENU_BUTTON_SCORE_ERASE_FILE) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -687,7 +493,7 @@ void check_score_menu_clicked_buttons(struct Object *scoreButton) { // If clicked in a existing save file, select it too see it's score if (save_file_exists(buttonID - MENU_BUTTON_SCORE_MIN) == TRUE) { play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; @@ -696,7 +502,7 @@ void check_score_menu_clicked_buttons(struct Object *scoreButton) { else { // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = @@ -717,69 +523,7 @@ void check_score_menu_clicked_buttons(struct Object *scoreButton) { #undef SCORE_TIMER -/** - * Render buttons for the copy menu. - * Also check if the save file exists to render a different Mario button. - */ -void render_copy_menu_buttons(struct Object *copyButton) { - // File A - if (save_file_exists(SAVE_FILE_A) == TRUE) { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_A] = - spawn_object_rel_with_rot(copyButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, 711, - 311, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_A] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 311, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_COPY_FILE_A]->oMenuButtonScale = 0.11111111f; - // File B - if (save_file_exists(SAVE_FILE_B) == TRUE) { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_B] = - spawn_object_rel_with_rot(copyButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, - -166, 311, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_B] = - spawn_object_rel_with_rot(copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, - 311, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_COPY_FILE_B]->oMenuButtonScale = 0.11111111f; - // File C - if (save_file_exists(SAVE_FILE_C) == TRUE) { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_C] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_C] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_COPY_FILE_C]->oMenuButtonScale = 0.11111111f; - // File D - if (save_file_exists(SAVE_FILE_D) == TRUE) { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_D] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_COPY_FILE_D] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_COPY_FILE_D]->oMenuButtonScale = 0.11111111f; - // Return to main menu button - sMainMenuButtons[MENU_BUTTON_COPY_RETURN] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 711, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_COPY_RETURN]->oMenuButtonScale = 0.11111111f; - // Switch to scire menu button - sMainMenuButtons[MENU_BUTTON_COPY_CHECK_SCORE] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, bhvMenuButton, 0, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_COPY_CHECK_SCORE]->oMenuButtonScale = 0.11111111f; - // Switch to erase menu button - sMainMenuButtons[MENU_BUTTON_COPY_ERASE_FILE] = spawn_object_rel_with_rot( - copyButton, MODEL_MAIN_MENU_RED_ERASE_BUTTON, bhvMenuButton, -711, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_COPY_ERASE_FILE]->oMenuButtonScale = 0.11111111f; -} - -#ifdef VERSION_EU - #define BUZZ_TIMER 36 -#else - #define BUZZ_TIMER 21 -#endif +#define BUZZ_TIMER 21 /** * Copy Menu phase actions that handles what to do when a file button is clicked. @@ -793,7 +537,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { if (save_file_exists(copyFileButtonID - MENU_BUTTON_COPY_MIN) == TRUE) { // If clicked in a existing save file, ask where it wants to copy play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[copyFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; @@ -804,7 +548,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { } else { // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[copyFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -819,7 +563,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { if (save_file_exists(copyFileButtonID - MENU_BUTTON_COPY_MIN) == FALSE) { // If clicked in a non-existing save file, copy the file play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif copyButton->oMenuButtonActionPhase = COPY_PHASE_COPY_COMPLETE; @@ -834,11 +578,10 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { // If clicked in a existing save file, play buzz sound if (MENU_BUTTON_COPY_FILE_A + sSelectedFileIndex == copyFileButtonID) { play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(5, 80); +#if ENABLE_RUMBLE + queue_rumble_data(5, 80); #endif - sMainMenuButtons[MENU_BUTTON_COPY_FILE_A + sSelectedFileIndex]->oMenuButtonState = - MENU_BUTTON_STATE_ZOOM_OUT; + sMainMenuButtons[MENU_BUTTON_COPY_FILE_A + sSelectedFileIndex]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_OUT; copyButton->oMenuButtonActionPhase = COPY_PHASE_MAIN; sFadeOutText = TRUE; return; @@ -852,13 +595,7 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) { } } -#ifdef VERSION_EU - #define ACTION_TIMER 41 - #define MAIN_RETURN_TIMER 36 -#else - #define ACTION_TIMER 31 - #define MAIN_RETURN_TIMER 31 -#endif +#define ACTION_TIMER 30 /** * In the copy menu, checks if a button was clicked to play a sound, button state and other functions. @@ -877,7 +614,7 @@ void check_copy_menu_clicked_buttons(struct Object *copyButton) { || buttonID == MENU_BUTTON_COPY_ERASE_FILE) { if (copyButton->oMenuButtonActionPhase == COPY_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -898,7 +635,7 @@ void check_copy_menu_clicked_buttons(struct Object *copyButton) { // After copy is complete, return to main copy phase if (copyButton->oMenuButtonActionPhase == COPY_PHASE_COPY_COMPLETE - && sMainMenuTimer >= MAIN_RETURN_TIMER) { + && sMainMenuTimer > ACTION_TIMER) { copyButton->oMenuButtonActionPhase = COPY_PHASE_MAIN; sMainMenuButtons[MENU_BUTTON_COPY_MIN + sSelectedFileIndex]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_OUT; @@ -906,66 +643,6 @@ void check_copy_menu_clicked_buttons(struct Object *copyButton) { } } -/** - * Render buttons for the erase menu. - * Also check if the save file exists to render a different Mario button. - */ -void render_erase_menu_buttons(struct Object *eraseButton) { - // File A - if (save_file_exists(SAVE_FILE_A) == TRUE) { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_A] = - spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, - 711, 311, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_A] = - spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, - 311, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_A]->oMenuButtonScale = 0.11111111f; - // File B - if (save_file_exists(SAVE_FILE_B) == TRUE) { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_B] = - spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, - -166, 311, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_B] = - spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, - -166, 311, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_B]->oMenuButtonScale = 0.11111111f; - // File C - if (save_file_exists(SAVE_FILE_C) == TRUE) { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_C] = spawn_object_rel_with_rot( - eraseButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_C] = spawn_object_rel_with_rot( - eraseButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, 711, 0, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_C]->oMenuButtonScale = 0.11111111f; - // File D - if (save_file_exists(SAVE_FILE_D) == TRUE) { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_D] = - spawn_object_rel_with_rot(eraseButton, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON, bhvMenuButton, - -166, 0, -100, 0, -0x8000, 0); - } else { - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_D] = spawn_object_rel_with_rot( - eraseButton, MODEL_MAIN_MENU_MARIO_NEW_BUTTON, bhvMenuButton, -166, 0, -100, 0, -0x8000, 0); - } - sMainMenuButtons[MENU_BUTTON_ERASE_FILE_D]->oMenuButtonScale = 0.11111111f; - // Return to main menu button - sMainMenuButtons[MENU_BUTTON_ERASE_RETURN] = spawn_object_rel_with_rot( - eraseButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 711, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_ERASE_RETURN]->oMenuButtonScale = 0.11111111f; - // Switch to score menu button - sMainMenuButtons[MENU_BUTTON_ERASE_CHECK_SCORE] = spawn_object_rel_with_rot( - eraseButton, MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, bhvMenuButton, 0, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_ERASE_CHECK_SCORE]->oMenuButtonScale = 0.11111111f; - // Switch to copy menu button - sMainMenuButtons[MENU_BUTTON_ERASE_COPY_FILE] = spawn_object_rel_with_rot( - eraseButton, MODEL_MAIN_MENU_BLUE_COPY_BUTTON, bhvMenuButton, -711, -388, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_ERASE_COPY_FILE]->oMenuButtonScale = 0.11111111f; -} - /** * Erase Menu phase actions that handles what to do when a file button is clicked. */ @@ -975,7 +652,7 @@ void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) if (save_file_exists(eraseFileButtonID - MENU_BUTTON_ERASE_MIN) == TRUE) { // If clicked in a existing save file, ask if it wants to delete it play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[eraseFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; @@ -986,7 +663,7 @@ void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) } else { // If clicked in a non-existing save file, play buzz sound play_sound(SOUND_MENU_CAMERA_BUZZ, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[eraseFileButtonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -1003,7 +680,7 @@ void erase_action_file_button(struct Object *eraseButton, s32 eraseFileButtonID) // Note: The prompt functions are actually called when the ERASE_MSG_PROMPT // message is displayed with print_erase_menu_prompt play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->oMenuButtonState = @@ -1034,7 +711,7 @@ void check_erase_menu_clicked_buttons(struct Object *eraseButton) { || buttonID == MENU_BUTTON_ERASE_COPY_FILE) { if (eraseButton->oMenuButtonActionPhase == ERASE_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; @@ -1053,7 +730,7 @@ void check_erase_menu_clicked_buttons(struct Object *eraseButton) { } // After erase is complete, return to main erase phase if (eraseButton->oMenuButtonActionPhase == ERASE_PHASE_MARIO_ERASED - && sMainMenuTimer >= MAIN_RETURN_TIMER) { + && sMainMenuTimer > ACTION_TIMER) { eraseButton->oMenuButtonActionPhase = ERASE_PHASE_MAIN; sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_OUT; @@ -1062,9 +739,8 @@ void check_erase_menu_clicked_buttons(struct Object *eraseButton) { } #undef ACTION_TIMER -#undef MAIN_RETURN_TIMER -#ifdef VERSION_EU +#ifdef MULTILANG #define SOUND_BUTTON_Y 388 #else #define SOUND_BUTTON_Y 0 @@ -1076,43 +752,28 @@ void check_erase_menu_clicked_buttons(struct Object *eraseButton) { void render_sound_mode_menu_buttons(struct Object *soundModeButton) { // Stereo option button sMainMenuButtons[MENU_BUTTON_STEREO] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 533, SOUND_BUTTON_Y, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_STEREO]->oMenuButtonScale = 0.11111111f; + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 533, SOUND_BUTTON_Y, -100, 0x0, -0x8000, 0x0); + sMainMenuButtons[MENU_BUTTON_STEREO]->oMenuButtonScale = MENU_BUTTON_SCALE; // Mono option button sMainMenuButtons[MENU_BUTTON_MONO] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 0, SOUND_BUTTON_Y, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_MONO]->oMenuButtonScale = 0.11111111f; + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 0, SOUND_BUTTON_Y, -100, 0x0, -0x8000, 0x0); + sMainMenuButtons[MENU_BUTTON_MONO]->oMenuButtonScale = MENU_BUTTON_SCALE; // Headset option button sMainMenuButtons[MENU_BUTTON_HEADSET] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, SOUND_BUTTON_Y, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_HEADSET]->oMenuButtonScale = 0.11111111f; - -#ifdef VERSION_EU - // English option button - sMainMenuButtons[MENU_BUTTON_LANGUAGE_ENGLISH] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 533, -111, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_LANGUAGE_ENGLISH]->oMenuButtonScale = 0.11111111f; - // French option button - sMainMenuButtons[MENU_BUTTON_LANGUAGE_FRENCH] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, 0, -111, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_LANGUAGE_FRENCH]->oMenuButtonScale = 0.11111111f; - // German option button - sMainMenuButtons[MENU_BUTTON_LANGUAGE_GERMAN] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, -111, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_LANGUAGE_GERMAN]->oMenuButtonScale = 0.11111111f; + soundModeButton, MODEL_MAIN_MENU_GENERIC_BUTTON, bhvMenuButton, -533, SOUND_BUTTON_Y, -100, 0x0, -0x8000, 0x0); + sMainMenuButtons[MENU_BUTTON_HEADSET]->oMenuButtonScale = MENU_BUTTON_SCALE; +#ifdef MULTILANG // Return button - sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN] = spawn_object_rel_with_rot( - soundModeButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 0, -533, -100, 0, -0x8000, 0); - sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN]->oMenuButtonScale = 0.11111111f; + sMainMenuButtons[MENU_BUTTON_OPTION_RETURN] = spawn_object_rel_with_rot( + soundModeButton, MODEL_MAIN_MENU_YELLOW_FILE_BUTTON, bhvMenuButton, 0, -533, -100, 0x0, -0x8000, 0x0); + sMainMenuButtons[MENU_BUTTON_OPTION_RETURN]->oMenuButtonScale = MENU_BUTTON_SCALE; #else // Zoom in current selection sMainMenuButtons[MENU_BUTTON_OPTION_MIN + sSoundMode]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN; #endif } -#undef SOUND_BUTTON_Y - /** * In the sound mode menu, checks if a button was clicked to change sound mode & button state. */ @@ -1131,35 +792,21 @@ void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) { || buttonID == MENU_BUTTON_HEADSET) { if (soundModeButton->oMenuButtonActionPhase == SOUND_MODE_PHASE_MAIN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; -#ifndef VERSION_EU - // Sound menu buttons don't return to Main Menu in EU - // because they don't have a case in bhv_menu_button_manager_loop +#ifndef MULTILANG + // Sound menu buttons don't return to Main Menu with multilang enabled sSelectedButtonID = buttonID; #endif sSoundMode = buttonID - MENU_BUTTON_OPTION_MIN; save_file_set_sound_mode(sSoundMode); } } -#ifdef VERSION_EU - // If language mode button clicked, select it and change language - if (buttonID == MENU_BUTTON_LANGUAGE_ENGLISH || buttonID == MENU_BUTTON_LANGUAGE_FRENCH - || buttonID == MENU_BUTTON_LANGUAGE_GERMAN) { - if (soundModeButton->oMenuButtonActionPhase == SOUND_MODE_PHASE_MAIN) { - play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(5, 80); -#endif - sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; - sLanguageMode = buttonID - MENU_BUTTON_LANGUAGE_MIN; - eu_set_language(sLanguageMode); - } - } +#ifdef MULTILANG // If neither of the buttons above are pressed, return to main menu - if (buttonID == MENU_BUTTON_LANGUAGE_RETURN) { + if (buttonID == MENU_BUTTON_OPTION_RETURN) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_ZOOM_IN_OUT; sSelectedButtonID = buttonID; @@ -1181,12 +828,27 @@ void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) { if (fileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { sSelectedFileNum = fileNum; } +} -#ifdef EXT_DEBUG_MENU - if (gPlayer1Controller->buttonDown == (L_CBUTTONS | D_CBUTTONS)) { - get_complete_save_file(fileNum); +/** + * Clears a section of sMainMenuButtons. + */ +void delete_menu_button_objects(s16 minID, s16 maxID) { + for (s16 buttonID = minID; buttonID < maxID; buttonID++) { + obj_mark_for_deletion(sMainMenuButtons[buttonID]); + } +} + +/** + * Hides buttons of corresponding button menu groups. + */ +void hide_submenu_buttons(s16 prevMenuButtonID) { + switch (prevMenuButtonID) { + case MENU_BUTTON_SCORE: delete_menu_button_objects(MENU_BUTTON_SCORE_MIN, MENU_BUTTON_SCORE_MAX ); break; + case MENU_BUTTON_COPY: delete_menu_button_objects(MENU_BUTTON_COPY_MIN, MENU_BUTTON_COPY_MAX ); break; + case MENU_BUTTON_ERASE: delete_menu_button_objects(MENU_BUTTON_ERASE_MIN, MENU_BUTTON_ERASE_MAX ); break; + case MENU_BUTTON_SOUND_MODE: delete_menu_button_objects(MENU_BUTTON_OPTION_MIN, MENU_BUTTON_OPTION_MAX); break; } -#endif } /** @@ -1194,7 +856,6 @@ void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) { * the return button (or sound mode) as source button. */ void return_to_main_menu(s16 prevMenuButtonID, struct Object *sourceButton) { - s32 buttonID; // If the source button is in default state and the previous menu in full screen, // play zoom out sound and shrink previous menu if (sourceButton->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT @@ -1206,151 +867,63 @@ void return_to_main_menu(s16 prevMenuButtonID, struct Object *sourceButton) { // If the previous button is in default state, return back to the main menu if (sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT) { sSelectedButtonID = MENU_BUTTON_NONE; - // Hide buttons of corresponding button menu groups - if (prevMenuButtonID == MENU_BUTTON_SCORE) { - for (buttonID = MENU_BUTTON_SCORE_MIN; buttonID < MENU_BUTTON_SCORE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - if (prevMenuButtonID == MENU_BUTTON_COPY) { - for (buttonID = MENU_BUTTON_COPY_MIN; buttonID < MENU_BUTTON_COPY_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - if (prevMenuButtonID == MENU_BUTTON_ERASE) { - for (buttonID = MENU_BUTTON_ERASE_MIN; buttonID < MENU_BUTTON_ERASE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - if (prevMenuButtonID == MENU_BUTTON_SOUND_MODE) { - for (buttonID = MENU_BUTTON_OPTION_MIN; buttonID < MENU_BUTTON_OPTION_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } + hide_submenu_buttons(prevMenuButtonID); } } -/** - * Loads score menu from the previous menu using "CHECK SCORE" as source button. - */ -void load_score_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { - s32 buttonID; +void load_menu_from_submenu(s16 prevMenuButtonID, s16 selectedButtonID, struct Object *sourceButton) { // If the source button is in default state and the previous menu in full screen, // play zoom out sound and shrink previous menu - if (sourceButton->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT - && sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { + if ((sourceButton->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT) + && (sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN)) { play_sound(SOUND_MENU_CAMERA_ZOOM_OUT, gGlobalSoundSource); sMainMenuButtons[prevMenuButtonID]->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING; sCurrentMenuLevel = MENU_LAYER_MAIN; } // If the previous button is in default state if (sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT) { - // Hide buttons of corresponding button menu groups - //! Not possible, this is checking if the score menu was opened from the score menu! - if (prevMenuButtonID == MENU_BUTTON_SCORE) { - for (buttonID = MENU_BUTTON_SCORE_MIN; buttonID < MENU_BUTTON_SCORE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - if (prevMenuButtonID == MENU_BUTTON_COPY) { - for (buttonID = MENU_BUTTON_COPY_MIN; buttonID < MENU_BUTTON_COPY_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - if (prevMenuButtonID == MENU_BUTTON_ERASE) { - for (buttonID = MENU_BUTTON_ERASE_MIN; buttonID < MENU_BUTTON_ERASE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } + if (selectedButtonID != prevMenuButtonID) { + hide_submenu_buttons(prevMenuButtonID); } // Play zoom in sound, select score menu and render it's buttons - sSelectedButtonID = MENU_BUTTON_SCORE; + sSelectedButtonID = selectedButtonID; play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); - sMainMenuButtons[MENU_BUTTON_SCORE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - render_score_menu_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]); + sMainMenuButtons[selectedButtonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; + render_menu_buttons(selectedButtonID); } } -/** - * Loads copy menu from the previous menu using "COPY FILE" as source button. - */ +// Loads score menu from the previous menu using "CHECK SCORE" as source button. +void load_score_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { + load_menu_from_submenu(prevMenuButtonID, MENU_BUTTON_SCORE, sourceButton); +} + +// Loads copy menu from the previous menu using "COPY FILE" as source button. void load_copy_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { - s32 buttonID; - // If the source button is in default state and the previous menu in full screen, - // play zoom out sound and shrink previous menu - if (sourceButton->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT - && sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { - play_sound(SOUND_MENU_CAMERA_ZOOM_OUT, gGlobalSoundSource); - sMainMenuButtons[prevMenuButtonID]->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING; - sCurrentMenuLevel = MENU_LAYER_MAIN; - } - // If the previous button is in default state - if (sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT) { - // Hide buttons of corresponding button menu groups - if (prevMenuButtonID == MENU_BUTTON_SCORE) { - for (buttonID = MENU_BUTTON_SCORE_MIN; buttonID < MENU_BUTTON_SCORE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - //! Not possible, this is checking if the copy menu was opened from the copy menu! - if (prevMenuButtonID == MENU_BUTTON_COPY) { - for (buttonID = MENU_BUTTON_COPY_MIN; buttonID < MENU_BUTTON_COPY_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - if (prevMenuButtonID == MENU_BUTTON_ERASE) { - for (buttonID = MENU_BUTTON_ERASE_MIN; buttonID < MENU_BUTTON_ERASE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - // Play zoom in sound, select copy menu and render it's buttons - sSelectedButtonID = MENU_BUTTON_COPY; - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); - sMainMenuButtons[MENU_BUTTON_COPY]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - render_copy_menu_buttons(sMainMenuButtons[MENU_BUTTON_COPY]); - } + load_menu_from_submenu(prevMenuButtonID, MENU_BUTTON_COPY, sourceButton); } -/** - * Loads erase menu from the previous menu using "ERASE FILE" as source button. - */ +// Loads erase menu from the previous menu using "ERASE FILE" as source button. void load_erase_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButton) { - s32 buttonID; - // If the source button is in default state and the previous menu in full screen, - // play zoom out sound and shrink previous menu - if (sourceButton->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT - && sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { - play_sound(SOUND_MENU_CAMERA_ZOOM_OUT, gGlobalSoundSource); - sMainMenuButtons[prevMenuButtonID]->oMenuButtonState = MENU_BUTTON_STATE_SHRINKING; - sCurrentMenuLevel = MENU_LAYER_MAIN; - } - // If the previous button is in default state - if (sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT) { - // Hide buttons of corresponding button menu groups - if (prevMenuButtonID == MENU_BUTTON_SCORE) { - for (buttonID = MENU_BUTTON_SCORE_MIN; buttonID < MENU_BUTTON_SCORE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - if (prevMenuButtonID == MENU_BUTTON_COPY) { - for (buttonID = MENU_BUTTON_COPY_MIN; buttonID < MENU_BUTTON_COPY_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - //! Not possible, this is checking if the erase menu was opened from the erase menu! - if (prevMenuButtonID == MENU_BUTTON_ERASE) { - for (buttonID = MENU_BUTTON_ERASE_MIN; buttonID < MENU_BUTTON_ERASE_MAX; buttonID++) { - obj_mark_for_deletion(sMainMenuButtons[buttonID]); - } - } - // Play zoom in sound, select erase menu and render it's buttons - sSelectedButtonID = MENU_BUTTON_ERASE; - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); - sMainMenuButtons[MENU_BUTTON_ERASE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - render_erase_menu_buttons(sMainMenuButtons[MENU_BUTTON_ERASE]); - } + load_menu_from_submenu(prevMenuButtonID, MENU_BUTTON_ERASE, sourceButton); } +static const Vec3s sSaveFileButtonInitPositions[] = { + { -6400, 2800, 0 }, // SAVE_FILE_A + { 1500, 2800, 0 }, // SAVE_FILE_B + { -6400, 0, 0 }, // SAVE_FILE_C + { 1500, 0, 0 }, // SAVE_FILE_D +}; + +#define SPAWN_FILE_SELECT_FILE_BUTTON_INIT(saveFile) \ + spawn_object_rel_with_rot(o, (save_file_exists(saveFile) ? MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE : MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE), \ + bhvMenuButton, \ + sSaveFileButtonInitPositions[saveFile][0], \ + sSaveFileButtonInitPositions[saveFile][1], \ + sSaveFileButtonInitPositions[saveFile][2], \ + 0x0, 0x0, 0x0) + /** * Menu Buttons Menu Manager Initial Action * Creates models of the buttons in the menu. For the Mario buttons it @@ -1359,178 +932,110 @@ void load_erase_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceBut */ void bhv_menu_button_manager_init(void) { // File A - if (save_file_exists(SAVE_FILE_A) == TRUE) { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A] = - spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE, - bhvMenuButton, -6400, 2800, 0, 0, 0, 0); - } else { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A] = - spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, - bhvMenuButton, -6400, 2800, 0, 0, 0, 0); - } + sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A] = SPAWN_FILE_SELECT_FILE_BUTTON_INIT(SAVE_FILE_A); sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A]->oMenuButtonScale = 1.0f; // File B - if (save_file_exists(SAVE_FILE_B) == TRUE) { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B] = - spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE, - bhvMenuButton, 1500, 2800, 0, 0, 0, 0); - } else { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B] = - spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, - bhvMenuButton, 1500, 2800, 0, 0, 0, 0); - } + sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B] = SPAWN_FILE_SELECT_FILE_BUTTON_INIT(SAVE_FILE_B); sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B]->oMenuButtonScale = 1.0f; // File C - if (save_file_exists(SAVE_FILE_C) == TRUE) { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C] = - spawn_object_rel_with_rot(gCurrentObject, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE, - bhvMenuButton, -6400, 0, 0, 0, 0, 0); - } else { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C] = spawn_object_rel_with_rot( - gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, bhvMenuButton, -6400, 0, 0, 0, 0, 0); - } + sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C] = SPAWN_FILE_SELECT_FILE_BUTTON_INIT(SAVE_FILE_C); sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C]->oMenuButtonScale = 1.0f; // File D - if (save_file_exists(SAVE_FILE_D) == TRUE) { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D] = spawn_object_rel_with_rot( - gCurrentObject, MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE, bhvMenuButton, 1500, 0, 0, 0, 0, 0); - } else { - sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D] = spawn_object_rel_with_rot( - gCurrentObject, MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE, bhvMenuButton, 1500, 0, 0, 0, 0, 0); - } + sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D] = SPAWN_FILE_SELECT_FILE_BUTTON_INIT(SAVE_FILE_D); sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D]->oMenuButtonScale = 1.0f; // Score menu button - sMainMenuButtons[MENU_BUTTON_SCORE] = spawn_object_rel_with_rot( - gCurrentObject, MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, bhvMenuButton, -6400, -3500, 0, 0, 0, 0); + sMainMenuButtons[MENU_BUTTON_SCORE] = + spawn_object_rel_with_rot(o, MODEL_MAIN_MENU_GREEN_SCORE_BUTTON, + bhvMenuButton, -6400, -3500, 0, 0x0, 0x0, 0x0); sMainMenuButtons[MENU_BUTTON_SCORE]->oMenuButtonScale = 1.0f; // Copy menu button - sMainMenuButtons[MENU_BUTTON_COPY] = spawn_object_rel_with_rot( - gCurrentObject, MODEL_MAIN_MENU_BLUE_COPY_BUTTON, bhvMenuButton, -2134, -3500, 0, 0, 0, 0); + sMainMenuButtons[MENU_BUTTON_COPY] = + spawn_object_rel_with_rot(o, MODEL_MAIN_MENU_BLUE_COPY_BUTTON, + bhvMenuButton, -2134, -3500, 0, 0x0, 0x0, 0x0); sMainMenuButtons[MENU_BUTTON_COPY]->oMenuButtonScale = 1.0f; // Erase menu button - sMainMenuButtons[MENU_BUTTON_ERASE] = spawn_object_rel_with_rot( - gCurrentObject, MODEL_MAIN_MENU_RED_ERASE_BUTTON, bhvMenuButton, 2134, -3500, 0, 0, 0, 0); + sMainMenuButtons[MENU_BUTTON_ERASE] = + spawn_object_rel_with_rot(o, MODEL_MAIN_MENU_RED_ERASE_BUTTON, + bhvMenuButton, 2134, -3500, 0, 0x0, 0x0, 0x0); sMainMenuButtons[MENU_BUTTON_ERASE]->oMenuButtonScale = 1.0f; // Sound mode menu button (Option Mode in EU) - sMainMenuButtons[MENU_BUTTON_SOUND_MODE] = spawn_object_rel_with_rot( - gCurrentObject, MODEL_MAIN_MENU_PURPLE_SOUND_BUTTON, bhvMenuButton, 6400, -3500, 0, 0, 0, 0); + sMainMenuButtons[MENU_BUTTON_SOUND_MODE] = + spawn_object_rel_with_rot(o, MODEL_MAIN_MENU_PURPLE_SOUND_BUTTON, + bhvMenuButton, 6400, -3500, 0, 0x0, 0x0, 0x0); sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonScale = 1.0f; - sTextBaseAlpha = 0; + gDialogTextAlpha = 0; } -#ifdef VERSION_JP - #define SAVE_FILE_SOUND SOUND_MENU_STAR_SOUND -#else - #define SAVE_FILE_SOUND SOUND_MENU_STAR_SOUND_OKEY_DOKEY -#endif - /** * In the main menu, check if a button was clicked to play it's button growing state. * Also play a sound and/or render buttons depending of the button ID selected. */ void check_main_menu_clicked_buttons(void) { -#ifdef VERSION_EU - if (sMainMenuTimer >= 5) { -#endif - // Sound mode menu is handled separately because the button ID for it - // is not grouped with the IDs of the other submenus. - if (check_clicked_button(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosX, - sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosY, 200.0f) == TRUE) { - sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - sSelectedButtonID = MENU_BUTTON_SOUND_MODE; - } else { - // Main Menu buttons - s8 buttonID; - // Configure Main Menu button group - for (buttonID = MENU_BUTTON_MAIN_MIN; buttonID < MENU_BUTTON_MAIN_MAX; buttonID++) { - s16 buttonX = sMainMenuButtons[buttonID]->oPosX; - s16 buttonY = sMainMenuButtons[buttonID]->oPosY; - - if (check_clicked_button(buttonX, buttonY, 200.0f) == TRUE) { - // If menu button clicked, select it - sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - sSelectedButtonID = buttonID; - break; - } + // Sound mode menu is handled separately because the button ID for it + // is not grouped with the IDs of the other submenus. + if (check_clicked_button(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosX, + sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oPosY, 200.0f)) { + sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; + sSelectedButtonID = MENU_BUTTON_SOUND_MODE; + } else { + // Main Menu buttons + s8 buttonID; + // Configure Main Menu button group + for (buttonID = MENU_BUTTON_MAIN_MIN; buttonID < MENU_BUTTON_MAIN_MAX; buttonID++) { + s16 buttonX = sMainMenuButtons[buttonID]->oPosX; + s16 buttonY = sMainMenuButtons[buttonID]->oPosY; + + if (check_clicked_button(buttonX, buttonY, 200.0f)) { + // If menu button clicked, select it + sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; + sSelectedButtonID = buttonID; + break; } } -#ifdef VERSION_EU - // Open Options Menu if sOpenLangSettings is TRUE (It's TRUE when there's no saves) - if (sOpenLangSettings == TRUE) { - sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; - sSelectedButtonID = MENU_BUTTON_SOUND_MODE; - sOpenLangSettings = FALSE; - } -#endif + } - // Play sound of the save file clicked - switch (sSelectedButtonID) { - case MENU_BUTTON_PLAY_FILE_A: - play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(60, 70); - queue_rumble_decay(1); -#endif - break; - case MENU_BUTTON_PLAY_FILE_B: - play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(60, 70); - queue_rumble_decay(1); -#endif - break; - case MENU_BUTTON_PLAY_FILE_C: - play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(60, 70); - queue_rumble_decay(1); -#endif - break; - case MENU_BUTTON_PLAY_FILE_D: - play_sound(SAVE_FILE_SOUND, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(60, 70); - queue_rumble_decay(1); -#endif - break; - // Play sound of the button clicked and render buttons of that menu. - case MENU_BUTTON_SCORE: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(5, 80); +#ifdef MULTILANG + // Open Options Menu if sOpenLangSettings is TRUE (It's TRUE when there's no saves) + if (sOpenLangSettings && (sMainMenuTimer >= 5)) { + sMainMenuButtons[MENU_BUTTON_SOUND_MODE]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; + sSelectedButtonID = MENU_BUTTON_SOUND_MODE; + sOpenLangSettings = FALSE; + } #endif - render_score_menu_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]); - break; - case MENU_BUTTON_COPY: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(5, 80); + + // Play sound of the save file clicked + switch (sSelectedButtonID) { + case MENU_BUTTON_PLAY_FILE_A: + case MENU_BUTTON_PLAY_FILE_B: + case MENU_BUTTON_PLAY_FILE_C: + case MENU_BUTTON_PLAY_FILE_D: + play_sound(SOUND_MENU_STAR_SOUND_OKEY_DOKEY, gGlobalSoundSource); +#if ENABLE_RUMBLE + queue_rumble_data(60, 70); + queue_rumble_decay(1); #endif - render_copy_menu_buttons(sMainMenuButtons[MENU_BUTTON_COPY]); - break; - case MENU_BUTTON_ERASE: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(5, 80); + break; + // Play sound of the button clicked and render buttons of that menu. + case MENU_BUTTON_SCORE: + case MENU_BUTTON_COPY: + case MENU_BUTTON_ERASE: + play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); +#if ENABLE_RUMBLE + queue_rumble_data(5, 80); #endif - render_erase_menu_buttons(sMainMenuButtons[MENU_BUTTON_ERASE]); - break; - case MENU_BUTTON_SOUND_MODE: - play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK - queue_rumble_data(5, 80); + render_menu_buttons(sSelectedButtonID); + break; + case MENU_BUTTON_SOUND_MODE: + play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gGlobalSoundSource); +#if ENABLE_RUMBLE + queue_rumble_data(5, 80); #endif - render_sound_mode_menu_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); - break; - } -#ifdef VERSION_EU + render_sound_mode_menu_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); + break; } -#endif } -#undef SAVE_FILE_SOUND - /** * Menu Buttons Menu Manager Loop Action * Calls a menu function depending of the button chosen. @@ -1539,116 +1044,54 @@ void check_main_menu_clicked_buttons(void) { */ void bhv_menu_button_manager_loop(void) { switch (sSelectedButtonID) { - case MENU_BUTTON_NONE: - check_main_menu_clicked_buttons(); - break; - case MENU_BUTTON_PLAY_FILE_A: - load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A], 1); - break; - case MENU_BUTTON_PLAY_FILE_B: - load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B], 2); - break; - case MENU_BUTTON_PLAY_FILE_C: - load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C], 3); - break; - case MENU_BUTTON_PLAY_FILE_D: - load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D], 4); - break; - case MENU_BUTTON_SCORE: - check_score_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]); - break; - case MENU_BUTTON_COPY: - check_copy_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_COPY]); - break; - case MENU_BUTTON_ERASE: - check_erase_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_ERASE]); - break; + case MENU_BUTTON_NONE: check_main_menu_clicked_buttons(); break; - case MENU_BUTTON_SCORE_FILE_A: - exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A], MENU_BUTTON_SCORE); - break; - case MENU_BUTTON_SCORE_FILE_B: - exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B], MENU_BUTTON_SCORE); - break; - case MENU_BUTTON_SCORE_FILE_C: - exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C], MENU_BUTTON_SCORE); - break; - case MENU_BUTTON_SCORE_FILE_D: - exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D], MENU_BUTTON_SCORE); - break; - case MENU_BUTTON_SCORE_RETURN: - return_to_main_menu(MENU_BUTTON_SCORE, sMainMenuButtons[MENU_BUTTON_SCORE_RETURN]); - break; - case MENU_BUTTON_SCORE_COPY_FILE: - load_copy_menu_from_submenu(MENU_BUTTON_SCORE, - sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE]); - break; - case MENU_BUTTON_SCORE_ERASE_FILE: - load_erase_menu_from_submenu(MENU_BUTTON_SCORE, - sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE]); - break; + case MENU_BUTTON_PLAY_FILE_A: load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_A], 1); break; + case MENU_BUTTON_PLAY_FILE_B: load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_B], 2); break; + case MENU_BUTTON_PLAY_FILE_C: load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_C], 3); break; + case MENU_BUTTON_PLAY_FILE_D: load_main_menu_save_file(sMainMenuButtons[MENU_BUTTON_PLAY_FILE_D], 4); break; - case MENU_BUTTON_COPY_FILE_A: - break; - case MENU_BUTTON_COPY_FILE_B: - break; - case MENU_BUTTON_COPY_FILE_C: - break; - case MENU_BUTTON_COPY_FILE_D: - break; - case MENU_BUTTON_COPY_RETURN: - return_to_main_menu(MENU_BUTTON_COPY, sMainMenuButtons[MENU_BUTTON_COPY_RETURN]); - break; - case MENU_BUTTON_COPY_CHECK_SCORE: - load_score_menu_from_submenu(MENU_BUTTON_COPY, - sMainMenuButtons[MENU_BUTTON_COPY_CHECK_SCORE]); - break; - case MENU_BUTTON_COPY_ERASE_FILE: - load_erase_menu_from_submenu(MENU_BUTTON_COPY, - sMainMenuButtons[MENU_BUTTON_COPY_ERASE_FILE]); - break; + case MENU_BUTTON_SCORE: check_score_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_SCORE]); break; + case MENU_BUTTON_COPY: check_copy_menu_clicked_buttons (sMainMenuButtons[MENU_BUTTON_COPY ]); break; + case MENU_BUTTON_ERASE: check_erase_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_ERASE]); break; - case MENU_BUTTON_ERASE_FILE_A: - break; - case MENU_BUTTON_ERASE_FILE_B: - break; - case MENU_BUTTON_ERASE_FILE_C: - break; - case MENU_BUTTON_ERASE_FILE_D: - break; - case MENU_BUTTON_ERASE_RETURN: - return_to_main_menu(MENU_BUTTON_ERASE, sMainMenuButtons[MENU_BUTTON_ERASE_RETURN]); - break; - case MENU_BUTTON_ERASE_CHECK_SCORE: - load_score_menu_from_submenu(MENU_BUTTON_ERASE, - sMainMenuButtons[MENU_BUTTON_ERASE_CHECK_SCORE]); - break; - case MENU_BUTTON_ERASE_COPY_FILE: - load_copy_menu_from_submenu(MENU_BUTTON_ERASE, - sMainMenuButtons[MENU_BUTTON_ERASE_COPY_FILE]); - break; + case MENU_BUTTON_SCORE_FILE_A: exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_A], MENU_BUTTON_SCORE); break; + case MENU_BUTTON_SCORE_FILE_B: exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_B], MENU_BUTTON_SCORE); break; + case MENU_BUTTON_SCORE_FILE_C: exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_C], MENU_BUTTON_SCORE); break; + case MENU_BUTTON_SCORE_FILE_D: exit_score_file_to_score_menu(sMainMenuButtons[MENU_BUTTON_SCORE_FILE_D], MENU_BUTTON_SCORE); break; - case MENU_BUTTON_SOUND_MODE: - check_sound_mode_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); - break; + case MENU_BUTTON_SCORE_RETURN: return_to_main_menu (MENU_BUTTON_SCORE, sMainMenuButtons[MENU_BUTTON_SCORE_RETURN ]); break; + case MENU_BUTTON_SCORE_COPY_FILE: load_copy_menu_from_submenu (MENU_BUTTON_SCORE, sMainMenuButtons[MENU_BUTTON_SCORE_COPY_FILE ]); break; + case MENU_BUTTON_SCORE_ERASE_FILE: load_erase_menu_from_submenu(MENU_BUTTON_SCORE, sMainMenuButtons[MENU_BUTTON_SCORE_ERASE_FILE]); break; + + case MENU_BUTTON_COPY_FILE_A: break; + case MENU_BUTTON_COPY_FILE_B: break; + case MENU_BUTTON_COPY_FILE_C: break; + case MENU_BUTTON_COPY_FILE_D: break; + case MENU_BUTTON_COPY_RETURN: return_to_main_menu (MENU_BUTTON_COPY, sMainMenuButtons[MENU_BUTTON_COPY_RETURN ]); break; + case MENU_BUTTON_COPY_CHECK_SCORE: load_score_menu_from_submenu(MENU_BUTTON_COPY, sMainMenuButtons[MENU_BUTTON_COPY_CHECK_SCORE]); break; + case MENU_BUTTON_COPY_ERASE_FILE: load_erase_menu_from_submenu(MENU_BUTTON_COPY, sMainMenuButtons[MENU_BUTTON_COPY_ERASE_FILE ]); break; + + case MENU_BUTTON_ERASE_FILE_A: break; + case MENU_BUTTON_ERASE_FILE_B: break; + case MENU_BUTTON_ERASE_FILE_C: break; + case MENU_BUTTON_ERASE_FILE_D: break; + + case MENU_BUTTON_ERASE_RETURN: return_to_main_menu (MENU_BUTTON_ERASE, sMainMenuButtons[MENU_BUTTON_ERASE_RETURN ]); break; + case MENU_BUTTON_ERASE_CHECK_SCORE: load_score_menu_from_submenu(MENU_BUTTON_ERASE, sMainMenuButtons[MENU_BUTTON_ERASE_CHECK_SCORE]); break; + case MENU_BUTTON_ERASE_COPY_FILE: load_copy_menu_from_submenu (MENU_BUTTON_ERASE, sMainMenuButtons[MENU_BUTTON_ERASE_COPY_FILE ]); break; + + case MENU_BUTTON_SOUND_MODE: check_sound_mode_menu_clicked_buttons(sMainMenuButtons[MENU_BUTTON_SOUND_MODE]); break; + +#ifdef MULTILANG + case MENU_BUTTON_OPTION_RETURN: return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_OPTION_RETURN]); break; +#endif // STEREO, MONO and HEADSET buttons are undefined so they can be selected without // exiting the Options menu, as a result they added a return button -#ifdef VERSION_EU - case MENU_BUTTON_LANGUAGE_RETURN: - return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_LANGUAGE_RETURN]); - break; -#else - case MENU_BUTTON_STEREO: - return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_STEREO]); - break; - case MENU_BUTTON_MONO: - return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_MONO]); - break; - case MENU_BUTTON_HEADSET: - return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_HEADSET]); - break; -#endif + case MENU_BUTTON_STEREO: return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_STEREO ]); break; + case MENU_BUTTON_MONO: return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_MONO ]); break; + case MENU_BUTTON_HEADSET: return_to_main_menu(MENU_BUTTON_SOUND_MODE, sMainMenuButtons[MENU_BUTTON_HEADSET]); break; } sClickPos[0] = -10000; @@ -1664,12 +1107,7 @@ void handle_cursor_button_input(void) { if (sSelectedButtonID == MENU_BUTTON_SCORE_FILE_A || sSelectedButtonID == MENU_BUTTON_SCORE_FILE_B || sSelectedButtonID == MENU_BUTTON_SCORE_FILE_C || sSelectedButtonID == MENU_BUTTON_SCORE_FILE_D) { - if (gPlayer3Controller->buttonPressed - & (B_BUTTON | START_BUTTON -#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION - | Z_TRIG -#endif - )) { + if (gPlayer3Controller->buttonPressed & (B_BUTTON | START_BUTTON | Z_TRIG)) { sClickPos[0] = sCursorPos[0]; sClickPos[1] = sCursorPos[1]; sCursorClickingTimer = 1; @@ -1679,11 +1117,7 @@ void handle_cursor_button_input(void) { } } else { // If cursor is clicked if (gPlayer3Controller->buttonPressed - & (A_BUTTON | B_BUTTON | START_BUTTON -#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION - | Z_TRIG -#endif - )) { + & (A_BUTTON | B_BUTTON | START_BUTTON)) { sClickPos[0] = sCursorPos[0]; sClickPos[1] = sCursorPos[1]; sCursorClickingTimer = 1; @@ -1702,53 +1136,20 @@ void handle_controller_cursor_input(void) { if (rawStickY > -2 && rawStickY < 2) { rawStickY = 0; } - #ifdef MOUSE_ACTIONS - else - { - gMouseHasFreeControl = FALSE; - } - #endif if (rawStickX > -2 && rawStickX < 2) { rawStickX = 0; } - #ifdef MOUSE_ACTIONS - else - { - gMouseHasFreeControl = FALSE; - } - #endif // Move cursor sCursorPos[0] += rawStickX / 8; sCursorPos[1] += rawStickY / 8; -#ifdef MOUSE_ACTIONS - if (sSelectedFileNum != 0) - gMouseHasFreeControl = FALSE; - - if ((gMouseXPos - gOldMouseXPos != 0 || gMouseYPos - gOldMouseYPos != 0) && sSelectedFileNum == 0) { - gMouseHasFreeControl = TRUE; - } - - static float screenScale; - screenScale = (float) gfx_current_dimensions.height / SCREEN_HEIGHT; - if (gMouseHasFreeControl && configMouse) { - sCursorPos[0] = ((gMouseXPos - (gfx_current_dimensions.width - (screenScale * 320)) / 2) / screenScale) - 160.0f; - sCursorPos[1] = (gMouseYPos / screenScale - 120.0f) * -1; - } - - gOldMouseXPos = gMouseXPos; - gOldMouseYPos = gMouseYPos; - -if (!gMouseHasFreeControl) { -#endif - // Stop cursor from going offscreen - if (sCursorPos[0] > GFX_DIMENSIONS_FROM_RIGHT_EDGE(188.0f)) { - sCursorPos[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(188.0f); + if (sCursorPos[0] > 132.0f) { + sCursorPos[0] = 132.0f; } - if (sCursorPos[0] < GFX_DIMENSIONS_FROM_LEFT_EDGE(-132.0f)) { - sCursorPos[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(-132.0f); + if (sCursorPos[0] < -132.0f) { + sCursorPos[0] = -132.0f; } if (sCursorPos[1] > 90.0f) { @@ -1757,9 +1158,6 @@ if (!gMouseHasFreeControl) { if (sCursorPos[1] < -90.0f) { sCursorPos[1] = -90.0f; } -#ifdef MOUSE_ACTIONS -} -#endif if (sCursorClickingTimer == 0) { handle_cursor_button_input(); @@ -1775,14 +1173,12 @@ void print_menu_cursor(void) { handle_controller_cursor_input(); create_dl_translation_matrix(MENU_MTX_PUSH, sCursorPos[0] + 160.0f - 5.0, sCursorPos[1] + 120.0f - 25.0, 0.0f); // Get the right graphic to use for the cursor. - if (sCursorClickingTimer == 0) { + if (sCursorClickingTimer == 0) // Idle gSPDisplayList(gDisplayListHead++, dl_menu_idle_hand); - } - if (sCursorClickingTimer != 0) { + if (sCursorClickingTimer != 0) // Grabbing gSPDisplayList(gDisplayListHead++, dl_menu_grabbing_hand); - } gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); if (sCursorClickingTimer != 0) { sCursorClickingTimer++; // This is a very strange way to implement a timer? It counts up and @@ -1794,22 +1190,49 @@ void print_menu_cursor(void) { } /** - * Prints a hud string depending of the hud table list defined with text fade properties. + * Takes a number between 0 and 3 and formats the corresponding file letter A to D into a buffer. + * If the language is set to Japanese, the letter is written in full-width digits. */ -void print_hud_lut_string_fade(s8 hudLUT, s16 x, s16 y, const unsigned char *text) { +void string_format_file_letter(char *buf, char *str, s32 fileIndex) { + char letterBuf[4]; +#ifdef ENABLE_JAPANESE + if (gInGameLanguage == LANGUAGE_JAPANESE) { + // The UTF-8 encoding of "A" is 0xEF, 0xBC, 0xA1 + letterBuf[0] = 0xEF; + letterBuf[1] = 0xBC; + letterBuf[2] = 0xA1 + fileIndex; + letterBuf[3] = '\0'; + sprintf(buf, str, letterBuf); + return; + } +#endif + + letterBuf[0] = 'A' + fileIndex; + letterBuf[1] = '\0'; + sprintf(buf, str, letterBuf); +} + +/** + * Prints a hud string with text fade properties. + */ +void print_hud_lut_string_fade(s16 x, s16 y, char *text, u32 alignment) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha - sTextFadeAlpha); - print_hud_lut_string(hudLUT, x, y, text); + gDialogTextAlpha -= sTextFadeAlpha; + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_hud_lut_string_aligned(x, y, text, alignment); + gDialogTextAlpha += sTextFadeAlpha; gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); } /** * Prints a generic white string with text fade properties. */ -void print_generic_string_fade(s16 x, s16 y, const unsigned char *text) { +void print_generic_string_fade(s16 x, s16 y, char *text, u32 alignment) { gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha - sTextFadeAlpha); - print_generic_string(x, y, text); + gDialogTextAlpha -= sTextFadeAlpha; + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string_aligned(x, y, text, alignment); + gDialogTextAlpha += sTextFadeAlpha; gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } @@ -1835,59 +1258,110 @@ s32 update_text_fade_out(void) { * Prints the amount of stars of a save file. * If a save doesn't exist, print "NEW" instead. */ +LangArray textNew = DEFINE_LANGUAGE_ARRAY( + "NEW", + "VIDE", + "FREI", + "NEW"); + void print_save_file_star_count(s8 fileIndex, s16 x, s16 y) { - u8 starCountText[4]; - s8 offset = 0; - s16 starCount; - - if (save_file_exists(fileIndex) == TRUE) { - starCount = save_file_get_total_star_count(fileIndex, COURSE_MIN - 1, COURSE_MAX - 1); - // Print star icon - print_hud_lut_string(HUD_LUT_GLOBAL, x, y, starIcon); - // If star count is less than 100, print x icon and move - // the star count text one digit to the right. + char starCountText[10]; + + if (save_file_exists(fileIndex)) { + s16 starCount = save_file_get_total_star_count(fileIndex, + COURSE_NUM_TO_INDEX(COURSE_MIN), + COURSE_NUM_TO_INDEX(COURSE_MAX)); + if (starCount < 100) { - print_hud_lut_string(HUD_LUT_GLOBAL, x + 16, y, xIcon); - offset = 16; + sprintf(starCountText, "★×%d", starCount); + } else { + sprintf(starCountText, "★%d", starCount); } - // Print star count - int_to_str(starCount, starCountText); - print_hud_lut_string(HUD_LUT_GLOBAL, x + offset + 16, y, starCountText); + print_hud_lut_string(x, y, starCountText); } else { // Print "new" text - print_hud_lut_string(HUD_LUT_GLOBAL, x, y, LANGUAGE_ARRAY(textNew)); + print_hud_lut_string(x, y, LANG_ARRAY(textNew)); } } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define SELECT_FILE_X 96 - #define SCORE_X 50 - #define COPY_X 115 - #define ERASE_X 180 -#ifdef VERSION_JP - #define SOUNDMODE_X1 235 -#else - #define SOUNDMODE_X1 sSoundTextX -#endif - #define SAVEFILE_X1 92 - #define SAVEFILE_X2 209 - #define MARIOTEXT_X1 92 - #define MARIOTEXT_X2 207 -#elif defined(VERSION_US) - #define SELECT_FILE_X 93 - #define SCORE_X 52 - #define COPY_X 117 - #define ERASE_X 177 - #define SOUNDMODE_X1 sSoundTextX - #define SAVEFILE_X1 92 - #define SAVEFILE_X2 209 - #define MARIOTEXT_X1 92 - #define MARIOTEXT_X2 207 -#elif defined(VERSION_EU) - #define SAVEFILE_X1 97 - #define SAVEFILE_X2 204 - #define MARIOTEXT_X1 97 - #define MARIOTEXT_X2 204 +LangArray textSelectFile = DEFINE_LANGUAGE_ARRAY( + "SELECT FILE", + "CHOISIR FICHIER", + "WÄHLE SPIEL", + "ファイルセレクト"); + +LangArray textScore = DEFINE_LANGUAGE_ARRAY( + "SCORE", + "SCORE", + "LEISTUNG", + "スコア"); + +LangArray textCopy = DEFINE_LANGUAGE_ARRAY( + "COPY", + "COPIER", + "KOPIEREN", + "コピー"); + +LangArray textErase = DEFINE_LANGUAGE_ARRAY( + "ERASE", + "EFFACER", + "LÖSCHEN", + "けす"); + +LangArray textMarioA = DEFINE_LANGUAGE_ARRAY( + "MARIO A", + "MARIO A", + "MARIO A", + "マリオA"); + +LangArray textMarioB = DEFINE_LANGUAGE_ARRAY( + "MARIO B", + "MARIO B", + "MARIO B", + "マリオB"); + +LangArray textMarioC = DEFINE_LANGUAGE_ARRAY( + "MARIO C", + "MARIO C", + "MARIO C", + "マリオC"); + +LangArray textMarioD = DEFINE_LANGUAGE_ARRAY( + "MARIO D", + "MARIO D", + "MARIO D", + "マリオD"); + +LangArray textSoundModeStereo = DEFINE_LANGUAGE_ARRAY( + "STEREO", + "STÉRÉO", + "STEREO", + "ステレオ"); + +LangArray textSoundModeMono = DEFINE_LANGUAGE_ARRAY( + "MONO", + "MONO", + "MONO", + "モノラル"); + +LangArray textSoundModeHeadset = DEFINE_LANGUAGE_ARRAY( + "HEADSET", + "CASQUE", + "PHONES", + "ヘッドホン"); + +LangArray *textSoundModes[] = { + &textSoundModeStereo, + &textSoundModeMono, + &textSoundModeHeadset +}; + +#ifdef MULTILANG +LangArray textOption = DEFINE_LANGUAGE_ARRAY( + "OPTION", + "OPTION", + "OPTIONEN", + "オプション"); #endif /** @@ -1898,146 +1372,99 @@ void print_save_file_star_count(s8 fileIndex, s16 x, s16 y) { * Same rule applies for score, copy and erase strings. */ void print_main_menu_strings(void) { -#ifdef VERSION_SH - // The current sound mode is automatically centered on US and Shindou. - static s16 sSoundTextX; // TODO: There should be a way to make this match on both US and Shindou. -#endif // Print "SELECT FILE" text gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); -#ifndef VERSION_EU - print_hud_lut_string(HUD_LUT_DIFF, SELECT_FILE_X, 35, textSelectFile); -#endif + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_hud_lut_string_aligned(SCREEN_CENTER_X, 35, LANG_ARRAY(textSelectFile), TEXT_ALIGN_CENTER); // Print file star counts - print_save_file_star_count(SAVE_FILE_A, SAVEFILE_X1, 78); - print_save_file_star_count(SAVE_FILE_B, SAVEFILE_X2, 78); - print_save_file_star_count(SAVE_FILE_C, SAVEFILE_X1, 118); - print_save_file_star_count(SAVE_FILE_D, SAVEFILE_X2, 118); + print_save_file_star_count(SAVE_FILE_A, 92, 78); + print_save_file_star_count(SAVE_FILE_B, 209, 78); + print_save_file_star_count(SAVE_FILE_C, 92, 118); + print_save_file_star_count(SAVE_FILE_D, 209, 118); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); -#ifndef VERSION_EU // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_generic_string(SCORE_X, 39, textScore); - print_generic_string(COPY_X, 39, textCopy); - print_generic_string(ERASE_X, 39, textErase); -#ifndef VERSION_JP - sSoundTextX = get_str_x_pos_from_center(254, textSoundModes[sSoundMode], 10.0f); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string_aligned(67, 39, LANG_ARRAY(textScore), TEXT_ALIGN_CENTER); + print_generic_string_aligned(130, 39, LANG_ARRAY(textCopy), TEXT_ALIGN_CENTER); + print_generic_string_aligned(191, 39, LANG_ARRAY(textErase), TEXT_ALIGN_CENTER); +#ifdef MULTILANG + print_generic_string_aligned(253, 39, LANG_ARRAY(textOption), TEXT_ALIGN_CENTER); +#else + print_generic_string_aligned(253, 39, LANG_ARRAY(*textSoundModes[sSoundMode]), TEXT_ALIGN_CENTER); #endif - print_generic_string(SOUNDMODE_X1, 39, textSoundModes[sSoundMode]); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); -#endif // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_menu_generic_string(MARIOTEXT_X1, 65, textMarioA); - print_menu_generic_string(MARIOTEXT_X2, 65, textMarioB); - print_menu_generic_string(MARIOTEXT_X1, 105, textMarioC); - print_menu_generic_string(MARIOTEXT_X2, 105, textMarioD); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_menu_generic_string(92, 65, LANG_ARRAY(textMarioA)); + print_menu_generic_string(207, 65, LANG_ARRAY(textMarioB)); + print_menu_generic_string(92, 105, LANG_ARRAY(textMarioC)); + print_menu_generic_string(207, 105, LANG_ARRAY(textMarioD)); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); } -#ifdef VERSION_EU -/** - * Prints the first part main menu strings that shows on the yellow background menu screen. - * Has the strings for the 4 buttons below the save buttons that get changed depending of the language. - * Calls print_main_menu_strings to print the remaining strings. - */ -void print_main_lang_strings(void) { - static s16 centeredX; +LangArray textCheckFile = DEFINE_LANGUAGE_ARRAY( + "CHECK FILE", + "VOIR SCORE", + "VON WELCHEM SPIEL", + "どのスコアをみる?"); - // Print "SELECT FILE" text - gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - centeredX = get_str_x_pos_from_center_scale(160, textSelectFile[sLanguageMode], 12.0f); - print_hud_lut_string(HUD_LUT_GLOBAL, centeredX, 35, textSelectFile[sLanguageMode]); - gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); - - // Print menu names - gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - centeredX = get_str_x_pos_from_center(76, textScore[sLanguageMode], 10.0f); - print_generic_string(centeredX, 39, textScore[sLanguageMode]); - centeredX = get_str_x_pos_from_center(131, textCopy[sLanguageMode], 10.0f); - print_generic_string(centeredX, 39, textCopy[sLanguageMode]); - centeredX = get_str_x_pos_from_center(189, textErase[sLanguageMode], 10.0f); - print_generic_string(centeredX, 39, textErase[sLanguageMode]); - centeredX = get_str_x_pos_from_center(245, textOption[sLanguageMode], 10.0f); - print_generic_string(centeredX, 39, textOption[sLanguageMode]); - gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - - print_main_menu_strings(); -} -#endif - -#if defined(VERSION_JP) || defined(VERSION_SH) - #define CHECK_FILE_X 90 - #define NOSAVE_DATA_X1 90 -#elif defined(VERSION_US) - #define CHECK_FILE_X 95 - #define NOSAVE_DATA_X1 99 -#elif defined(VERSION_EU) - #define CHECK_FILE_X checkFileX - #define NOSAVE_DATA_X1 noSaveDataX -#endif +LangArray textNoSavedDataExists = DEFINE_LANGUAGE_ARRAY( + "NO SAVED DATA EXISTS", + "AUCUNE SAUVEGARDE DISPONIBLE", + "KEIN SPIEL VORHANDEN", + "ファイルにデータがありません"); /** * Defines IDs for the top message of the score menu and displays it if the ID is called in messageID. */ void score_menu_display_message(s8 messageID) { -#ifdef VERSION_EU - s16 checkFileX, noSaveDataX; -#endif switch (messageID) { case SCORE_MSG_CHECK_FILE: -#ifdef VERSION_EU - checkFileX = get_str_x_pos_from_center_scale(160, LANGUAGE_ARRAY(textCheckFile), 12.0f); -#endif - print_hud_lut_string_fade(HUD_LUT_DIFF, CHECK_FILE_X, 35, LANGUAGE_ARRAY(textCheckFile)); + print_hud_lut_string_fade(SCREEN_CENTER_X, 35, LANG_ARRAY(textCheckFile), TEXT_ALIGN_CENTER); break; case SCORE_MSG_NOSAVE_DATA: -#ifdef VERSION_EU - noSaveDataX = get_str_x_pos_from_center(160, LANGUAGE_ARRAY(textNoSavedDataExists), 10.0f); -#endif - print_generic_string_fade(NOSAVE_DATA_X1, 190, LANGUAGE_ARRAY(textNoSavedDataExists)); + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textNoSavedDataExists), TEXT_ALIGN_CENTER); break; } } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define RETURN_X 45 - #define COPYFILE_X1 128 - #define ERASEFILE_X1 228 -#elif defined(VERSION_US) - #define RETURN_X 44 - #define COPYFILE_X1 135 - #define ERASEFILE_X1 231 -#elif defined(VERSION_EU) - #define RETURN_X centeredX - #define COPYFILE_X1 centeredX - #define ERASEFILE_X1 centeredX -#endif +#define SUBMENU_LEFT_BUTTON_X 62 +#define SUBMENU_MIDDLE_BUTTON_X 160 +#define SUBMENU_RIGHT_BUTTON_X 258 -#ifdef VERSION_EU - #define FADEOUT_TIMER 35 -#else - #define FADEOUT_TIMER 20 -#endif +#define FADEOUT_TIMER 20 + +LangArray textReturn = DEFINE_LANGUAGE_ARRAY( + "RETURN", + "RETOUR", + "ZURÜCK", + "もどる"); + +LangArray textCopyFileButton = DEFINE_LANGUAGE_ARRAY( + "COPY FILE", + "COPIER", + "KOPIEREN", + "ファイルコピー"); + +LangArray textEraseFileButton = DEFINE_LANGUAGE_ARRAY( + "ERASE FILE", + "EFFACER", + "LÖSCHEN", + "ファイルけす"); /** * Prints score menu strings that shows on the green background menu screen. */ void print_score_menu_strings(void) { -#ifdef VERSION_EU - s16 centeredX; -#endif // Update and print the message at the top of the menu. if (sMainMenuTimer == FADEOUT_TIMER) { sFadeOutText = TRUE; } - if (update_text_fade_out() == TRUE) { + if (update_text_fade_out()) { if (sStatusMessageID == SCORE_MSG_CHECK_FILE) { sStatusMessageID = SCORE_MSG_NOSAVE_DATA; } else { @@ -2047,118 +1474,87 @@ void print_score_menu_strings(void) { // Print messageID called above score_menu_display_message(sStatusMessageID); -#ifndef VERSION_EU // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); print_save_file_star_count(SAVE_FILE_A, 90, 76); print_save_file_star_count(SAVE_FILE_B, 211, 76); print_save_file_star_count(SAVE_FILE_C, 90, 119); print_save_file_star_count(SAVE_FILE_D, 211, 119); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); -#endif // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(69, textReturn[sLanguageMode], 10.0f); -#endif - print_generic_string(RETURN_X, 35, LANGUAGE_ARRAY(textReturn)); -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(159, textCopyFileButton[sLanguageMode], 10.0f); -#endif - print_generic_string(COPYFILE_X1, 35, LANGUAGE_ARRAY(textCopyFileButton)); -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(249, textEraseFileButton[sLanguageMode], 10.0f); -#endif - print_generic_string(ERASEFILE_X1, 35, LANGUAGE_ARRAY(textEraseFileButton)); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string_aligned(SUBMENU_LEFT_BUTTON_X, 35, LANG_ARRAY(textReturn), TEXT_ALIGN_CENTER); + print_generic_string_aligned(SUBMENU_MIDDLE_BUTTON_X, 35, LANG_ARRAY(textCopyFileButton), TEXT_ALIGN_CENTER); + print_generic_string_aligned(SUBMENU_RIGHT_BUTTON_X, 35, LANG_ARRAY(textEraseFileButton), TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); -#ifdef VERSION_EU - print_main_menu_strings(); -#else // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_menu_generic_string(89, 62, textMarioA); - print_menu_generic_string(211, 62, textMarioB); - print_menu_generic_string(89, 105, textMarioC); - print_menu_generic_string(211, 105, textMarioD); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_menu_generic_string(89, 62, LANG_ARRAY(textMarioA)); + print_menu_generic_string(211, 62, LANG_ARRAY(textMarioB)); + print_menu_generic_string(89, 105, LANG_ARRAY(textMarioC)); + print_menu_generic_string(211, 105, LANG_ARRAY(textMarioD)); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); -#endif } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define NOFILE_COPY_X 90 - #define COPY_FILE_X 90 - #define COPYIT_WHERE_X 90 - #define NOSAVE_DATA_X2 90 - #define COPYCOMPLETE_X 90 - #define SAVE_EXISTS_X1 90 -#elif defined(VERSION_US) - #define NOFILE_COPY_X 119 - #define COPY_FILE_X 104 - #define COPYIT_WHERE_X 109 - #define NOSAVE_DATA_X2 101 - #define COPYCOMPLETE_X 110 - #define SAVE_EXISTS_X1 110 -#elif defined(VERSION_EU) - #define NOFILE_COPY_X centeredX - #define COPY_FILE_X centeredX - #define COPYIT_WHERE_X centeredX - #define NOSAVE_DATA_X2 centeredX - #define COPYCOMPLETE_X centeredX - #define SAVE_EXISTS_X1 centeredX -#endif +LangArray textCopyFile = DEFINE_LANGUAGE_ARRAY( + "COPY FILE", + "COPIER FICHIER", + "SPIEL KOPIEREN", + "ファイルコピーする"); + +LangArray textCopyItToWhere = DEFINE_LANGUAGE_ARRAY( + "COPY IT TO WHERE?", + "COPIER SUR?", + "WOHIN KOPIEREN?", + "どこにコピーしますか?"); + +LangArray textCopyCompleted = DEFINE_LANGUAGE_ARRAY( + "COPYING COMPLETED", + "COPIE ACHEVEÉ", + "SPIEL KOPIERT", + "コピーおわりました"); + +LangArray textSavedDataExists = DEFINE_LANGUAGE_ARRAY( + "SAVED DATA EXISTS", + "SAVEGARDE EXISTANTE", + "BEREITS BELEGT", + "ファイルにデータがはいってます"); + +LangArray textNoFileToCopyFrom = DEFINE_LANGUAGE_ARRAY( + "NO EMPTY FILE", + "AUCUN FICHIER VIDE", + "KEIN PLATZ VORHANDEN", + "からのファイルがありません"); /** * Defines IDs for the top message of the copy menu and displays it if the ID is called in messageID. */ void copy_menu_display_message(s8 messageID) { -#ifdef VERSION_EU - s16 centeredX; -#endif switch (messageID) { case COPY_MSG_MAIN_TEXT: - if (sAllFilesExist == TRUE) { -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textNoFileToCopyFrom[sLanguageMode], 10.0f); -#endif - print_generic_string_fade(NOFILE_COPY_X, 190, LANGUAGE_ARRAY(textNoFileToCopyFrom)); + if (sAllFilesExist) { + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textNoFileToCopyFrom), TEXT_ALIGN_CENTER); } else { -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center_scale(160, textCopyFile[sLanguageMode], 12.0f); -#endif - print_hud_lut_string_fade(HUD_LUT_DIFF, COPY_FILE_X, 35, LANGUAGE_ARRAY(textCopyFile)); + print_hud_lut_string_fade(SCREEN_CENTER_X, 35, LANG_ARRAY(textCopyFile), TEXT_ALIGN_CENTER); } break; case COPY_MSG_COPY_WHERE: -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textCopyItToWhere[sLanguageMode], 10.0f); -#endif - print_generic_string_fade(COPYIT_WHERE_X, 190, LANGUAGE_ARRAY(textCopyItToWhere)); + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textCopyItToWhere), TEXT_ALIGN_CENTER); break; case COPY_MSG_NOSAVE_EXISTS: -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textNoSavedDataExists[sLanguageMode], 10.0f); - print_generic_string_fade(NOSAVE_DATA_X2, 190, textNoSavedDataExists[sLanguageMode]); -#else - print_generic_string_fade(NOSAVE_DATA_X2, 190, textNoSavedDataExistsCopy); -#endif + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textNoSavedDataExists), TEXT_ALIGN_CENTER); break; case COPY_MSG_COPY_COMPLETE: -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textCopyCompleted[sLanguageMode], 10.0f); -#endif - print_generic_string_fade(COPYCOMPLETE_X, 190, LANGUAGE_ARRAY(textCopyCompleted)); + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textCopyCompleted), TEXT_ALIGN_CENTER); break; case COPY_MSG_SAVE_EXISTS: -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textSavedDataExists[sLanguageMode], 10.0f); -#endif - print_generic_string_fade(SAVE_EXISTS_X1, 190, LANGUAGE_ARRAY(textSavedDataExists)); + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textSavedDataExists), TEXT_ALIGN_CENTER); break; } } @@ -2208,116 +1604,78 @@ void copy_menu_update_message(void) { } } -#if defined(VERSION_JP) - #define VIEWSCORE_X1 133 - #define ERASEFILE_X2 220 -#elif defined(VERSION_US) - #define VIEWSCORE_X1 128 - #define ERASEFILE_X2 230 -#elif defined(VERSION_EU) - #define VIEWSCORE_X1 centeredX - #define ERASEFILE_X2 centeredX -#elif defined(VERSION_SH) - #define VIEWSCORE_X1 133 - #define ERASEFILE_X2 230 -#endif +LangArray textViewScore = DEFINE_LANGUAGE_ARRAY( + "CHECK SCORE", + "SCORE", + "LEISTUNG", + "スコアをみる"); /** * Prints copy menu strings that shows on the blue background menu screen. */ void print_copy_menu_strings(void) { -#ifdef VERSION_EU - s16 centeredX; -#endif // Update and print the message at the top of the menu. copy_menu_update_message(); // Print messageID called inside a copy_menu_update_message case copy_menu_display_message(sStatusMessageID); -#ifndef VERSION_EU // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); print_save_file_star_count(SAVE_FILE_A, 90, 76); print_save_file_star_count(SAVE_FILE_B, 211, 76); print_save_file_star_count(SAVE_FILE_C, 90, 119); print_save_file_star_count(SAVE_FILE_D, 211, 119); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); -#endif // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(69, textReturn[sLanguageMode], 10.0f); -#endif - print_generic_string(RETURN_X, 35, LANGUAGE_ARRAY(textReturn)); -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(159, textViewScore[sLanguageMode], 10.0f); -#endif - print_generic_string(VIEWSCORE_X1, 35, LANGUAGE_ARRAY(textViewScore)); -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(249, textEraseFileButton[sLanguageMode], 10.0f); -#endif - print_generic_string(ERASEFILE_X2, 35, LANGUAGE_ARRAY(textEraseFileButton)); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string_aligned(SUBMENU_LEFT_BUTTON_X, 35, LANG_ARRAY(textReturn), TEXT_ALIGN_CENTER); + print_generic_string_aligned(SUBMENU_MIDDLE_BUTTON_X, 35, LANG_ARRAY(textViewScore), TEXT_ALIGN_CENTER); + print_generic_string_aligned(SUBMENU_RIGHT_BUTTON_X, 35, LANG_ARRAY(textEraseFileButton), TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); -#ifdef VERSION_EU - print_main_menu_strings(); -#else // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_menu_generic_string(89, 62, textMarioA); - print_menu_generic_string(211, 62, textMarioB); - print_menu_generic_string(89, 105, textMarioC); - print_menu_generic_string(211, 105, textMarioD); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_menu_generic_string(89, 62, LANG_ARRAY(textMarioA)); + print_menu_generic_string(211, 62, LANG_ARRAY(textMarioB)); + print_menu_generic_string(89, 105, LANG_ARRAY(textMarioC)); + print_menu_generic_string(211, 105, LANG_ARRAY(textMarioD)); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); -#endif } -#if defined(VERSION_JP) || defined(VERSION_SH) -#ifdef VERSION_JP - #define CURSOR_X 160.0f -#else - #define CURSOR_X (x + 70) -#endif - #define MENU_ERASE_YES_MIN_X 145 - #define MENU_ERASE_YES_MAX_X 164 -#else - #define CURSOR_X (x + 70) - #define MENU_ERASE_YES_MIN_X 140 - #define MENU_ERASE_YES_MAX_X 169 -#endif +LangArray textYes = DEFINE_LANGUAGE_ARRAY( + "YES", + "OUI", + "JA", + "はい"); -#define MENU_ERASE_YES_NO_MIN_Y 191 -#define MENU_ERASE_YES_NO_MAX_Y 210 -#ifdef VERSION_SH - #define MENU_ERASE_NO_MIN_X 194 - #define MENU_ERASE_NO_MAX_X 213 -#else - #define MENU_ERASE_NO_MIN_X 189 - #define MENU_ERASE_NO_MAX_X 218 -#endif +LangArray textNo = DEFINE_LANGUAGE_ARRAY( + "NO", + "NON", + "NEIN", + "いいえ"); /** * Prints the "YES NO" prompt and checks if one of the prompts are hovered to do it's functions. */ void print_erase_menu_prompt(s16 x, s16 y) { - s16 colorTransTimer = gGlobalTimer << 12; + s16 colorFade = gGlobalTimer << 12; - s16 cursorX = sCursorPos[0] + CURSOR_X; + s16 cursorX = sCursorPos[0] + x + 70.f; s16 cursorY = sCursorPos[1] + 120.0f; - if (cursorX < MENU_ERASE_YES_MAX_X && cursorX >= MENU_ERASE_YES_MIN_X && - cursorY < MENU_ERASE_YES_NO_MAX_Y && cursorY >= MENU_ERASE_YES_NO_MIN_Y) { + if (cursorX < 169 && cursorX >= 140 && + cursorY < 210 && cursorY >= 191) { // Fade "YES" string color but keep "NO" gray - sYesNoColor[0] = sins(colorTransTimer) * 50.0f + 205.0f; + sYesNoColor[0] = sins(colorFade) * 50.0f + 205.0f; sYesNoColor[1] = 150; sEraseYesNoHoverState = MENU_ERASE_HOVER_YES; - } else if (cursorX < MENU_ERASE_NO_MAX_X && cursorX >= MENU_ERASE_NO_MIN_X - && cursorY < MENU_ERASE_YES_NO_MAX_Y && cursorY >= MENU_ERASE_YES_NO_MIN_Y) { + } else if (cursorX < 218 && cursorX >= 189 + && cursorY < 210 && cursorY >= 191) { // Fade "NO" string color but keep "YES" gray sYesNoColor[0] = 150; - sYesNoColor[1] = sins(colorTransTimer) * 50.0f + 205.0f; + sYesNoColor[1] = sins(colorFade) * 50.0f + 205.0f; sEraseYesNoHoverState = MENU_ERASE_HOVER_NO; } else { // Don't fade both strings and keep them gray @@ -2330,7 +1688,7 @@ void print_erase_menu_prompt(s16 x, s16 y) { // ..and is hovering "YES", delete file if (sEraseYesNoHoverState == MENU_ERASE_HOVER_YES) { play_sound(SOUND_MARIO_WAAAOOOW, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[MENU_BUTTON_ERASE]->oMenuButtonActionPhase = ERASE_PHASE_MARIO_ERASED; @@ -2345,7 +1703,7 @@ void print_erase_menu_prompt(s16 x, s16 y) { // ..and is hovering "NO", return back to main phase } else if (sEraseYesNoHoverState == MENU_ERASE_HOVER_NO) { play_sound(SOUND_MENU_CLICK_FILE_SELECT, gGlobalSoundSource); -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(5, 80); #endif sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->oMenuButtonState = @@ -2359,86 +1717,53 @@ void print_erase_menu_prompt(s16 x, s16 y) { // Print "YES NO" strings gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, sYesNoColor[0], sYesNoColor[0], sYesNoColor[0], sTextBaseAlpha); - print_generic_string(x + 56, y, LANGUAGE_ARRAY(textYes)); - gDPSetEnvColor(gDisplayListHead++, sYesNoColor[1], sYesNoColor[1], sYesNoColor[1], sTextBaseAlpha); - print_generic_string(x + 98, y, LANGUAGE_ARRAY(textNo)); + gDPSetEnvColor(gDisplayListHead++, sYesNoColor[0], sYesNoColor[0], sYesNoColor[0], gDialogTextAlpha); + print_generic_string(x + 56, y, LANG_ARRAY(textYes)); + gDPSetEnvColor(gDisplayListHead++, sYesNoColor[1], sYesNoColor[1], sYesNoColor[1], gDialogTextAlpha); + print_generic_string(x + 98, y, LANG_ARRAY(textNo)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } -// MARIO_ERASED_VAR is the value there the letter "A" is, it works like this: -// US and EU --- JP -// M a r i o A --- マ リ オ A -// 0 1 2 3 4 5 6 --- 0 1 2 3 -#if defined(VERSION_JP) || defined(VERSION_SH) -#ifdef VERSION_JP - #define ERASE_FILE_X 96 -#else - #define ERASE_FILE_X 111 -#endif - #define NOSAVE_DATA_X3 90 - #define MARIO_ERASED_VAR 3 - #define MARIO_ERASED_X 90 - #define SAVE_EXISTS_X2 90 -#elif defined(VERSION_US) - #define ERASE_FILE_X 98 - #define NOSAVE_DATA_X3 100 - #define MARIO_ERASED_VAR 6 - #define MARIO_ERASED_X 100 - #define SAVE_EXISTS_X2 100 -#elif defined(VERSION_EU) - #define ERASE_FILE_X centeredX - #define NOSAVE_DATA_X3 centeredX - #define MARIO_ERASED_VAR 6 - #define MARIO_ERASED_X centeredX - #define SAVE_EXISTS_X2 centeredX -#endif +LangArray textEraseFile = DEFINE_LANGUAGE_ARRAY( + "ERASE FILE", + "EFFACER FICHIER", + "SPIEL LÖSCHEN", + "ファイルけす"); + +LangArray textSure = DEFINE_LANGUAGE_ARRAY( + "SURE?", + "OK?", + "SICHER?", + "ほんと?"); + +LangArray textMarioXJustErased = DEFINE_LANGUAGE_ARRAY( + "MARIO %s JUST ERASED", + "MARIO %s EFFACÉ", + "MARIO %s GELÖSCHT", + "マリオ%sをけしました"); /** * Defines IDs for the top message of the erase menu and displays it if the ID is called in messageID. */ void erase_menu_display_message(s8 messageID) { -#ifdef VERSION_EU - s16 centeredX; -#endif - -#ifndef VERSION_EU - unsigned char textEraseFile[] = { TEXT_ERASE_FILE }; - unsigned char textSure[] = { TEXT_SURE }; - unsigned char textNoSavedDataExists[] = { TEXT_NO_SAVED_DATA_EXISTS }; - unsigned char textMarioAJustErased[] = { TEXT_FILE_MARIO_A_JUST_ERASED }; - unsigned char textSavedDataExists[] = { TEXT_SAVED_DATA_EXISTS }; -#endif - + char str[50]; switch (messageID) { case ERASE_MSG_MAIN_TEXT: -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center_scale(160, textEraseFile[sLanguageMode], 12.0f); -#endif - print_hud_lut_string_fade(HUD_LUT_DIFF, ERASE_FILE_X, 35, LANGUAGE_ARRAY(textEraseFile)); + print_hud_lut_string_fade(SCREEN_CENTER_X, 35, LANG_ARRAY(textEraseFile), TEXT_ALIGN_CENTER); break; case ERASE_MSG_PROMPT: - print_generic_string_fade(90, 190, LANGUAGE_ARRAY(textSure)); + print_generic_string_fade(90, 190, LANG_ARRAY(textSure), TEXT_ALIGN_LEFT); print_erase_menu_prompt(90, 190); // YES NO, has functions for it too break; case ERASE_MSG_NOSAVE_EXISTS: -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textNoSavedDataExists[sLanguageMode], 10.0f); -#endif - print_generic_string_fade(NOSAVE_DATA_X3, 190, LANGUAGE_ARRAY(textNoSavedDataExists)); + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textNoSavedDataExists), TEXT_ALIGN_CENTER); break; case ERASE_MSG_MARIO_ERASED: - LANGUAGE_ARRAY(textMarioAJustErased)[MARIO_ERASED_VAR] = sSelectedFileIndex + 10; -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textMarioAJustErased[sLanguageMode], 10.0f); -#endif - print_generic_string_fade(MARIO_ERASED_X, 190, LANGUAGE_ARRAY(textMarioAJustErased)); + string_format_file_letter(str, LANG_ARRAY(textMarioXJustErased), sSelectedFileIndex); + print_generic_string_fade(SCREEN_CENTER_X, 190, str, TEXT_ALIGN_CENTER); break; case ERASE_MSG_SAVE_EXISTS: // unused -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(160, textSavedDataExists[sLanguageMode], 10.0f); -#endif - print_generic_string_fade(SAVE_EXISTS_X2, 190, LANGUAGE_ARRAY(textSavedDataExists)); + print_generic_string_fade(SCREEN_CENTER_X, 190, LANG_ARRAY(textSavedDataExists), TEXT_ALIGN_CENTER); break; } } @@ -2485,21 +1810,10 @@ void erase_menu_update_message(void) { } } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define VIEWSCORE_X2 133 - #define COPYFILE_X2 223 -#else - #define VIEWSCORE_X2 127 - #define COPYFILE_X2 233 -#endif - /** * Prints erase menu strings that shows on the red background menu screen. */ void print_erase_menu_strings(void) { -#ifdef VERSION_EU - s16 centeredX; -#endif // Update and print the message at the top of the menu. erase_menu_update_message(); @@ -2507,207 +1821,189 @@ void print_erase_menu_strings(void) { // Print messageID called inside a erase_menu_update_message case erase_menu_display_message(sStatusMessageID); -#ifndef VERSION_EU // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); print_save_file_star_count(SAVE_FILE_A, 90, 76); print_save_file_star_count(SAVE_FILE_B, 211, 76); print_save_file_star_count(SAVE_FILE_C, 90, 119); print_save_file_star_count(SAVE_FILE_D, 211, 119); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); -#endif // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - -#ifdef VERSION_EU - centeredX = get_str_x_pos_from_center(69, textReturn[sLanguageMode], 10.0f); - print_generic_string(centeredX, 35, textReturn[sLanguageMode]); - centeredX = get_str_x_pos_from_center(159, textViewScore[sLanguageMode], 10.0f); - print_generic_string(centeredX, 35, textViewScore[sLanguageMode]); - centeredX = get_str_x_pos_from_center(249, textCopyFileButton[sLanguageMode], 10.0f); - print_generic_string(centeredX, 35, textCopyFileButton[sLanguageMode]); -#else - print_generic_string(RETURN_X, 35, textReturn); - print_generic_string(VIEWSCORE_X2, 35, textViewScore); - print_generic_string(COPYFILE_X2, 35, textCopyFileButton); -#endif + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_generic_string_aligned(SUBMENU_LEFT_BUTTON_X, 35, LANG_ARRAY(textReturn), TEXT_ALIGN_CENTER); + print_generic_string_aligned(SUBMENU_MIDDLE_BUTTON_X, 35, LANG_ARRAY(textViewScore), TEXT_ALIGN_CENTER); + print_generic_string_aligned(SUBMENU_RIGHT_BUTTON_X, 35, LANG_ARRAY(textCopyFileButton), TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); -#ifdef VERSION_EU - print_main_menu_strings(); -#else // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_menu_generic_string(89, 62, textMarioA); - print_menu_generic_string(211, 62, textMarioB); - print_menu_generic_string(89, 105, textMarioC); - print_menu_generic_string(211, 105, textMarioD); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + print_menu_generic_string(89, 62, LANG_ARRAY(textMarioA)); + print_menu_generic_string(211, 62, LANG_ARRAY(textMarioB)); + print_menu_generic_string(89, 105, LANG_ARRAY(textMarioC)); + print_menu_generic_string(211, 105, LANG_ARRAY(textMarioD)); gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); -#endif } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define SOUND_HUD_X 96 -#elif defined(VERSION_US) - #define SOUND_HUD_X 88 +LangArray textSoundSelect = DEFINE_LANGUAGE_ARRAY( + "SOUND SELECT", + "SELECTION SON", + "WÄHLE SOUND", + "サウンドセレクト"); + +#ifdef MULTILANG +LangArray textLanguageSelect = DEFINE_LANGUAGE_ARRAY( + "LANGUAGE SELECT", + "SELECTION LANGUE", + "WÄHLE SPRACHE", + "ランゲージセレクト"); + +char *textLanguage[] = { + "ENGLISH", + "FRANÇAIS", + "DEUTSCH", + "にほんご", +}; + +#define SOUND_LABEL_Y 141 +#define LANGUAGE_SELECT_Y 80 +#else +#define SOUND_LABEL_Y 87 #endif +#define OPTION_LABEL_SPACING 74 + /** * Prints sound mode menu strings that shows on the purple background menu screen. * - * In EU, this function acts like "print_option_mode_menu_strings" because of languages. + * With multilang, this function acts like "print_option_mode_menu_strings" because of languages. */ void print_sound_mode_menu_strings(void) { s32 mode; - -#if defined(VERSION_US) || defined(VERSION_SH) - s16 textX; -#elif defined(VERSION_EU) s32 textX; -#endif - -#ifndef VERSION_EU - unsigned char textSoundSelect[] = { TEXT_SOUND_SELECT }; -#endif // Print "SOUND SELECT" text gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); -#ifdef VERSION_EU - print_hud_lut_string(HUD_LUT_DIFF, 47, 32, textSoundSelect[sLanguageMode]); - print_hud_lut_string(HUD_LUT_DIFF, 47, 101, textLanguageSelect[sLanguageMode]); -#else - print_hud_lut_string(HUD_LUT_DIFF, SOUND_HUD_X, 35, textSoundSelect); + print_hud_lut_string(47, 32, LANG_ARRAY(textSoundSelect)); +#ifdef MULTILANG + print_hud_lut_string(47, 110, LANG_ARRAY(textLanguageSelect)); #endif gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); -#ifdef VERSION_EU // In EU their X position get increased each string // Print sound mode names - for (mode = 0, textX = 90; mode < 3; textX += 70, mode++) { + for (mode = 0, textX = SCREEN_CENTER_X - OPTION_LABEL_SPACING; mode < 3; textX += OPTION_LABEL_SPACING, mode++) { if (mode == sSoundMode) { - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); } else { - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha); + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); } - print_generic_string( - get_str_x_pos_from_center(textX, textSoundModes[sLanguageMode * 3 + mode], 10.0f), - 141, textSoundModes[sLanguageMode * 3 + mode]); + print_generic_string_aligned(textX, SOUND_LABEL_Y, LANG_ARRAY(*textSoundModes[mode]), TEXT_ALIGN_CENTER); } - // In EU, print language mode names - for (mode = 0, textX = 90; mode < 3; textX += 70, mode++) { - if (mode == sLanguageMode) { - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - } else { - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha); - } - print_generic_string( - get_str_x_pos_from_center(textX, textLanguage[mode], 10.0f), - 72, textLanguage[mode]); - } -#else - // Print sound mode names - for (mode = 0; mode < 3; mode++) { - if (mode == sSoundMode) { - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - } else { - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, sTextBaseAlpha); +#ifdef MULTILANG + // Handle changing the selected language + if (sCursorClickingTimer == 2) { + s16 cursorX = sCursorPos[0] + SCREEN_CENTER_X; + s16 cursorY = sCursorPos[1] + SCREEN_CENTER_Y; + + s8 oldSelectedLanguageIndex = sSelectedLanguageIndex; + + if (cursorY < LANGUAGE_SELECT_Y + 20 && cursorY >= LANGUAGE_SELECT_Y) { + if (cursorX < SCREEN_CENTER_X - 40 && cursorX >= SCREEN_CENTER_X - 60) { + sSelectedLanguageIndex--; + } else if (cursorX < SCREEN_CENTER_X + 60 && cursorX >= SCREEN_CENTER_X + 40) { + sSelectedLanguageIndex++; + } + // Update language if the language has been changed + if (sSelectedLanguageIndex != oldSelectedLanguageIndex) { + play_sound(SOUND_MENU_CHANGE_SELECT, gGlobalSoundSource); + sSelectedLanguageIndex = (sSelectedLanguageIndex + NUM_DEFINED_LANGUAGES) % NUM_DEFINED_LANGUAGES; + multilang_set_language(gDefinedLanguages[sSelectedLanguageIndex]); + } } - #ifndef VERSION_JP - // Mode names are centered correctly on US and Shindou - textX = get_str_x_pos_from_center(mode * 74 + 87, textSoundModes[mode], 10.0f); - print_generic_string(textX, 87, textSoundModes[mode]); - #else - print_generic_string(mode * 74 + 67, 87, textSoundModes[mode]); - #endif } -#endif -#ifdef VERSION_EU - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_generic_string(182, 29, textReturn[sLanguageMode]); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + // Print current language + print_generic_string_aligned(SCREEN_CENTER_X, LANGUAGE_SELECT_Y, textLanguage[gInGameLanguage], TEXT_ALIGN_CENTER); + print_generic_string_aligned(SCREEN_CENTER_X - 50, LANGUAGE_SELECT_Y, "◀", TEXT_ALIGN_CENTER); + print_generic_string_aligned(SCREEN_CENTER_X + 50, LANGUAGE_SELECT_Y, "▶", TEXT_ALIGN_CENTER); + + // Print return text + print_generic_string(184, 29, LANG_ARRAY(textReturn)); #endif gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } -unsigned char textStarX[] = { TEXT_STAR_X }; - /** * Prints castle secret stars collected in a score menu save file. */ void print_score_file_castle_secret_stars(s8 fileIndex, s16 x, s16 y) { - unsigned char secretStarsText[20]; - // Print "[star] x" - print_menu_generic_string(x, y, textStarX); + char secretStarsText[20]; + char secretStarsNum[8]; // Print number of castle secret stars - int_to_str(save_file_get_total_star_count(fileIndex, COURSE_BONUS_STAGES - 1, COURSE_MAX - 1), - secretStarsText); -#ifdef VERSION_EU - print_menu_generic_string(x + 20, y, secretStarsText); -#else - print_menu_generic_string(x + 16, y, secretStarsText); -#endif + format_int_to_string(secretStarsNum, save_file_get_total_star_count(fileIndex, + COURSE_NUM_TO_INDEX(COURSE_BONUS_STAGES), + COURSE_NUM_TO_INDEX(COURSE_MAX))); + sprintf(secretStarsText, "★×%s", secretStarsNum); + print_menu_generic_string(x, y, secretStarsText); } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define HISCORE_COIN_ICON_X 0 - #define HISCORE_COIN_TEXT_X 16 - #define HISCORE_COIN_NAMES_X 45 -#else - #define HISCORE_COIN_ICON_X 18 - #define HISCORE_COIN_TEXT_X 34 - #define HISCORE_COIN_NAMES_X 60 -#endif +LangArray text4Dashes = DEFINE_LANGUAGE_ARRAY( + "----", + "----", + "----", + "ーーーー"); + +LangArray textMarioFace = DEFINE_LANGUAGE_ARRAY( + "{}%s", + "{}%s", + "{}%s", + "マリオ%s"); /** * Prints course coins collected in a score menu save file. */ void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { - unsigned char coinScoreText[20]; + char str[20]; + char coinScoreText[10]; u8 stars = save_file_get_star_flags(fileIndex, courseIndex); - unsigned char textCoinX[] = { TEXT_COIN_X }; - unsigned char textStar[] = { TEXT_STAR }; -#if defined(VERSION_JP) || defined(VERSION_SH) - #define LENGTH 5 -#else - #define LENGTH 8 -#endif - unsigned char fileNames[][LENGTH] = { - { TEXT_4DASHES }, // huh? - { TEXT_SCORE_MARIO_A }, { TEXT_SCORE_MARIO_B }, { TEXT_SCORE_MARIO_C }, { TEXT_SCORE_MARIO_D }, - }; -#undef LENGTH + // MYSCORE if (sScoreFileCoinScoreMode == 0) { - // Print "[coin] x" - print_menu_generic_string(x + 25, y, textCoinX); // Print coin score - int_to_str(save_file_get_course_coin_score(fileIndex, courseIndex), coinScoreText); - print_menu_generic_string(x + 41, y, coinScoreText); + format_int_to_string(coinScoreText, save_file_get_course_coin_score(fileIndex, courseIndex)); + sprintf(str, "✪×%s", coinScoreText); + print_menu_generic_string(x + 25, y, str); // If collected, print 100 coin star - if (stars & (1 << 6)) { - print_menu_generic_string(x + 70, y, textStar); + if (stars & STAR_FLAG_ACT_100_COINS) { + print_menu_generic_string(x + 70, y, "★"); } } // HISCORE else { - // Print "[coin] x" - print_menu_generic_string(x + HISCORE_COIN_ICON_X, y, textCoinX); + u16 coinScoreFile; // Print coin highscore - int_to_str((u16) save_file_get_max_coin_score(courseIndex) & 0xFFFF, coinScoreText); - print_menu_generic_string(x + HISCORE_COIN_TEXT_X, y, coinScoreText); + format_int_to_string(coinScoreText, (u16) save_file_get_max_coin_score(courseIndex) & 0xFFFF); + sprintf(str, "✪×%s", coinScoreText); + print_menu_generic_string(x + 18, y, str); // Print coin highscore file - print_menu_generic_string(x + HISCORE_COIN_NAMES_X, y, - fileNames[(save_file_get_max_coin_score(courseIndex) >> 16) & 0xFFFF]); + coinScoreFile = (save_file_get_max_coin_score(courseIndex) >> 16) & 0xFFFF; + if (coinScoreFile == 0) { + print_menu_generic_string(x + 60, y, LANG_ARRAY(text4Dashes)); + } else { + string_format_file_letter(str, LANG_ARRAY(textMarioFace), coinScoreFile - 1); + print_menu_generic_string(x + 60, y, str); + } } } @@ -2716,295 +2012,108 @@ void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s16 x, s1 */ void print_score_file_star_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { s16 i = 0; - unsigned char starScoreText[19]; + char starScoreText[30]; + char *entries[6]; u8 stars = save_file_get_star_flags(fileIndex, courseIndex); s8 starCount = save_file_get_course_star_count(fileIndex, courseIndex); // Don't count 100 coin star - if (stars & (1 << 6)) { + if (stars & STAR_FLAG_ACT_100_COINS) { starCount--; } // Add 1 star character for every star collected for (i = 0; i < starCount; i++) { - starScoreText[i] = DIALOG_CHAR_STAR_FILLED; + entries[i] = "★"; + } + for (i = starCount; i < 6; i++) { + entries[i] = ""; } - // Terminating byte - starScoreText[i] = DIALOG_CHAR_TERMINATOR; + sprintf(starScoreText, "%s%s%s%s%s%s", entries[0], entries[1], entries[2], entries[3], entries[4], entries[5]); print_menu_generic_string(x, y, starScoreText); } -#if defined(VERSION_JP) || defined(VERSION_SH) - #define MARIO_X 28 - #define FILE_LETTER_X 86 -#ifdef VERSION_JP - #define LEVEL_NUM_PAD 0 - #define SECRET_STARS_PAD 0 -#else - #define LEVEL_NUM_PAD 5 - #define SECRET_STARS_PAD 10 -#endif - #define LEVEL_NAME_X 23 - #define STAR_SCORE_X 152 - #define MYSCORE_X 237 - #define HISCORE_X 237 -#else - #define MARIO_X 25 - #define FILE_LETTER_X 95 - #define LEVEL_NUM_PAD 3 - #define SECRET_STARS_PAD 6 - #define LEVEL_NAME_X 23 - #define STAR_SCORE_X 171 -#ifdef VERSION_EU - #define MYSCORE_X get_str_x_pos_from_center(257, textMyScore[sLanguageMode], 10.0f) - #define HISCORE_X get_str_x_pos_from_center(257, textHiScore[sLanguageMode], 10.0f) -#else - #define MYSCORE_X 238 - #define HISCORE_X 231 -#endif -#endif +LangArray textScoreMenuMarioX = DEFINE_LANGUAGE_ARRAY( + "MARIO %c", + "MARIO %c", + "MARIO %c", + "マリオ %c"); -#ifdef VERSION_EU -#include "game/segment7.h" -#endif +LangArray textHiScore = DEFINE_LANGUAGE_ARRAY( + "HI SCORE", + "MEILLEUR SCORE", + "BESTLEISTUNG", + "ハイスコア"); + +extern LangArray textMyScore; /** * Prints save file score strings that shows when a save file is chosen inside the score menu. */ void print_save_file_scores(s8 fileIndex) { - s16 courseNum; - s8 tensDigPad; - -#ifndef VERSION_EU - unsigned char textMario[] = { TEXT_MARIO }; -#ifdef VERSION_JP - unsigned char textFileLetter[] = { TEXT_ZERO }; - void **levelNameTable = segmented_to_virtual(seg2_course_name_table); -#endif - unsigned char textHiScore[] = { TEXT_HI_SCORE }; - unsigned char textMyScore[] = { TEXT_MY_SCORE }; -#if defined(VERSION_US) || defined(VERSION_SH) - unsigned char textFileLetter[] = { TEXT_ZERO }; - void **levelNameTable = segmented_to_virtual(seg2_course_name_table); -#endif -#else - unsigned char textFileLetter[] = { TEXT_ZERO }; - void **levelNameTable; - - switch (sLanguageMode) { - case LANGUAGE_ENGLISH: - levelNameTable = segmented_to_virtual(eu_course_strings_en_table); - break; - case LANGUAGE_FRENCH: - levelNameTable = segmented_to_virtual(eu_course_strings_fr_table); - break; - case LANGUAGE_GERMAN: - levelNameTable = segmented_to_virtual(eu_course_strings_de_table); - break; - } -#endif - - textFileLetter[0] = fileIndex + ASCII_TO_DIALOG('A'); // get letter of file selected + u32 i; + char str[20]; + char fileLetter; -#ifdef TARGET_N3DS - gDPForceFlush(gDisplayListHead++); - gDPSet2d(gDisplayListHead++, 2); // vetoed +#ifndef MULTILANG + const char **levelNameTable = segmented_to_virtual(seg2_course_name_table); +#else + const char ***levelNameLanguageTable = segmented_to_virtual(course_strings_language_table); + const char **levelNameTable = segmented_to_virtual(levelNameLanguageTable[gInGameLanguage]); #endif // Print file name at top gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - print_hud_lut_string(HUD_LUT_DIFF, GFX_DIMENSIONS_FROM_LEFT_EDGE(MARIO_X), 15, textMario); - print_hud_lut_string(HUD_LUT_GLOBAL, GFX_DIMENSIONS_FROM_LEFT_EDGE(FILE_LETTER_X), 15, textFileLetter); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + fileLetter = 'A' + fileIndex; + sprintf(str, LANG_ARRAY(textScoreMenuMarioX), fileLetter); + print_hud_lut_string(25, 15, str); // Print save file star count at top - print_save_file_star_count(fileIndex, GFX_DIMENSIONS_FROM_LEFT_EDGE(124), 15); + print_save_file_star_count(fileIndex, 124, 15); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); // Print course scores gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, sTextBaseAlpha); - - for (courseNum = COURSE_MIN; courseNum <= COURSE_STAGES_MAX; courseNum++) { - courseNum >= 10 ? (tensDigPad = 0) : (tensDigPad = 1); - - print_menu_generic_string(GFX_DIMENSIONS_FROM_LEFT_EDGE(LEVEL_NAME_X) + (tensDigPad * LEVEL_NUM_PAD), - 23 + 12 * courseNum, segmented_to_virtual(levelNameTable[courseNum - 1])); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - print_score_file_star_score(fileIndex, courseNum - 1, GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - STAR_SCORE_X), 23 + 12 * courseNum); - print_score_file_course_coin_score(fileIndex, courseNum - 1, GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - 213), 23 + 12 * courseNum); + for ((i = 0); (i < COURSE_STAGES_MAX); (i++)) { + s32 lineY = 35 + (12 * i); + format_int_to_string(str, i + 1); + print_menu_generic_string(41, lineY, segmented_to_virtual(levelNameTable[i])); + print_menu_generic_string_aligned(37, lineY, str, TEXT_ALIGN_RIGHT); + print_score_file_star_score( fileIndex, i, 171, lineY); + print_score_file_course_coin_score(fileIndex, i, 213, lineY); } // Print castle secret stars text - print_menu_generic_string(GFX_DIMENSIONS_FROM_LEFT_EDGE(LEVEL_NAME_X + SECRET_STARS_PAD), 23 + 12 * 16, - segmented_to_virtual(levelNameTable[25])); + print_menu_generic_string(41, 215, segmented_to_virtual(levelNameTable[25])); // Print castle secret stars score - print_score_file_castle_secret_stars(fileIndex, GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - STAR_SCORE_X), 23 + 12 * 16); + print_score_file_castle_secret_stars(fileIndex, 171, 215); // Print current coin score mode if (sScoreFileCoinScoreMode == 0) { - print_menu_generic_string(MYSCORE_X, 24, LANGUAGE_ARRAY(textMyScore)); + print_menu_generic_string_aligned(262, 24, LANG_ARRAY(textMyScore), TEXT_ALIGN_CENTER); } else { - print_menu_generic_string(HISCORE_X, 24, LANGUAGE_ARRAY(textHiScore)); + print_menu_generic_string_aligned(262, 24, LANG_ARRAY(textHiScore), TEXT_ALIGN_CENTER); } gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); } -#ifdef WIDESCREEN -/** - * Copy of the X values of the vertices so they can be intialized independently. - */ -const short sGeneralButtonVtxPosXGroup1[] = { - -163, -122, -163, -143, -133, -133, -133, 133, -133, 133, 133, -133, -143, 143, 133, 143, -}; - -const short sGeneralButtonVtxPosXGroup2[] = { - 143, 133, 133, 133, -143, 143, -143, 133, 143, -133, -143, -133, -143, 163, -143, -163, -}; - -const short sGeneralButtonVtxPosXGroup3[] = { - 163, 143, -143, 143, 163, -163, -143, -163, 163, 122, -122, -122, -122, -163, -}; - -const short sGeneralButtonVtxPosXGroup4[] = { - -122, -122, 122, -163, 163, -122, -122, 122, 163, -163, 122, 163, 122, 163, 122, -}; - -const short sSaveButtonBackVtxPosX[] = { - 163, -163, 163, -163, -}; - -extern Vtx vertex_menu_main_button_dynamic_group1[]; -extern Vtx vertex_menu_main_button_dynamic_group2[]; -extern Vtx vertex_menu_main_button_dynamic_group3[]; -extern Vtx vertex_menu_main_button_dynamic_group4[]; -extern Vtx vertex_menu_save_button_back[]; - -void file_select_fit_screen(void) { - // color buttons vtx - Vtx *vtxColorButton1 = segmented_to_virtual(vertex_menu_main_button_dynamic_group1); - Vtx *vtxColorButton2 = segmented_to_virtual(vertex_menu_main_button_dynamic_group2); - Vtx *vtxColorButton3 = segmented_to_virtual(vertex_menu_main_button_dynamic_group3); - Vtx *vtxColorButton4 = segmented_to_virtual(vertex_menu_main_button_dynamic_group4); - // save button vtx - Vtx *vtxSaveBackButton = segmented_to_virtual(vertex_menu_save_button_back); - - // NOTE: This may look like a hack but this is better than scaling because it doesn't - // look weird when it gets more wide, lighting also gets weird with scaling. - // This workaround moves the tris to adapt the screen without looking weird. - - vtxColorButton1[0].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[0]); - vtxColorButton1[1].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[1]); - vtxColorButton1[2].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[2]); - vtxColorButton1[3].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[3]); - vtxColorButton1[4].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[4]); - vtxColorButton1[5].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[5]); - vtxColorButton1[6].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[6]); - vtxColorButton1[7].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup1[7]); - vtxColorButton1[8].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[8]); - vtxColorButton1[9].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup1[9]); - vtxColorButton1[10].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup1[10]); - vtxColorButton1[11].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[11]); - vtxColorButton1[12].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup1[12]); - vtxColorButton1[13].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup1[13]); - vtxColorButton1[14].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup1[14]); - vtxColorButton1[15].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup1[15]); - - vtxColorButton2[0].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[0]); - vtxColorButton2[1].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[1]); - vtxColorButton2[2].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[2]); - vtxColorButton2[3].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[3]); - vtxColorButton2[4].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[4]); - vtxColorButton2[5].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[5]); - vtxColorButton2[6].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[6]); - vtxColorButton2[7].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[7]); - vtxColorButton2[8].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[8]); - vtxColorButton2[9].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[9]); - vtxColorButton2[10].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[10]); - vtxColorButton2[11].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[11]); - vtxColorButton2[12].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[12]); - vtxColorButton2[13].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup2[13]); - vtxColorButton2[14].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[14]); - vtxColorButton2[15].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup2[15]); - - vtxColorButton3[0].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup3[0]); - vtxColorButton3[1].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup3[1]); - vtxColorButton3[2].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[2]); - vtxColorButton3[3].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup3[3]); - vtxColorButton3[4].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup3[4]); - vtxColorButton3[5].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[5]); - vtxColorButton3[6].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[6]); - vtxColorButton3[7].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[7]); - vtxColorButton3[8].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup3[8]); - vtxColorButton3[9].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup3[9]); - vtxColorButton3[10].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[10]); - vtxColorButton3[11].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[11]); - vtxColorButton3[12].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[12]); - vtxColorButton3[13].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup3[13]); - - vtxColorButton4[0].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup4[0]); - vtxColorButton4[1].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup4[1]); - vtxColorButton4[2].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[2]); - vtxColorButton4[3].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup4[3]); - vtxColorButton4[4].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[4]); - vtxColorButton4[5].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup4[5]); - vtxColorButton4[6].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup4[6]); - vtxColorButton4[7].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[7]); - vtxColorButton4[8].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[8]); - vtxColorButton4[9].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup4[9]); - vtxColorButton4[10].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[10]); - vtxColorButton4[11].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[11]); - vtxColorButton4[12].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[12]); - vtxColorButton4[13].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[13]); - vtxColorButton4[14].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sGeneralButtonVtxPosXGroup4[14]); - - vtxSaveBackButton[0].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sSaveButtonBackVtxPosX[0]); - vtxSaveBackButton[1].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sSaveButtonBackVtxPosX[1]); - vtxSaveBackButton[2].n.ob[0] = GFX_DIMENSIONS_FROM_RIGHT_EDGE(320 - sSaveButtonBackVtxPosX[2]); - vtxSaveBackButton[3].n.ob[0] = GFX_DIMENSIONS_FROM_LEFT_EDGE(sGeneralButtonVtxPosXGroup4[3]); -} -#endif - /** * Prints file select strings depending on the menu selected. * Also checks if all saves exists and defines text and main menu timers. */ -static void print_file_select_strings(void) { - UNUSED u8 filler[8]; - +void print_file_select_strings(void) { create_dl_ortho_matrix(); switch (sSelectedButtonID) { - case MENU_BUTTON_NONE: -#ifdef VERSION_EU - // Ultimately calls print_main_menu_strings, but prints main language strings first. - print_main_lang_strings(); -#else - print_main_menu_strings(); -#endif - break; - case MENU_BUTTON_SCORE: - print_score_menu_strings(); - sScoreFileCoinScoreMode = 0; - break; - case MENU_BUTTON_COPY: - print_copy_menu_strings(); - break; - case MENU_BUTTON_ERASE: - print_erase_menu_strings(); - break; - case MENU_BUTTON_SCORE_FILE_A: - print_save_file_scores(SAVE_FILE_A); - break; - case MENU_BUTTON_SCORE_FILE_B: - print_save_file_scores(SAVE_FILE_B); - break; - case MENU_BUTTON_SCORE_FILE_C: - print_save_file_scores(SAVE_FILE_C); - break; - case MENU_BUTTON_SCORE_FILE_D: - print_save_file_scores(SAVE_FILE_D); - break; - case MENU_BUTTON_SOUND_MODE: - print_sound_mode_menu_strings(); - break; + case MENU_BUTTON_NONE: print_main_menu_strings(); break; + case MENU_BUTTON_SCORE: print_score_menu_strings(); sScoreFileCoinScoreMode = 0; break; + case MENU_BUTTON_COPY: print_copy_menu_strings(); break; + case MENU_BUTTON_ERASE: print_erase_menu_strings(); break; + case MENU_BUTTON_SCORE_FILE_A: print_save_file_scores(SAVE_FILE_A); break; + case MENU_BUTTON_SCORE_FILE_B: print_save_file_scores(SAVE_FILE_B); break; + case MENU_BUTTON_SCORE_FILE_C: print_save_file_scores(SAVE_FILE_C); break; + case MENU_BUTTON_SCORE_FILE_D: print_save_file_scores(SAVE_FILE_D); break; + case MENU_BUTTON_SOUND_MODE: print_sound_mode_menu_strings(); break; } // If all 4 save file exists, define true to sAllFilesExist to prevent more copies in copy menu if (save_file_exists(SAVE_FILE_A) == TRUE && save_file_exists(SAVE_FILE_B) == TRUE && @@ -3014,26 +2123,12 @@ static void print_file_select_strings(void) { sAllFilesExist = FALSE; } // Timers for menu alpha text and the main menu itself - if (sTextBaseAlpha < 250) { - sTextBaseAlpha += 10; + if (gDialogTextAlpha < 250) { + gDialogTextAlpha += 10; } if (sMainMenuTimer < 1000) { sMainMenuTimer++; } - -#ifdef WIDESCREEN - file_select_fit_screen(); -#endif - -#ifdef SET_KEY_COMBO_SKIP_PEACH_CUTSCENE - // Adds key combo to skip peach intro cutscene, useful on Non-PC targets - if ((gPlayer1Controller->buttonDown == (L_TRIG | R_TRIG)) && sCurrentMenuLevel == MENU_LAYER_MAIN) { - if (!(gGlobalGameSkips & GAME_SKIP_INTRO_SCENE)) { - play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); - gGlobalGameSkips |= GAME_SKIP_INTRO_SCENE; - } - } -#endif } /** @@ -3041,53 +2136,43 @@ static void print_file_select_strings(void) { */ Gfx *geo_file_select_strings_and_menu_cursor(s32 callContext, UNUSED struct GraphNode *node, UNUSED Mat4 mtx) { if (callContext == GEO_CONTEXT_RENDER) { -#ifdef TARGET_N3DS - gDPForceFlush(gDisplayListHead++); - gDPSet2d(gDisplayListHead++, 1); - gDPSetIod(gDisplayListHead++, iodFileSelect); -#endif print_file_select_strings(); print_menu_cursor(); -#ifdef TARGET_N3DS - gDPForceFlush(gDisplayListHead++); - gDPSet2d(gDisplayListHead++, 0); -#endif } return NULL; } +#ifdef MULTILANG +/** + * Determines the array index of the saved language based on which languages are defined. + */ +static u8 get_language_index(u8 language) { + for (u32 i = 0; i < NUM_DEFINED_LANGUAGES; i++) { + if (language == gDefinedLanguages[i]) { + return i; + } + } + return LANGUAGE_ENGLISH; +} +#endif + /** * Initiates file select values after Mario Screen. * Relocates cursor position of the last save if the game goes back to the Mario Screen * either completing a course choosing "SAVE & QUIT" or having a game over. */ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) { -#ifdef VERSION_EU - s8 fileIndex; -#endif sSelectedButtonID = MENU_BUTTON_NONE; sCurrentMenuLevel = MENU_LAYER_MAIN; - sTextBaseAlpha = 0; + gDialogTextAlpha = 0; // Place the cursor over the save file that was being played. // gCurrSaveFileNum is 1 by default when the game boots, as such // the cursor will point on Mario A save file. switch (gCurrSaveFileNum) { - case 1: // File A - sCursorPos[0] = -94.0f; - sCursorPos[1] = 46.0f; - break; - case 2: // File B - sCursorPos[0] = 24.0f; - sCursorPos[1] = 46.0f; - break; - case 3: // File C - sCursorPos[0] = -94.0f; - sCursorPos[1] = 5.0f; - break; - case 4: // File D - sCursorPos[0] = 24.0f; - sCursorPos[1] = 5.0f; - break; + case SAVE_FILE_NUM_A: sCursorPos[0] = -94.0f; sCursorPos[1] = 46.0f; break; + case SAVE_FILE_NUM_B: sCursorPos[0] = 24.0f; sCursorPos[1] = 46.0f; break; + case SAVE_FILE_NUM_C: sCursorPos[0] = -94.0f; sCursorPos[1] = 5.0f; break; + case SAVE_FILE_NUM_D: sCursorPos[0] = 24.0f; sCursorPos[1] = 5.0f; break; } sClickPos[0] = -10000; sClickPos[1] = -10000; @@ -3100,11 +2185,11 @@ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) { sMainMenuTimer = 0; sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE; sSoundMode = save_file_get_sound_mode(); -#ifdef VERSION_EU - sLanguageMode = eu_get_language(); +#ifdef MULTILANG + sSelectedLanguageIndex = get_language_index(gInGameLanguage); - for (fileIndex = 0; fileIndex <= 3; fileIndex++) { - if (save_file_exists(fileIndex) == TRUE) { + for (u32 fileNum = 0; fileNum < NUM_SAVE_FILES; fileNum++) { + if (save_file_exists(fileNum) == TRUE) { sOpenLangSettings = FALSE; break; } else { @@ -3112,7 +2197,7 @@ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) { } } #endif - + gCurrLevelNum = LEVEL_UNKNOWN_1; return 0; } diff --git a/src/menu/file_select.h b/src/menu/file_select.h index d4d75b657..2c070b782 100644 --- a/src/menu/file_select.h +++ b/src/menu/file_select.h @@ -6,12 +6,17 @@ #include "types.h" -#define MENU_LAYER_MAIN 1 -#define MENU_LAYER_SUBMENU 2 +enum MenuLayers { + MENU_LAYER_NONE, + MENU_LAYER_MAIN, + MENU_LAYER_SUBMENU +}; -#define MENU_ERASE_HOVER_NONE 0 -#define MENU_ERASE_HOVER_YES 1 -#define MENU_ERASE_HOVER_NO 2 +enum MenuEraseButtonHoverStates { + MENU_ERASE_HOVER_NONE, + MENU_ERASE_HOVER_YES, + MENU_ERASE_HOVER_NO +}; enum MainMenuButtonStates { MENU_BUTTON_STATE_DEFAULT, @@ -71,20 +76,15 @@ enum MenuButtonTypes { MENU_BUTTON_ERASE_MAX, // Sound Mode Menu (SOUND SELECT) - // This menu includes language settings on EU + // This menu includes language settings with multilang MENU_BUTTON_SOUND_MODE = MENU_BUTTON_ERASE_MAX, MENU_BUTTON_OPTION_MIN, MENU_BUTTON_STEREO = MENU_BUTTON_OPTION_MIN, MENU_BUTTON_MONO, MENU_BUTTON_HEADSET, -#ifdef VERSION_EU - // Language Menu - MENU_BUTTON_LANGUAGE_MIN, - MENU_BUTTON_LANGUAGE_ENGLISH = MENU_BUTTON_LANGUAGE_MIN, - MENU_BUTTON_LANGUAGE_FRENCH, - MENU_BUTTON_LANGUAGE_GERMAN, - MENU_BUTTON_LANGUAGE_RETURN, +#ifdef MULTILANG + MENU_BUTTON_OPTION_RETURN, #endif MENU_BUTTON_OPTION_MAX diff --git a/src/menu/star_select.c b/src/menu/star_select.c index 958d33125..9133740d6 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -4,7 +4,6 @@ #include "behavior_data.h" #include "engine/behavior_script.h" #include "engine/graph_node.h" -#include "eu_translation.h" #include "game/area.h" #include "game/game_init.h" #include "game/ingame_menu.h" @@ -12,13 +11,17 @@ #include "game/memory.h" #include "game/object_helpers.h" #include "game/object_list_processor.h" -#include "game/rumble_init.h" #include "game/save_file.h" #include "game/segment2.h" #include "game/segment7.h" +#include "game/rumble_init.h" #include "sm64.h" #include "star_select.h" -#include "text_strings.h" +#include "game/main.h" // n64 +#include // non-n64 + +// from hackersm64 +#define o gCurrentObject /** * @file star_select.c @@ -52,6 +55,12 @@ static s8 sSelectableStarIndex = 0; // Act Selector menu timer that keeps counting until you choose an act. static s32 sActSelectorMenuTimer = 0; +#ifdef WIDE +#define ACT_SELECT_WIDESCREEN_SCALE (gConfig.widescreen ? (4.f / 3) : 1.f) +#else +#define ACT_SELECT_WIDESCREEN_SCALE 1.f +#endif + /** * Act Selector Star Type Loop Action * Defines a select type for a star in the act selector. @@ -60,17 +69,17 @@ void bhv_act_selector_star_type_loop(void) { switch (gCurrentObject->oStarSelectorType) { // If a star is not selected, don't rotate or change size case STAR_SELECTOR_NOT_SELECTED: - gCurrentObject->oStarSelectorSize -= 0.1; - if (gCurrentObject->oStarSelectorSize < 1.0) { - gCurrentObject->oStarSelectorSize = 1.0; + gCurrentObject->oStarSelectorSize -= 0.1f; + if (gCurrentObject->oStarSelectorSize < 1.0f) { + gCurrentObject->oStarSelectorSize = 1.0f; } gCurrentObject->oFaceAngleYaw = 0; break; // If a star is selected, rotate and slightly increase size case STAR_SELECTOR_SELECTED: - gCurrentObject->oStarSelectorSize += 0.1; - if (gCurrentObject->oStarSelectorSize > 1.3) { - gCurrentObject->oStarSelectorSize = 1.3; + gCurrentObject->oStarSelectorSize += 0.1f; + if (gCurrentObject->oStarSelectorSize > 1.3f) { + gCurrentObject->oStarSelectorSize = 1.3f; } gCurrentObject->oFaceAngleYaw += 0x800; break; @@ -89,11 +98,12 @@ void bhv_act_selector_star_type_loop(void) { * Renders the 100 coin star with an special star selector type. */ void render_100_coin_star(u8 stars) { - if (stars & (1 << 6)) { + if (stars & STAR_FLAG_ACT_100_COINS) { // If the 100 coin star has been collected, create a new star selector next to the coin score. - sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR, - bhvActSelectorStarType, 370, 24, -300, 0, 0, 0); - sStarSelectorModels[6]->oStarSelectorSize = 0.8; + sStarSelectorModels[6] = spawn_object_abs_with_rot(o, 0, MODEL_STAR, + bhvActSelectorStarType, 370 * ACT_SELECT_WIDESCREEN_SCALE, 24, -300, 0, 0, 0); + + sStarSelectorModels[6]->oStarSelectorSize = 0.8f; sStarSelectorModels[6]->oStarSelectorType = STAR_SELECTOR_100_COINS; } } @@ -148,8 +158,8 @@ void bhv_act_selector_init(void) { // Render star selector objects for (i = 0; i < sVisibleStars; i++) { sStarSelectorModels[i] = - spawn_object_abs_with_rot(gCurrentObject, 0, selectorModelIDs[i], bhvActSelectorStarType, - 75 + sVisibleStars * -75 + i * 152, 248, -300, 0, 0, 0); + spawn_object_abs_with_rot(o, 0, selectorModelIDs[i], bhvActSelectorStarType, + (75 + (sVisibleStars * -75) + (i * 152)) * ACT_SELECT_WIDESCREEN_SCALE, 248, -300, 0, 0, 0); sStarSelectorModels[i]->oStarSelectorSize = 1.0f; } @@ -203,30 +213,34 @@ void bhv_act_selector_loop(void) { /** * Print the course number selected with the wood rgba16 course texture. */ -#ifdef VERSION_EU -void print_course_number(s16 language) { -#else + void print_course_number(void) { -#endif - u8 courseNum[4]; + char courseNum[4]; create_dl_translation_matrix(MENU_MTX_PUSH, 158.0f, 81.0f, 0.0f); // Full wood texture in JP & US, lower part of it on EU gSPDisplayList(gDisplayListHead++, dl_menu_rgba16_wood_course); -#ifdef VERSION_EU +#ifdef MULTILANG // Change upper part of the wood texture depending of the language defined - switch (language) { + switch (multilang_get_language()) { case LANGUAGE_ENGLISH: +#ifdef ENABLE_JAPANESE + case LANGUAGE_JAPANESE: +#endif gSPDisplayList(gDisplayListHead++, dl_menu_texture_course_upper); break; +#ifdef ENABLE_FRENCH case LANGUAGE_FRENCH: gSPDisplayList(gDisplayListHead++, dl_menu_texture_niveau_upper); break; +#endif +#ifdef ENABLE_GERMAN case LANGUAGE_GERMAN: gSPDisplayList(gDisplayListHead++, dl_menu_texture_kurs_upper); break; +#endif } gSPDisplayList(gDisplayListHead++, dl_menu_rgba16_wood_course_end); @@ -236,142 +250,74 @@ void print_course_number(void) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - int_to_str(gCurrCourseNum, courseNum); - - if (gCurrCourseNum < 10) { // 1 digit number - print_hud_lut_string(HUD_LUT_GLOBAL, 152, 158, courseNum); - } else { // 2 digit number - print_hud_lut_string(HUD_LUT_GLOBAL, 143, 158, courseNum); - } + sprintf(courseNum, "%d", gCurrCourseNum); + print_hud_lut_string_aligned(157, 158, courseNum, TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); } -#ifdef VERSION_JP -#define ACT_NAME_X 158 -#else -#define ACT_NAME_X 163 -#endif - +LangArray textActMyScore = DEFINE_LANGUAGE_ARRAY( + "MYSCORE", + "MON SCORE", + "LEISTUNG", + "マイスコア"); /** * Print act selector strings, some with special checks. */ void print_act_selector_strings(void) { -#ifdef VERSION_EU - unsigned char myScore[][10] = { {TEXT_MYSCORE}, {TEXT_MY_SCORE_FR}, {TEXT_MY_SCORE_DE} }; -#else - unsigned char myScore[] = { TEXT_MYSCORE }; -#endif - unsigned char starNumbers[] = { TEXT_ZERO }; - -#ifdef VERSION_EU - u8 **levelNameTbl; - u8 *currLevelName; - u8 **actNameTbl; -#else - u8 **levelNameTbl = segmented_to_virtual(seg2_course_name_table); - u8 *currLevelName = segmented_to_virtual(levelNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum)]); - u8 **actNameTbl = segmented_to_virtual(seg2_act_name_table); -#endif - u8 *selectedActName; - s16 lvlNameX; - s16 actNameX; + char **levelNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]); + char *currLevelName = segmented_to_virtual(levelNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum)]); + char **actNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][2]); + char *selectedActName; s8 i; -#ifdef VERSION_EU - s16 language = eu_get_language(); -#endif create_dl_ortho_matrix(); + gDialogTextAlpha = 255; -#ifdef VERSION_EU - switch (language) { - case LANGUAGE_ENGLISH: - actNameTbl = segmented_to_virtual(act_name_table_eu_en); - levelNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - actNameTbl = segmented_to_virtual(act_name_table_eu_fr); - levelNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - actNameTbl = segmented_to_virtual(act_name_table_eu_de); - levelNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } - currLevelName = segmented_to_virtual(levelNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum)]); -#endif // Print the coin highscore. gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); print_hud_my_score_coins(1, gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum), 155, 106); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); // Print the "MY SCORE" text if the coin score is more than 0 if (save_file_get_course_coin_score(gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum)) != 0) { -#ifdef VERSION_EU - print_generic_string(95, 118, myScore[language]); -#else - print_generic_string(102, 118, myScore); -#endif + print_generic_string_aligned(145, 118, LANG_ARRAY(textActMyScore), TEXT_ALIGN_RIGHT); } - lvlNameX = get_str_x_pos_from_center(160, currLevelName + 3, 10.0f); - print_generic_string(lvlNameX, 33, currLevelName + 3); + print_generic_string_aligned(SCREEN_CENTER_X, 33, currLevelName, TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); -#ifdef VERSION_EU - print_course_number(language); -#else print_course_number(); -#endif gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); // Print the name of the selected act. if (sVisibleStars != 0) { selectedActName = segmented_to_virtual(actNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum) * 6 + sSelectedActIndex]); - actNameX = get_str_x_pos_from_center(ACT_NAME_X, selectedActName, 8.0f); - print_menu_generic_string(actNameX, 81, selectedActName); + print_menu_generic_string_aligned(SCREEN_CENTER_X, 81, selectedActName, TEXT_ALIGN_CENTER); } // Print the numbers above each star. for (i = 1; i <= sVisibleStars; i++) { - starNumbers[0] = i; -#ifdef VERSION_EU - print_menu_generic_string(143 - sVisibleStars * 15 + i * 30, 38, starNumbers); -#else - print_menu_generic_string(139 - sVisibleStars * 17 + i * 34, 38, starNumbers); -#endif + char str[4]; + format_int_to_string(str, i); + print_menu_generic_string_aligned(SCREEN_CENTER_X + (i*2 - sVisibleStars - 1) * 17, 38, str, TEXT_ALIGN_CENTER); } gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); -} + } /** * Geo function that Print act selector strings. - *!@bug: This geo function is missing the third param. Harmless in practice due to o32 convention. */ -#ifdef AVOID_UB -Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node, UNUSED void *context) -#else -Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node) -#endif -{ +Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node, UNUSED void *context) { if (callContext == GEO_CONTEXT_RENDER) { -#ifdef TARGET_N3DS - gDPForceFlush(gDisplayListHead++); - gDPSet2d(gDisplayListHead++, 1); - gDPSetIod(gDisplayListHead++, iodStarSelect); -#endif print_act_selector_strings(); -#ifdef TARGET_N3DS - gDPForceFlush(gDisplayListHead++); - gDPSet2d(gDisplayListHead++, 0); -#endif } return NULL; } @@ -387,22 +333,15 @@ s32 lvl_init_act_selector_values_and_stars(UNUSED s32 arg, UNUSED s32 unused) { sInitSelectedActNum = 0; sVisibleStars = 0; sActSelectorMenuTimer = 0; -#ifdef NO_SEGMENTED_MEMORY - sSelectedActIndex = 0; - sSelectableStarIndex = 0; -#endif sObtainedStars = save_file_get_course_star_count(gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum)); // Don't count 100 coin star - if (stars & (1 << 6)) { + if (stars & STAR_FLAG_ACT_100_COINS) { sObtainedStars--; } - //! no return value -#ifdef AVOID_UB return 0; -#endif } /** @@ -412,20 +351,9 @@ s32 lvl_init_act_selector_values_and_stars(UNUSED s32 arg, UNUSED s32 unused) { s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused) { if (sActSelectorMenuTimer > 10) { // If any of these buttons are pressed, play sound and go to course act -#if !QOL_FEATURE_Z_BUTTON_EXTRA_OPTION - if ((gPlayer3Controller->buttonPressed & A_BUTTON) - || (gPlayer3Controller->buttonPressed & START_BUTTON) - || (gPlayer3Controller->buttonPressed & B_BUTTON)) -#else - if ((gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | B_BUTTON | Z_TRIG))) -#endif - { -#ifdef VERSION_JP - play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); -#else + if ((gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | B_BUTTON | Z_TRIG))) { play_sound(SOUND_MENU_STAR_SOUND_LETS_A_GO, gGlobalSoundSource); -#endif -#ifdef RUMBLE_FEEDBACK +#if ENABLE_RUMBLE queue_rumble_data(60, 70); queue_rumble_decay(1); #endif diff --git a/src/menu/star_select.h b/src/menu/star_select.h index d00afb1ab..86cdd576b 100644 --- a/src/menu/star_select.h +++ b/src/menu/star_select.h @@ -12,11 +12,7 @@ enum StarSelectorTypes { STAR_SELECTOR_100_COINS }; -#ifdef AVOID_UB Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node, UNUSED void *context); -#else -Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node); -#endif s32 lvl_init_act_selector_values_and_stars(UNUSED s32 arg, UNUSED s32 unused); s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused); diff --git a/text/define_courses.inc.c b/text/define_courses.inc.c index 3a67c531e..6f7aa483d 100644 --- a/text/define_courses.inc.c +++ b/text/define_courses.inc.c @@ -1,30 +1,31 @@ #define COURSE_ACTS(id, name, a,b,c,d,e,f) \ - static const u8 GLUE2(COURSE_TABLE, _ ## id)[] = { name }; + static const char GLUE2(COURSE_NAME_TABLE, _ ## id)[] = { name }; #define SECRET_STAR(id, name) \ - static const u8 GLUE2(COURSE_TABLE, _ ## id)[] = { name }; + static const char GLUE2(COURSE_NAME_TABLE, _ ## id)[] = { name }; #define CASTLE_SECRET_STARS(str) \ - static const u8 GLUE2(COURSE_TABLE, _castle_secret_stars)[] = { str }; + static const char GLUE2(COURSE_NAME_TABLE, _castle_secret_stars)[] = { str }; #define EXTRA_TEXT(id, str) -#include "courses.h" +#include COURSE_FILE #undef COURSE_ACTS #undef SECRET_STAR #undef CASTLE_SECRET_STARS -#define COURSE_ACTS(id, name, a,b,c,d,e,f) GLUE2(COURSE_TABLE, _ ## id), -#define SECRET_STAR(id, name) GLUE2(COURSE_TABLE, _ ## id), -#define CASTLE_SECRET_STARS(str) GLUE2(COURSE_TABLE, _castle_secret_stars), +#define COURSE_ACTS(id, name, a,b,c,d,e,f) GLUE2(COURSE_NAME_TABLE, _ ## id), +#define SECRET_STAR(id, name) GLUE2(COURSE_NAME_TABLE, _ ## id), +#define CASTLE_SECRET_STARS(str) GLUE2(COURSE_NAME_TABLE, _castle_secret_stars), -const u8 *const COURSE_TABLE[] = { -#include "courses.h" +#define _(x) x // backwards compatibility + +const char *const COURSE_NAME_TABLE[] = { +#include COURSE_FILE NULL }; #undef COURSE_ACTS #undef SECRET_STAR #undef CASTLE_SECRET_STARS - diff --git a/text/define_text.inc.c b/text/define_text.inc.c index d33031f67..4c9788391 100644 --- a/text/define_text.inc.c +++ b/text/define_text.inc.c @@ -1,62 +1,26 @@ -// == debug table == - -#ifndef VERSION_EU - -// (this wasn't translated for US, and was removed in EU) - -static const u8 Debug0[] = { - _("STAGE SELECT\n" - " つづける?\n" - " 1 マウンテン\n" - " 2 ファイアーバブル\n" - " 3 スノースライダー\n" - " 4 ウォーターランド\n" - "   クッパ1ごう\n" - " もどる") -}; - -static const u8 Debug1[] = { - _("PAUSE    \n" - " つづける?\n" - " やめる ?") -}; - -static const struct DialogEntry debug_text_entry_0 = { - 1, 8, 30, 200, Debug0 -}; - -static const struct DialogEntry debug_text_entry_1 = { - 1, 3, 100, 150, Debug1 -}; - -const struct DialogEntry *const seg2_debug_text_table[] = { - &debug_text_entry_0, &debug_text_entry_1, NULL, -}; - -#endif - - // == dialog == // (defines en_dialog_table etc.) +#define _(x) x // backwards compatibility + #define DEFINE_DIALOG(id, _1, _2, _3, _4, str) \ - static const u8 dialog_text_ ## id[] = { str }; + static const char dialog_text_ ## id[] = { str }; -#include "dialogs.h" +#include DIALOG_FILE #undef DEFINE_DIALOG -#define DEFINE_DIALOG(id, unused, linesPerBox, leftOffset, width, _) \ +#define DEFINE_DIALOG(id, voice, linesPerBox, leftOffset, width, _) \ static const struct DialogEntry dialog_entry_ ## id = { \ - unused, linesPerBox, leftOffset, width, dialog_text_ ## id \ + voice, linesPerBox, leftOffset, width, dialog_text_ ## id \ }; -#include "dialogs.h" +#include DIALOG_FILE #undef DEFINE_DIALOG #define DEFINE_DIALOG(id, _1, _2, _3, _4, _5) &dialog_entry_ ## id, -const struct DialogEntry *const seg2_dialog_table[] = { -#include "dialogs.h" +const struct DialogEntry *const DIALOG_TABLE[] = { +#include DIALOG_FILE NULL }; @@ -66,28 +30,27 @@ const struct DialogEntry *const seg2_dialog_table[] = { // The game duplicates this in levels/menu/leveldata.c in EU, so we split // it out into a separate include file. -#define COURSE_TABLE seg2_course_name_table #include "define_courses.inc.c" // == acts == // (defines en_act_name_table etc.) #define COURSE_ACTS(id, name, a,b,c,d,e,f) \ - static const u8 act_name_ ## id ## _1[] = { a }; \ - static const u8 act_name_ ## id ## _2[] = { b }; \ - static const u8 act_name_ ## id ## _3[] = { c }; \ - static const u8 act_name_ ## id ## _4[] = { d }; \ - static const u8 act_name_ ## id ## _5[] = { e }; \ - static const u8 act_name_ ## id ## _6[] = { f }; + static const char act_name_ ## id ## _1[] = { a }; \ + static const char act_name_ ## id ## _2[] = { b }; \ + static const char act_name_ ## id ## _3[] = { c }; \ + static const char act_name_ ## id ## _4[] = { d }; \ + static const char act_name_ ## id ## _5[] = { e }; \ + static const char act_name_ ## id ## _6[] = { f }; #define SECRET_STAR(id, name) #define CASTLE_SECRET_STARS(str) #undef EXTRA_TEXT #define EXTRA_TEXT(id, str) \ - static const u8 extra_text_ ## id[] = { str }; + static const char extra_text_ ## id[] = { str }; -#include "courses.h" +#include COURSE_FILE #undef COURSE_ACTS #undef EXTRA_TEXT @@ -97,7 +60,7 @@ const struct DialogEntry *const seg2_dialog_table[] = { act_name_ ## id ## _4, act_name_ ## id ## _5, act_name_ ## id ## _6, #define EXTRA_TEXT(id, str) extra_text_ ## id, -const u8 *const seg2_act_name_table[] = { -#include "courses.h" +const char *const ACT_NAME_TABLE[] = { +#include COURSE_FILE NULL }; diff --git a/textures/segment2/custom/font_graphics.acute.ia4.png b/textures/segment2/custom/font_graphics.acute.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..ca8e24a2177b904a9e1d98ca87811fb7b8b8a2f4 GIT binary patch literal 4584 zcmeHKc~leU7LUl$h+^6F0hT((eVHtiJtZI}2vLI(0!6ewCX)$_WFr|!L=@`A1Kj)E zC`wUKc?wl|)CG|uXrD`Q!&<3S?L%CsSfnZzk$w|U;k^FiIj{ebb0(SjzTf@bdw<`( z_hd3vVIi(AzAiKx%~cU94+p<);G)x=!FNpB(GO`fr>+!rG#QTCAhX4!BlI{#E-~W} zZYOj!n!Wz<)}XD86NasMk*irBtDtB8H5-DjDNZFLjA0yj$^AjMIEit zyYnu^#5})$D6nGG5uw-eRWIE(yB7avM0!oN!gtV`tp(HF;j=ywV_GkGdpwQY)e`Q0 zWv!}h+pM|jmMcSxLwR}Zf=OH zy=yJ@IS_vwx_&RF4$Dk%uJB`?E}OV2N>IIrjUI?ne_PV>gA3ODhS?Mb2eb^9sx^HH9{&(Bg(KAWfV*1YUZNr@k&JPT-jLc#(~o7IWkJe-k}rHh0YKZ+?EG5L7>ZgW&M>y#+h=)gp%950*C6F%RZF z8ddjT_t|Xqq38ljvD1MOw3m3p3f$`oW-#8OpKIJFkvA zqw$b!4o@9;TRwX4N~oP4kiMey_PXK2b*-oGb|i}KceGSowrpm@kENld|1wup-@W(i zd7|=)&h?8=e}Sg8{dA{pUu)_qjnA@&-d{Bx54@!D+Llk2oIibX|2GmhTU?|u`pntl zCw|$ZYr_7i+tjW&=~=i5Ep0A5$9vVvJ32qJH2brM2fj`e?+F>5;T|zzoSH1yA(=?t z+;+mt`BsF-EKkidT~5(4_bnES*yAOmVec5zf!gM&__z(3C+D2@EAm%<)Rb0vBcQff znPA;DI9PRbq`J7(`=`-p621A-q11+rWxsV8T)7P?O?jqQPT#LqE!=y5X$F`n-UOH( z(aJdz%w%AqT9XE6+6`tfTWB=@K)V^m5^xgI;Bkae%6L*<$$$v0l<^5)$ySz)2Lc8}vr2#4cqxcqQPTT4pgI2ZT(JGNP3#NM^F& z5Rb`Yvf*Gmk&G|`Tp)joRwoIU&+MT9Pf|uaNtz`rmd$2k+PF-UC62`ri^VK9!a@)j zAYkhfBZ=B!qjfAr(aj;pt(b){lZ43#QJkp8ltfAy46qNqiO*nGD&Nu@tvxCLJy>?s z%;GTFEQ5j7+rml)Cj*k6fd16Nssg?NfrzbPR5Po*xnRc?5({y$)b0pqs3Ub z9yb7}6?oBIU0=!=JCKC$`|lqwurA~YjM5~7o)wX z6h$Y=Ao2rT3yILt%%7>siHVi@P(7+B`91zfg+N{dNmnk)ts94BEw<8YSQ z80Xla1eXM<6jBDl?1nm4RC<)u0Rzwjgi&jJ)xgaMBrQA$safG-sD1bnWD%jJj> z(K}ESZn1(|q*ys@W={~*!AL+lKw6ZlR6yXc0NF@n791r_7PZNwmolgjAj;BF;E;d! zv4j#lcggF8=MPePG_4J!;{aOE`hra{RYX|_l?lmx6 zz^r1u9acShQ4;=zpPqC03q1hpekbpxZ@*mqa=n)V?*;C!u70`ROM&+S_gB~dO)i&r zuRFLA`~$Lqml@x$Mr+6eyy*Lak`6%Q;YVT`Utarhk!0N6pw!m}vh_!X4!)aSSccwYJ_zM7trU(v` Jm&}M=@dw3g#d-h$ literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.backslash.ia4.png b/textures/segment2/custom/font_graphics.backslash.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..f10941e9a38f101a411ad4bb88326621a75d9735 GIT binary patch literal 5716 zcmeHLc~BEs9*%t^ zf6uw{>>KNo7yW$Cr7j6$M$YF{(mkHX9aKb!_rR(_zpNOvap%O6EU~!qrfnwb|9k*G z5Y#!JgD_Ckt!mKBHC#zEoi0U*jbvd;Zrk&$_;@Z}`ulN}LV& z;>-E;kD-&t=Hgdsv$f-D+nqlzI0B^lEkE48aw*{AwF$-jw#9zwwKFQSPrw6P#h%!V zBgey&RT=yDRD|`qRWaVHl=^y}#SIb=7+P!nJXZ zw9$`m4e7cx;bq|Pd)m*-7W@!mybXJJJQ%)}_Lx<0EX5oEU+8vcni_3?FkhNp&|fik z+}ZZ3(CMG|+EWxHR%a&;Sm5b7dZ~KoIiVtK{%Beh5RsC*uAgVb>b`1=zb5%s@Rp-p zH|tKGoYG~=G2W~DtyzIrxS?|bHfx&_Y!5eX+Vs`L$ykoG!UYUfZlof2F_)~dSX$NahhqU+P#oAz(yN{(4J(RXIzDy# zgu^w7eH6N%MQAj2C-ew%_kC zb??^tLAXzCnD39m+RlA`UEDt;X4;07(-@w>Iv9fpvN zdH1T5d-}~fZtu!$+=CMc^>rK6Biy;R}?;( zRTBHt%kxD^m#nk%R-1GC-j7|KEg!xieMtJ<(5aKkFR!l})os+0^>Eaf`Z0%k9o@(u zyuN(%x*5v#KzY}O9G2?|G3+?R75qzENlAdke5i*&8h<}B_VPg&6*5ShBIk-sl#9f zEk`5@9_27IY$|UPYxxwNQ7L(Ruv8+}aZ1TVJQ9vHtN1Cph#3|>Zbno*J0q2)ILWAy zoq`=S05I@2M(i-?jaJ&Bl(=wdaPJ(JNyIJ_TdGo$5E&y@nJm0mE|p7RDAb`#M4kf4yWkR0XY5JSN@1fz12XK|e2d8`$b#%Q%MMwWL%0dT1f z;1F5@85y#lh~dMCh!*V!AWuo3lQSpXPpY z7lB^qni7j$i3`MWFJfiVdCs*E@N-YGQy60k4=TJlrQVF|{vupFf$#zbvyi~DC?x0Q z3W&tD7{qWefhcf}(-LkPE$CL0V6!t8J|qP&1#CbHx!8z@G>bX(-QC!y@J^**P~R{H zp=dk`({h5AQxe(7r$^!(t5r}0$Yq9u41q_q0;Evu0rH2ECicdig z;bE4*ZFmAwU>ttB{-p-IgQ>65@ERfHN?w#T6ee zdI%^#c|1bUAbOuBIa!89NCG1v24_G461+2d6b1!Ws0#Mei*=z_6wEf@RL* z!kb1KEc?G!>o#b0z5p%BJqFG#;20!pIR`cOD$plB=BK&Ef6OJs;VcJExX#}dM^du%eXDOKA2pc-o8oUjo{Cf9lR%jGJ0i!cP#C-W5d;=riIHZO2N}- z=7>pFk*ISI=eM0GC$~2k^tNdtL%nN!JUvKq=A4z|!B7v4IwZdL1vYs@uNP07Dx1o7 ZbQG~fk4lYWo(xQjG@()Ionw-}`yYez1;qdW literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.cedilla.ia4.png b/textures/segment2/custom/font_graphics.cedilla.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..ea43ad4dd8d58ee264a21534393eadf8a6fdeb91 GIT binary patch literal 4620 zcmeHKdsGu=79a722nDSR_>MsZ)M1j4w?xXDh`|UEQz?aEWwnHeCc6~*HMQqd{} zE%;hQD)<(aM^zB36+sqMC?Z8gv31oRD66i|{SpxIZ2$3`?SITUlbQLxdw=)d-+i2X z8S>x&8>>lH5Cqvs1ARll(+=F0mLtIL@|4q4AZWP5N`;aRL6aDIgHA=N2?m|4Cm4j0 zR6&sO=Hs033jSwC(4r}MAD zFC$Y9_l~x@|IoE0`9PuCrM#=wW_ZWdrmUP(t4mw1Bu@6ID|#95wW}BMpd>fw4S#Xl z`q^=gzd86VIK1Ianf#B!j@=WwTcyScoyo4nxy(D%I=7LJZ#9P%x3$2%uOB_oWUg6o zsrk5P#p@nz`Y(!~$8|*n@=KYy!^hh?lgg;l8Kn`O^Zs@yJ)+ibOVWypT&vAtW#4sJ zN#y05cg42nFK#I1L^69O+%x>%an-r0Xk>ZYgCjX7BAwRcKU?!dbwSaumrgYICOn#0 z8C%Y{e*flmP39#_!_?X5OP$NY_%#J`G~m$pSqG;DZYbY$sNj?03somwuI=;Bd|EJ_ zdpo*Iaty8VP-aOTI%|DWBeND}+E^C}jakE2*`Iysoz_~hiB?j|T_cvvcFCOZylnqs zPvzV!izOGD8kE&YmnHv}rJ>Q=+B!DE>xNU+=@(z5maN_3pWT_R7;$R%oQft-!MZ7X zMy76jH}N=`9nIlzU=jG$vXl)?MM>gocvFIa7JIu$N8QXAE_R7cCMol1xHpJy$| z7**bJH)o!wzB6)Gu0?y=y)Vnp6!1G^Vy9fV8tUlPKBCC>UzLKV_MVBzS1%gR7rlPF z@lEB%uoUSx_mR7i`@URu4O!KVd%V7osay5!nwGr0iry1vQV{QO_2Z5^IlrVmsrl)v z`Tk>Df?h3tHF@;3GY8_g>@9?#VKYe|AGy@W=Ut0{#>n5f<;=nha=Q)Z4*r7~U+9t^ zWz{wkzEyj1y0!h-cz$Z*oIHF5J7dP>5rHR)^|yT9Hk~`}&=HFrtDe^8rR+LWeINi^eKszvyNSKLo=UmsJt24R z!$mtbBrjQ)z<3f|a_i{Uli>{#d(ZU8F7?drZARyXPBp3)**59(0`f3$i--#?KKK?+`oFt;-TzEX#^!DrD(5^5XX2^;aysd?)Z;1}$6Pp?chsdqqA8 zBPXWK4oN*vQ3;41g07UCDl?is>KKs6aaT40S=4HWefQ#9L7}cD9pu$D2!q( z6)ZxdSpq^NBv3*0Ac(~V5>zFs9_*C~3I|XsE?0nJDiO@VaTd&F38GD-Dxd&*fYjo;B?#e)TyiqFCb zg0159g*Sjs=~Q$QY9PE~K%^iVP(tQt7%u%}x_;L&iUs-`)D(-OU~|M=k=R|p zMEZk8Og;TBS`XxZ`0y|b3>pGJuWtKdZ!qZs%o;i2mKztLs&{B+g z17BnGfuB-y4_H_d-y1ht0nms`mN<4M^%2?0eWdD)qlj4B#UG literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.circumflex.ia4.png b/textures/segment2/custom/font_graphics.circumflex.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..dc3f6150dca23d34ca830acb4df931eca56f48ea GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!2%?s>bJ`PDREC1$B>G+WQjEo{?|9@DKBW@ d5EckyU^wH&`g`Ac$yA^c22WQ%mvv4FO#qAO6RiLM literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.double_low_quote.ia4.png b/textures/segment2/custom/font_graphics.double_low_quote.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..0e751109529f81ff217dc924dfeaa2b73d67aa2d GIT binary patch literal 4607 zcmeHKc~leU77tG-2w0F!pjM{=7t}11OhS^AxCN95kqD8>qB5D8gh)0r0|BI3#EMH% z#JYf@KF|YI#HC2(*%nbN`Vd@*zGuawK7>R26mY4wF8IC#R5}Be%%s=5hbnqHLB% z1)!cqmz}BnSGUIpz0AumtMI%g?)Zu?h8r(Bjk>+DqN=3!#4nGrlYy33clqnCOei$x zWQ%@1yyB)kfp78u(_5SdBj~74REd0K@H|XNYLS1Ee3l0Ba?7qEdrOeAm=A&Q2yWl(0>(P|x zZzlzn!O{ZO*6zx-1dp2PJ7GjeB#Y&~dQ#Iq_7Wj7y3 zbbI`E)>^BwnhsIjSJPHLu^w7}>HGUN*whDU|B^hYeX;u)=g74+t4HT=M0CHMFK??X zU9{()A6dKho!ekl)_lZ!QnGkr%92TL=|!bJ@9X5AmDi;Y*ggBse%{+h$F`^vAF7 z_j%~g=ceL)<6n+!^s4C&cs=zy8qHyXRw`A1$m}zQNM9g~Q<>P9b2$;-%aH`{r0TI z``tU>ZQJE18qc?OqOYGVf6!jmR;6!=o$!JSv58-Z2o zP>cs6wNv4kXpYgWN5OGw^{9qmnG72HhD~tMEQL%$=P>)d+E)}hlu`o&&;wcnZnTi^ zz)G#2h^0`Qo-m&mDnwu*j36+=gW-3eIKoVVTC}mkY$ms#*>*4@kPeU*wN)x0uv>s^ zL{c+>Qbx1VXw*sQwh$njrM_Y@o>lVulRGTT%#{Qf$!Q>`(^GSHe6IhbMv&I%^yZ$vWT)?biy&YBqdf6oW3qJ$r@E3Xj)Wc5ROW$F+hUI!M z1>OrhTwTL*y_W*-1s<-h|C?N{?_PHZ1NaAI0WULxh|?Y5Md)v;$hl#(*ZG?+)`O>! zrigfwMsxGFT@JL8UH)LvnUcxFojaX9M+AIW_+k4~ury8iY4zACa+ek?BlZ8 j>?7>|C_YatVaCyDogx>f)Mlsq07;XD&kw7foxJLQ#MsG- literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.eszett.ia4.png b/textures/segment2/custom/font_graphics.eszett.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..cb3f5abdabdb8f411e9a5cb2da76e6bb2895573d GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!2%?s>bJ`PDJxGG$B>G+=1o+vo$ zh?jTXo$KHE>6ZHmC+E$XH{L6}W}mt7aQ*H*-)u#E+n(0R2S+`ovzuIpWJ>2ANPO|W zl!_{>M9X}KJ#QHI;)(Kf(ZXzAlm3(8F?n~1$~ifopBb`$*dEKQgerq?(b~`AO34?d}~C=oPxymR}mSkh3oQv3C{kbq|@`!?(4rl%K2hWo$s01 z=P%dlc9h;(swql|v0lbUUR%=%oS&gS3; z&Vxg4LrApdkGrEk+E6s0%&ErxNd97|@+&|0Yk60{$PaVeoO5;--|7m-ZE`Bu{j1yP zNh?woXz9v2e$x&BVoG)O5&g0|IXk`FX5YKM^=?g7k)b)OjY@i% z7f7!`8$*4l$7^z5Vuj>+{YI+7CxJZkT{}_V+_ArYdG)s+Rew*fC4QRmSzCEJ+No*T zJatq+P}uU)<_mB@R`KSBNMZ2+kBVuqVF~25e%aO5H3G+dN#Dl(P!&Bj-}BTs2cGMx zNww_ET@edLxR_gR7ETOKyOkZzcGxfeabfE-_r0To6}RB@O-I9iA17H@+;X6{{@=AP zFH{`bV5{%Ke(TaFKg~+nn$X&^(tjamRSQ~{JvR7USA`3b=<~?;;iwgbyFN1~c=I4= zz&KK&h*l{SuUi2$K*`4Z)8UPux-CC+K^x*W=-BcGr{BW;8fyK;uaZnLm6XHw?R0^b zm;0e={K3gBO5gIKlOGOW06ARVl*>*m{_<}{Ptx{vl&o8_-fNv?=L1EF+q%ng&qSA+ z<{!LVE>-S6zRLJ`PxGXE(=&qRrtLT=te)}o`qz4%lV$A2?IZr7bC9gKd1+4=vi(ZK zJ!@2xpw_EN1uq)$U~pQ})%NsT$=XGMZB+cx+jaVv+o-^w$@52u6QA>jJE+OhpT{Hb zm5mu4^!{xRQd#*=jliM4G%<3_@zR4~^;IW+neapwKKdj!k+Z=RH8E<#iq4h?dsnYC zpTAmCv8c7E+98e-F6{`N>2vsnU}B2~M>-cJ9GkYimf=O{!aFBDLO$G=kf<|E*m1?laY;u;JR|f8xWey9rL+BJaYocXu!7&bz zN>Bi50bY51T!yOD(Qhmm3G^govReVM`ygpj_g1Vvu`xULbb1E@%-`_#LBG!34hAT- zTBbB&^O^8eN;!-1FT;%(iOcM_QcQbyA%eM|r)d zR0a!;8Zd&P0_1EG@L*zzP9)Ld2&R>C5h0375NQBk2Y9r6R43sF2>EC)iYPM)suE4@ z9Th``11el62*9KgJ|fbJg@_R6iV##6z(=^aR4YKWd_pSL+Np3%Hq~gRP;i_ih3W~8 z$)LAyFoMe_N2}y4KAZb?B{~(Qb-)1h0BOLDR?FKh4M`ExX_V2ECkhZth2V=T6^R8R z{##HyVYYx;WLSAzwxFAtIT#s82S|%Dl?n*#79bm$!c3sF(X25VQ{^lsD44Od7dRZ) zeJo+51t2n*n(wLl=|o!hQ+E@jlJ+eawim7p#k!qX&~yT~I|6pyTUat`&=a7;drIo{ zI{7EZB@l@us8p*%#9S_OTmb}vighA{5D0KWDiBC`B4J;4i%~~gQ8O`F4>ASWfD*E2 z1N-%eIleF6noKZCaY27`#RyNN;fZ8IzAS*t;`AiTVS4&?wt<}g(Ie0f=rsg@UH2Lo zE?`!1-VCcAy%-7q!cWgR{DmF>b-$B$(zjo(e!1RBfp-G;S69DW@1(#xf%~iL|0b97 z+t(e!0R914!OM)gG^ZWB2o2Omgesw~6{}Aj0#8FsVY4g{G;}0$4S?2{cz{JmTBQzg zY;|-UG=U!(a=!^Id8(9?H6G`&B#*LRySlneqLK0LdBeJ@^ghtqwSypvdioHcAXP}D KvSv!s(*FWS2*P6k literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.i_no_dot.ia4.png b/textures/segment2/custom/font_graphics.i_no_dot.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..31127441ea011559cd40d4e530d1707dd2d83d94 GIT binary patch literal 4606 zcmeHKeN+=y77u=*s0(WmQLKysA}EvZKoSTj1Vg}Jl$0-7Wim5?kt7q7fdtS}Q9-RD zNR_IH;$eY$7A@+^LF&3Fl#0(jXq=wMq z5S3xTA>2Y}Xf(^MpAPDb-O#MuVbg9&j@M$({B47uce*`(`h04DzNn(UXn<^W{nBZF z`()3u;X%n|R-iL4ud2tV^4x=6^Y`cElg-gFigk(q9jv)4Ha{~c)H|nCFFaNn_4-K3 z`G81OdxtsqtJ29YUoX$E+>*_1lzH$@bdr^2n-|Opn%2u#=Hoh_`imPb-`jWo?!n&X z`hza7gC0BH&wVV|;g0l&oGEh=O)eNT7UblYG2}|=-oND@JTnU3f54SBMJ!qsy#!i^VhRX$rj#Dg>*{do&axb?iL$#I?0Kffutz z9dfdxuIl!jSjWtO#8o#JIVIehb^7x5>iugL)?ZLBJ6Ej_i1_2GS&7@|f~EYb)92TQ z?JUen3eBrK<6HLWrkp>R6xEILic|5C`<;s_KJ#sjtob}{R>i@V z7I@vJr@cRZ(|Y%8aZ9{`*cjD$=7*BVt!;N0#0tb37717Fl^ zRNOduGcmH8G5fhJvh{H7oruc(>g(vu(hF%%>Wa5k`+4pWQsu}M*`n`Hq^n;m*B@WG zM6kZR;=~`WLxTE4$1{%hV$+gd%w6nMyNl*_c*)sTpOvK#8E0W$)DCXW^>6-k&2w5# z%?FQ;yVd{I{+hgh-JP7K0R5|vjL3rw&3OT*!#6V5B;aM^TGFht6Q~_R~vqE=UnP=*bw(^bmfDhn&Q^H zw%1(|hlXblPdYWT&T~Gr+Ji>3^CCh+mGaQgH?090qU317rHCs^=dZJ?n|6Co-@VNn zYp>~2Gv*B^8N9FabFTR)5_}mPPoF0L-XpzND5ojz4faaIK>f9b2H*9<&B4F>Ve|cq z^A5)>WQ3)cz)kmEN=`1K*(O6}^aEnn{58_*{CeOqJ9XXS-2u$EUX>s*db!&2V|R;zoi}AoH+fZ~w^syJN^;1tYcZ`R$FG#~XW& zk*_BG9IQ0lPF;e58RJTTSrVsMB}Pdd6TwI|&a~(ZVAjxRfx#97f~MjWq{fp8y@dXx z{t_J`FbO?YpkONup?C@ro@vCRGow^!W-2Pe=)pk_ffg|U(BTvUS#(;xNo4H zv86LM5McfmcbxW{+-=H0OQ8@;Ni@wGo?I%STm6eM5+yLP?G@MHn8=^YhIt$Wf%!bH z23F&KYFH%T@iiO{q817{W1!@E6NTte+zJK2nFPS$sf7ZO1{cC8myg1Hfk*(XaUQJZ zv)L$zqrq^5HwI$0kpNYRXvaong~9+7SBR+DLXimOaxol4g9u@@NXUWtBDTLjpDRF6 zE@FeiQ1MFAs6)VU5;`OqXBqU#Hi4CJ@d~9}LgzBs?{<`0gwg;5&;x`XBh99FA{C*- zqbbD7C&y3VFXH=g1tKn=#}WVn4x7mvkysB#4AKGABGyU;05({VjX2bZ zBNS;=k)&2aw+01SEo}u31&$m`IAH=B8P=K~t@>zu)5vP13ABVw1VOgK6(i_~6BCk- zV>U;?ZbXEpAo^q+bogjVz1b&z<+!*!KMlg>W3U?GaACe5ABPdX28G#v{5nquEG6mUy60&6jd5@CmGhW}Ef?JtlgZ^gw!yG>q$4|`j7xP4P)@ZUU zYfrz)HjwoTJ_2nDV}<~*8`%TH1JJ>lfN_?@6@g0A;s z;JuV5s%wI-_hR6^lqag||3;U?yXy|F2mgS~;4<@VVj~4ELX*^yGAV61Z(qwLu$o~A zk2le1Ge59CcC^DKu3*!ik}JaOd+eR2cr7WXId_3Ace!+h%C!Sca*gO}%XVJG>rAtsr;NlHKouc!fxsRc#KWFBFJJV*u-@O9Pd)dGs3 z_@cIG6%~|<56bll)ee|ecFg<>}_T^UU(U=vMm(BVW9MkCYo z7!5NMIE7-q_AqZjspn*;HBB+Aw_L~>KH^+Kxe{}TsaSqLqb@eb(x5wBFeafO@2i0L zNzW_0#@rg~7!v7qAng|)%@lTZ?LfPx^@@437Q{aMy>#I!hqNC9Rcq}}dY0^rcsncN z`l^XjsSid=FbxRe>F#oob=jN_*^BH zlGjz#XH$lskA1z-_vh38xmnPp@~c74P6_$4OPiaE0=CqA{?lxA-aXfv@ZXkgZP>i* zhJESup(EYjCJ(B)Mo@fKCWb&0Xp}`0X08(;0{VoD1NPC#ytAJT&Ymi?ubDGpMb5^0s;|_OR*elBF?Gnj+Iv2B#Z>o>>Rre%clWFV+btG;qAW*saZ}EoG@ns!8C8~? zZRMCRbKF8ndHLcOIijIV`FWoOFY=8(?J@D?&HwpiwIcN%o6>KA(HFb)B@zMF!RRWFE2k6Yu0rIN?+Z2WO1pao`1-DQ&iUF+PNYT?HvEcC9CP^ z^MmZRLS=OZ;lH$h|XXZ+CC@{CY<{ z{aCT;_VFf(Yv9^OC?e=du9=l7J(pTGHq7nWZ9;d1Gn<)yyyRNd?M%U^v4dt)-R4}# zp466q@y_(NjjsC0^&3N-F6~&fw>fmvxtiP2meCIc?r96KxG*2Pw9LDh+oQF2iDy4_ zb)0;W9H$lUIKn%-vXozVAS<-Jb8t~Wap0+^DIu3z9+!Py%R9GidBu~VZKf#vr(oX% z&{?Pi=pfPZ*CENyJE+3R4qW3H|YjN;-`|CG;=&a!9V1 zVhKcex&fP;9-&0i6A=+g4-9bhH;Vy*1|wmbS(BtSip>(bjaLlbt!5UTW`mH45_+^e ziYC<=FdC1^V?vA&Gm*-n2RPFF4Ja;F1c&xefG-I>fh6@}7RzKZF-=^i&Y)(oMIsRk z;;=Xz20$>3X<8CCGqgr;D@8X)FlIyygq|dHTAGy;R_Rhm37rncY476G=;iYF^jc$& z3P2B*8P>DdOo*k?uzJrhk|C*pq$i+1oncghM$A%RMqP>l!9r3oE$Q8xB1|Tade2}@ zNlj?M{Mcz4g|P+&)*0A zE_WLkpyYCKuntMFI+X=W=+=0}s16}evF(+Epdy@yau^(3g)?|u1ZDWCR0xC5g&-J* zA&keydQr)=MiSN{n3W2UGYP;W#38Oqs6rV6j!?zmu>}}Igm5qh2N5EW0Og^O0PjT+ zX&^vV!b!cOvQnXd3K#kba6b;h;0QT922Y5K7$OK(F}OmED}qFr2<7|PsI2QCo)IOJ z&^b)#gC!~nCUKoX14^CHqB@iD!;q5DU~@^>DjQqCXG21W%j0t(k%+_p0GfvxjG*MK ztZazM?Pf+1aVX$~LFo`0SdFptTD5J8bz#IH9Uv`ityI8lvx98JQUeB)I)hTDOOnv7 z(bBAxwgRX5cP~pgVFZXYYt8pm{ah@$`>T5sBoVeD8qHR?Vi@UmVuVvM)aD4x>mEW9 zV67ShJG`f)-r0#iSuPmHg(@LW$iNXlh{3}-Du#;B1rIJ?q~eH#0u`$2%Wl-+qzN`) zGt?kckPRpyTQ;;QJu3V3#hVf^tAr5P-w+QhrIIZab46l^PiOTc%d+n2ciH;0{zngg z8=zMc0Q0(Spt*ov#d_bYdi1hN_!nM1>+lzP0Mz|XK1$zyx%%b$CAXh(oLWSeMBIZ^lQi046V4@C+rj9*L(OZLaGI?DCp6N(t|yc?V^>#yG~T b1c$F$v%{P1J3m_mz!X_XMDU@Y_?3SE5An)F literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.inverted_question_mark.ia4.png b/textures/segment2/custom/font_graphics.inverted_question_mark.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..0ec3621dd18a1509a18495acd1b605f6dedba4f0 GIT binary patch literal 4628 zcmeHKdsGu=77vQ(Mgc7#sI|oSM4Dvs0x}X1351{lgrJD%GMSmcU|u8x2^5d(0|dcm zRpe1^wfLwAiV7<}QnjK8YAae)Km`=HtSf?6Sy^Sj1VlXBe>`XVA31r<-0yzBd++c5 zzI!rRVIg8$>O?AqLa~(uiNe9}SnwG&${Kt}ud4W*LK!|eRTf2tBL8NJ6hFs&L~3LcO3`Tp6rH68P}Np95UMI^yHN=QGeVVhL{ zarvxja|bugf67MoH2#h0PcpX!&yHa~H*T-2aICw(o7L&@_X7KRagLiG>+<0z5$`-g zJ3|~Ib6&2cYo1(4Hig|h^uX1z^Ox$b_>Db>4i;`$w|NBYbPHX|cCOgG^iI_;uN%g{ zHNHAB-DK#gJ3S?J86w`bev9Y?{lM_DFYLnELGeq*teKXPc%dOdb9L;NxWvlf)nfgr z{N2>1g{K1TPpGf27e{A>j!PM(JNM?m3#)3;8=^R?JyQ%T4kr88^yMJd)vC*w)(VgO-V>*-4=N_4)DJzm*-09hn=Dt)Fv}b32 zd1G;k`;p{lHxpOAY&`N6>#W_xprWlAo4l3Xv-X92e{VZfcPsCJbPxV(_Pwm%BUY}S z_{}Zj%#+st+MBWDcmXxKK8vZKR81L|*)Z>K>)I}T2^am8-6$VFx>YvoqGVYu%#hP| z*&GY0JT^LQ?6ODqTgHFcl-O#T?mWKIxq4;WtDNY+n!YP{m=n@WO>ivqDYh?tn)LRm z&+pBL(--&jX74?9?eZZ=xasv<#J==y?>(jQ(%T0quJ=1z_L1EiZ|9~_I|ABrW!+Qj zA6(xzv!Lf{&2vrH8{cqVV)gdt4jiRv#k+!I9TbYybi&_1OyckV{-A*4QTWZ4Yrz-i zI;NX$wYatiCN|q+&E*fPN*cTU*JjUCxw|YY`g(k}WQ-)Z(>BdvTY+m*+wK0Cd-x-Pl&_JOXnb1hLT ziKx={Q@%ISylOX+`-2zcJ3ah-LqQ$=WU;)p{DE+sZ)Ot|GOzP%BP++hCb?pg*x^Mh zp*hZ3z)USKy?4Gf$76Dg%>oyPg+FhZ(O!7-(cJc}ei@R z&cAs$r7Xpli`|B&IzhV(S3cW-bNSzsBjXY z8C6QP9ySW;7F-xyo6Rgb&Ei6?5YnThVKje@4yW;$JSM~lFcQfex(}7+t-};>xG1n6 z0^AAd@g%8*SuBIWz%+1~8eJTVEf5G;5QoL#Fn|X`pQ0uaBSWp9YKG{;5aD`MM`%ex zqo$cL5xFLb6w>Kno%TLIl~yVpfLH7LSpa;njEI)SWfNpXZqYbgql_faqm9q`j8>68{93}xX;Tm?Y& zAV2m;{v@IJK-NdOnO7|33{C`u8^Hg_`+e;eXW%83!XgctWDY733F+p1VN8P(7;L%3 zF*(HN33v>i9Kjeoz5->)*?c(zVtdKi3I*iF;bMcJBx*g0s8QSu1;CjEz!9Jd1mSsj zF(8QV!Qf#4LLe6)41q$=z~x(m71%gC$IfkP3}X1*A@>F^xh0VM#`)@CXty z)5iATvmsBAEC=GUJ-qlIoEG6aJ&>Fkl?^eueaILJ2Len4NQY1%aX3q>jUv!A1E9&Ji&9xVc>(3eYJp zh|NGf%@ji5d_z12 z$5Y1kgn1nBrnCBsWtq?P`)a*e|HFs3#bMA80Q>rEV7P!;#Tpn^{d|Ggf99*d4}WF| z8f_@ZC-FN(*AQKw#K0#x52_lPunq3RQx literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.missing_character.ia4.png b/textures/segment2/custom/font_graphics.missing_character.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..12f63b3b77ac2651a04b9a054841d34717333ded GIT binary patch literal 4664 zcmeHLdr%YS7GEn01yn?>pmNQPXhCPQ*}Rhy5C{TFY>YwiQDir}frY$C781Y<3JPr{ zVpXI?(Ti{E1H`r}BFH#EE!t}FRk3JQZWVFF`r?Yn{Sr`N+JBt6{g2G-X7@Yi{LVSQ z@0>IF@|j|8_z2ett`G!`h>Vaa!M6vvTwI*MeR0;&Nf0!Ym9C1Rm6(NLG#NCMmSoUr zMv_5VDGdZ!ubnK^t-tN(p4(&oT$(-gpT28zYE|b(JnQVr4%)q8?(X_uKS`QCJZD|( z6X^Zsnws=Z=TZI*9+v`IH+~R+Hk=(cV%f7jXN7QbbwNR^HsDEKlIM;&ipE#>?v)31 zQE45rVQ}}&@9(4Kfg|r&JD-0TUbT=j)|UFwq}J14bOg@K%c($;B7b>s+w-!ntogX? zMwXenFqzDHAt1{9Z@E04=IhqN%!9mxMk?8-tcWKT;d$YMi${8lxvQ#vXnIQcwS^`w zr=HAgO_W}c)aAu5{$kXawArT0wxaHpPpFxPI$xruCp+p2x~HB){L+7T)%mog>L z+|+41B|d8;MWQ9;OGe|Xo^xhxRm@oFQi0X!AmYbI3{Ck^*86;Hy2IN@WSuRVw2fN4*TefjFymx zxBWb9OJ8iAaTou`ncVzfeHAu*_{D;qZBZSIwr;D9J{1+dsbTb)i1x}8F@>2ooH)U5 z?&F?j4nK44H^@IEVYQd12gLW>C0m0|9PN1zQZY)BH48i#(Rz`KH4JqN7=M<<_9I)PFCR;cX-eE*mIjY&-c$cIKYD+x8MbZa zU7rl|lUhtOChD%vUUHqDvsqW&dXUzB%PMU+Bu%;BVn)V)JM{h@Q_cjRi`MlMa#QDp zmi=-syFO)mj`xb>Pn~WFJmNwh$9*TN`#$G-+;>F%K1FVX&)EqhaE6x=Cy#5U>t(w( zE?q0Dj<~|>)LqFOdOUv@TDU3s*p$NEk50dQ`21Q!+DS?W|M72^w#(})_+OpsnsT5Z z?zZ>kLldhOWYrwR>i5OJ`fok*-bjV%nyse>3?MHG44N2ultgXNu`t4blPs&w2nG=Z z1q4}*m^z8188{hF>7~qvCu*1sijXoF^5tx~F_cW8BGOId{Pejhb$XIoOfZ82T?4EV z0H7mjjA7Mj^=64x%5>mLz_WcBVKN*lbdr=ABUdm&4JMMoWARvQILu0=a+raxi~tj% zktk)e`XIoYl$k)&MhSvgEEbl9%QBea5mYP|BWw=B;lMxxHmB)n%nIwxQ|u7E7&6kV zHc>{JGUyq0Obj=q&{8H7$QiHW(;4ORH}HCM9}9pF#EKaal*LALI;6janGQ<@AbkP- zrG;4q<~5=u&4v_{nhZ-N_4Jhf5QO@Ty)nh4b)-Y65mHO)fT|gIMF+SHkCZFkSlB6u zr*uY#6(D$CIGL`%3EdI`tRZ#l~=gkMl(^Paxm} zjx~T@zJLR>New0x2-rNenjDC3HfU%IW+H>*L8c%ZP(qGu7=C?Z`VZ8%B#?Hd*r2~r zfXh>%JP8+-pd2RBmn>rM>DSo?Ab;W`z@gA@2mrg@H85PjtU}%lt3JN$6#k8$zJ2%` zJpkxIC-21XAYFrWy%PiPq&!$%gLJ(U1Mj3fSY7`&x?JBLcSt?>1!Mt-nU&sU$>1RL z9zG{r2KD3>oCPN)=zU|vA~OWJjj>-tpyDlFV9}Y5l!rP0$K7ejWcQpD=)V2<6e$Z< zc{QzG8|(_rba@Yc*|TQ#uXEg#wLi+e4?xgN=b^c){i~)uT6yGW*52%|mE#lEZ)o1q f?%s7J(QQ0x8`br3X1V>pAt*9zuIx}qT=xF}(~REr literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.plus.ia4.png b/textures/segment2/custom/font_graphics.plus.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..b6b8839153c15c43f084233b2aa2009dbdf47b59 GIT binary patch literal 5553 zcmeHLX;f2Z8jj)$sEAr{D={)Gg`39c⪚Mzf4 zaH&h(2OV%NA}XZ{DjiT<7#)jKQCsb_BknL?0xF*AAJ0*Lk#jAn2nB57B~8H}LM&s~h+`b^f7Y0)bONrY@e>k{Lp?#iZv_Ss_2$%nDf> zrxyrpS4;kyl7CI;y0G={IpXq_Zthj(LFe!EJ^K95MXS~@Xsu7}TKYtMzWAviyXD^P zUcu%S#%YUZZm>)ky03u#X~9xc<)q0G)22UsQk0;SHQs#MpAN4%`=6#e#bvp*>5X4H zXFff@qW<@adCx?ZwPiOHN~bfr(@n*-F{6j~_L4O5(Mvgl|FP1IC$BF%n6SO6vUI!8 z!MQUE8-l~s&1#r_>B`~Xd>&IZ`w{!nc?iVmV{ePNy|)?rGNAFJ6hH9ZDsQ4OY4y( z?gO-i=QRo24`&u#>rX9e7H}Na;Oud5!uVNx?mEvj?7p^C>p#G$ep7g!bDz7r_v%I< zmVT*Ca9lpoM6Ew^_LfJ|=5n7YL*xhQ7OI?Ql+-w{J2Yf69(HRy%r3yz-uv;2`-T^Z zxkm;q){9?!KZr*zFzWBTWhn(&UGlJiZf9b=v+{m-&5O#- z_Ya`uiNmr7hwt!4iq2>S0ply4?r(}$hlXz1h^SJ>LZ)@@zE2TzADVP(zuU|I`+%)+oig|jYD={((TPW zSArY=VV+l9w`X?MUjAaZcwxwm5W)kW^{Iy<1QY3p}O z>hR(KB6n@V^qQbZ9(98It{Btc(={-8L$&l9&)F;2RUfRrJm{?3&Q(*kXk5F|zL&;& zq-XW}dR4=r!`+w28XixwkYCSP*$`%2wxi_9&|OO|?{`Vk%F6GbdUk(dY4yf`W=rQb z|9GW2STW?;aSCuUpV-EmGU|hw9qSiV&AeZ`b%ZTo4wY_1%fW#oLU{NQLA6J z4QQ72h09APoQn2bw6VBlM4EP3i1+6y6%`Z3Es18oy5a>F{Ufx2K8Uw}#i*vjrV8Gz zo21+&+T5)Ap}aisvSXIBA zJ+-6m#m*T$V}I`P;=H&Q4I7jEb92ThU!6ESr;uASc=G;P^^YP?WBZ5uaDMaL zA1u-&U;a5$6V!WN&^g1@n9M8KXBVa7+k6v+F((TORvyGB-5!|jwDZ%Y7o56h;XYc^ zt~D#C#f

O~=gGdadr3Vbbh`ZLa@D@>gpP`>y!r%&F%O9$l>rE#VC3vEWC$C&ym& z%=_1i{+D_bwYct<5mN%nZcN4+by(}%MvrdGqOH$IO2N!=`-%f&CO%@Kk~SH{Bx9mj zvCUuxV@Mzf3bvU^I)&wh6r02uRiX#S%0xnrQHkP+2spy5W|O(_ObZ*E8L6W)Q)mSv z3LfnoWK#kF1Iv>_n<3R`RoYY{2d)x)w=YXXLWc>Tq7ubNL<`j>3oFFMxEO{)ZCpAk z8tp6$vM_q3He`G|1h`U(l6l^<?l%GQ=5}*knnPAPR*-0;3WXg@6TQoo(bv8)USO zv_rIEgs@iH!kKx_WE9#lNy?PQt3)EOFMJuF!5k6s3f^dKR{`iDv5{s8B8DXfgQTN} zl@Cn^AngJDp@&rmrnN-NT1{ydnhi~7jr_=t5Dfjw-<)Pib{tEXE>zCXe#=t5fLK$MB)9m4C zLR2FA`AWt_bBxmQ6{9gdL7_0Dm*F&oqYMs_3YdUk6qmC!L69tqb%4?stvqR@SvwQ} z7jpoIl<6@Rladfg!4!nEv=pLPRtCWcMM_DUf*Bm`01;*3Kvj~d9iy^CF?J}Ll*$PL zgD4C^ARMC!NFkH45W!-46rp9Po9ku@bW}$+2M~DgukK zHe`EZlz&$Cgm&C|n>;+aXpmon;&c0l&5_I+-*kv7p1-OX}r1_Xp`>r3kCXU>efX zGz!v%%OE*HVGzl{Qba~D3?*%&@e18)((@Ulg&ms&m;yGSgdA*ye(hrVzZp$NGHX`~ z2K^0V5Q^$hScyxOxI!d(|McVpLsK$^6x1@wK)9SBAvs0LAQ?kYundOfu)ZyO@01<^ z7|K2bJ%oj6DTd<^OezS_AruVB8B7n+2qI?*kXlr)crzRCB6|d?M5G^ro&q5exgJ+Q z3XHTDCkkc>hLVt!BoPHBmtmAl{~qXJN*w+W^jMrF5DLsU8BO32u0SzJK`?TNLRg%} z2!bWhwrTs0iW5V02;e4HBFIa6K@$7@^yQ=plKkH+YBT6?0|q_YwgztO;CF)L)enXC zW(Kjo&sX~le4j@Mg`J1ImA;*Fb;|Wt3cQtZXLWVT^;QbJm2qcvy)(I-Uq5PKjo`nJ z4DcY~3)fT6!9$3y)Tdz~g4XP1)n(wSw>f-@RUmK~V1IWJtX=O37JKrVh|r!tIe7_S z7nkh6B!Hz+nvk(N&ssWBDDaFqGT+nwieDa5P~+XIj-S72Ld-z7qOQ9dgU7A!KBe4i mpg$8=v}w&luVo|mI|+QhaOr~d4{io90!?US$i8uj3;qY4WYXOL literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics.slash.ia4.png b/textures/segment2/custom/font_graphics.slash.ia4.png new file mode 100644 index 0000000000000000000000000000000000000000..891acef3f4dffa3d02423e392fcbfa01264df176 GIT binary patch literal 5501 zcmeHLX;c$e8;**ih}MG(2%<46;xft1WG2f%S5ky=7w^?B%8%ZDm6|JaL`9zOJ zi-3Y#t=hU{TQ{UAT5IdBP+I*|P_b3(hFkskZW2U1?H|ukf01)0nYs6UpL?I@U1lGadW@zB@ndflO8kK5=~l#Mw5Z#wXD#RW@Lq| zjpqac+pl+5#;^F@-+j^5*sxVI)a@77&VVQE$&Ag&fRERi>nvl_dmqnjm3iiFn_f9{ z8|tpP_Fke~^wrHloA+KTv)-JaW4JY*)5I4(c~PlfbKrpyqTD;gDT7qd^J<08n*UYt z=04rhrgnY#Dl}(wX^?;1BF1*~_TEkYlCU3cxj=1e-IGRF-KE>VOx}05$NHlC?i%f# z!?^(&;UV?;R8-z4eXF9fhq^Kcdu^OCf1JUiZ^Vi-mt(VQYCCv592|MM&G%=rwmsN% z#&_kmr^ElK7#whJ$-&T?zCYH@oSx%)?s5!wCunlc;q=)-_X11*dp4y0c=fDDf%M33 z1N=4;-xTZn{?fZ9HP7oy)sd3DJ*O>nD;Tgrk($!BWZy+y_?FzopKcq!apXe6ch5I5 z*QlC)JJ*#@iM?5zoqTg}=JZ|*i2{bdJ|li$z5ndzBhG8D%*?ygYn4xMZikZZXS_-XNa)v}JU@ovjSc@q^Oty>q5T%VgL<@${f`Ob5jl2EwX*Ck@5PhpM!iX#CI_Wt+Ar*`L;$#cgFBG0(5XUHsWwQ|rG=syweha6e7by?S%S zR(!&?X=Z3?0rp!T2v53V8sh3(IVwEhaYUAHM$HC`wnV({_;yvwA6Lv0&ys~twj2yz z+5=y^aZ&Nq3-HX;@xeEUvt{l_6rrt?ecJC_mj+iCQZ>PPxEj3?<6o}!J>}hr5_)|? z-L=r3&-xQ5=48k3v>jjCuxg6e?JNDCp1Rw;M3xbf;xR1pTErbc#hkpLgFC-?uxHlH z@`SGU_caW8v7_6QL(`{TowmEAt6!fkdW7<0t%#X z&GOPwzSFEJr`DVn;BPjJJ)YekI%hUOcs`dWDRcjXTRaFbIZElx`J(j#0GVA$LvG1>c(yrv{r&*i( zd7r*DWYyU();^fI_T{6YVaYv5d2StgD%y#Fsa%K1+I&DlX>v1olmVXF0ygXE&Jk1bSkR9MZfB(gaC4OCP za~I%!E)|ha_V-PyeOm3!6{g=TGW^}z+b=33bCTCl&}wpd&{`&I#t^hYCngyK#foh@ zBWOJWK|qkrNYY8HMM$v;yj~@`f1p$(0H9+nq|m0*>dk~rC34^r;M_he5eXe8mL!#EvL;FxVlc5nOpJ+PD9pyEqM|@I zVStI@i0IIfjS%2UB}%kdjD$pDwOYkisn}pjkRVE>QUaqA6or5VWKPptNE@U#_p?Jd zF+y20ZQ_j<-k=xSF-gjhVo`}iU|#roe>$T^(*&v>ikl0A01QEj$oler+!)ysl z1t5(Z`d1Hg4Cv63Xx3~#DHK?1KcI=q0`Z&_M+?u}S)?ae;ppwoOKz`Y6gE$i3Z9mc>)qai{Kbc%g@>QI%) zzCOViXr3V)r&3zV;S>r(oE)Pe3}rBgRKhp}qnLuFahzmXX)`Fb-fSWDG;4U2q~eO05#1V&|%k zkti)`;eZ3E0bb7-tmZeyF}#i)Zz1h^A~HFQpfZr37=mIj`o?G?Ychjew4)-hSn5Q! z2ZjK2fV8ANQvra(1F#`NOe|?Jm|_eDtx9Cyg3#{iNN{0*Gb|Cj8Cay*bG|X_$Fs@K zD`ydCdB>Dc=tx{3j&l(+naVPbg@B)PicTc;2`s4a#*}(J&i_leSQ)}{QkaG~ng-!w zF*&5bDJeuUundvo3`5DBG@8)O2F_w7O>A%iU<%lP6mqZ;`ZtO>= z3ZZBW3KN)&z?34%ho`5&8JdzSWgwSH2Er6L39^xtLvjYEU^xscV9pu6_eu{34CNn# z9>T)3Op0L;Oe%3uAruTL7%2zQ2%=zd5L%Q|z8#JC5j`9w5ZT9|r$k6Z!C^{BDJAX6 ziON7LKuJhOl892OkV`2!_W|fh2@L)i^iUMTXarS291BwrMst8DM^O-m%jF2hpfb=n z-y1yylphv@$Ov3UNSkUeKw`h2zV0*ul7I9fr$MtDFsNDQ7`U;6=LAX9gF<65gF^a{ zpT-{eA(s#eTNZgIeOu&ek?WllcqikQ>}rwgofLQ{Y3a&aBBVx@0LC3E4qm>}P&e>~^)KXT3_GvD{SzkBcRyZ4?< zM#Qwqp6-L(84QM}I!vVnzrDf5WPS#|W0n*SW-z+KGE04a5{Py-}j}_NtrC$_(+uNtSICfWaPx4JmdUnF7`zc}JGam(ctn1Trmd~rD z!~K=-vhNS+S20gJxQDD_qG+86QqC0RRK@}GpSc-haVPw0|4D;lw|msvTL6UMDSnAzBz==M6XB60TC zE!8nG&Epd^~xhqQ+F@ISxM{K*`eOZ;xLBoDFr5s(q@*l>p zHY%f1bBHI3b4Pn@*^FZ+b$0@Oxyx4ihi?n-OT4HaqA(SuzL8qU6GOND@UUEP@9B}c zRZ$1#tZgLV#zUtsEU)((aPvyviGiDLMsCQ93fzUxv?rwRZ!%AQq|5j+UYi@ddZho9 zHXJF~6YP4dA}z5p634)yvu4XG}95gm7A@9gl(O{bngJNU)Er6(PQ zxpw6S!J2N7cWSEV3}rWjiA$Koxrv@0ar4v{GH=XIV;4vLG<8^IqH2uKu`MH$x3^ll z&C2Pq(miE!aDL*z2`g{J^zm?GE*+Gi{dd)d)yxcvv4EL9;+a>sZ57>viT(kxw+H|D zd&W5}hIx!yb(`PaEpr*!0G($9no8g8e|RZG6I!sVzbI+%m6hw}99X9x!7erGW#7l} z1ceK#N(*)mkl6RtkC|D#edj^l?s@TM&+&d^C5x`*{Cef=v4<%a53IkIeEmVa{7`uH z+=ch+PF$?-={@kUa?(KYqVwmx)cMmy<S<2mx~X<7ZP z^2edM^EJl*T1-ut!>H>+aXe#Y1im z%4l7#bh(&);8E@IB$UB$8G(m{M5seT-nRv4hOF$hC;oOiqIY`H9%bOx^wItG-;~t! z@GH#!-F10s$;Q>O2P#I+nln`&mOu97m)5P`1?kXB=J=({4&Iy8t5>a*d#0RAp1s-& z9_Lm|EcUM1GiLCMUyGjad)Vw}u8aOjFJV?5mq?r9R#nfe3YaIKv^(W-b@ZxRd|h@x z0hco-&+GIxJkxJRe&T~8<+oh-`){8$e6i0H6>hln@F>oATOzCy1tuo*xM_FAUZ&^2 zp#nq6hObtxS&)0yZEkavzk9dG0d7%!^-Z}OcOLGOsU@U7DXh7*HwvR(H{Ip0D~paP zySYZUvCR8f(e?Nt_nLAK$|{$$cFZO#>f%0o@^xP0saJxr^Cb@W?c&*|rWS5)x#w5J zxFnC5`}yX*W-woTaWF@sHB;rN)yzf=Rz1dcm~CLrFc?8fhYdmFF$&USCfuT6Jvmmy zf^dU^HB+SFYHT4`93GZRVAE5l>Cn`8RAyi)$GZnP9GM_cx9SR~0M!8lssht8mDOhn7Ws`F_cDtQz z7qG2_iNll0WE?J^!{@^Q0h1{f3UR;|au`j~#-YMUl)!BiZnZ!(C!)6|Q3@6d>_hM4 zGut$p5A+tYT?L>A$AQ>5JT{kOHgh^!kW^?gAZZWiPc29t7{?qfMp}~y6bntpEYz@$ z6bAHzy)B7IaHeBGIamT_22c`s<#lp7S*?lqU_nb@!p%0P6%e}Dl3{qho@F4ShRn+!HVJrx${;iMGaCt%7-zdNDK=xu?W_S zBzjmc;Oiwko>(A8MIETr7Lr0NC`MBOayAZljEE7D@(dU(5E-O^!ic~K;DBX9o?d`) z`65ir?LZMu;GimzgpN_sR0cpLL_|_9%Ee%=)F^_5LWu;{OJ!2nC=;MUsX!_cN_kEy z11g_nCCmsoPTY)`FpkY)a&FLq%Y!4-3KpN;=GD0pk$_M}U;ugmw-~H;@*`M>o3ZH> zLhH#B1NQyhyaoB^sp2~xv-Ec=E8c!D1(gxgFz$%#UPakIVG|q4Gb4Bt2iHqRl8oagn!|u{T%*64}iMM$tUUCC0CbRpQOMifxD`! zORi5+;FG{z)%Aaq%l+f)4rT%Wfb8I9rty9c`cbJ`PDIrf6$B>G+WQjEo{?~iOx=rF_ YFn!4USAP+s4^WoD)78&qol`;+04tsm>i_@% literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/tex_decimal_point.rgba16.png b/textures/segment2/custom/tex_decimal_point.rgba16.png new file mode 100644 index 0000000000000000000000000000000000000000..1be0f835f50639f1a7765df0aa7687a0b32e13d0 GIT binary patch literal 4782 zcmeHLX;c$g7A|#IWfw+V8q0_qnw5ks5ELOKQN!K}wyji>3S=OQNns)`CTyxja_YaD6Y*|y>8}(^DBu?+#RB}>bo5K6PsDnGort{`XugV zx1}{#m)_v9FLT=Akf2ucs%P&S%5(RB{BLjaK4qTuMXO3*uQ|1OFYEj61($grHRo4A zYuw#SdbaQKTNelEa&|i0-PL0j;s>|pB=~KNwV2bU`xs-|%y_sVt!4+kz~w*dANW5> z>WWF6f;cU(3rx)%buE_3OAJ53&#;b3ynE02a?<9_W!LLp&rXgk45(j}!Mb6jCtj~kW))_4 z*>$;H3N2(qL~eEd#xv#i_O%7_{pReFOW9PHnyjdxqkem4q?OAWY=k=72QZ1g_s3Vl z<(D?OkB*u}Z92vqZ;~U+W1Bq@W*VEu>0N7-kh}sUd01mQcsXRBb8e}GPO7-++otcXO8ZrncEs^@Zh=M2MyEp) z_6O93B34N**B0{0adVk%0pH&}b}CHpV`}4ECVG?k!-_*f+FAR>_(KPNINPDCyMOLb z>G-0=)bRR-U8xSl;|=CV9IiQ36p~KFJQI|hmp*teIix`IE$j1+=i=#6EerF1D#f~{ zur-}6i;5DAbMNuIxlV5DG6HAjKFlE1Hyp?l96=i=Ma?|z|H87dU7V)L-JAV5G@-F8 zKI_6y?K+Fit@cw%^3>6bBUfZ{@-npKi;UF7vo0C7#|XDr_^XxS6KhznbcF7zcHx_g z+Od1zXrIO1SRUF?UiZjVQ54$Q>G(HyQLW2zep>wfEq$$f$_uOCoV1+RslE6KTEEeA z{*)~1J8@&Er}3NKRp5>_1+S%4e&{Dv9=KD|KlSKAt5qd;nrmqP>Zq!^wAu2v<4CLz zZ8u=HXS}?%sM#hC>Ata~(bg>Mh21Y#$o0XGUTjmWmW~_$bDWPwU-Q&Yo90tiy_nVN zKB@h3zF?uz69^iWDE0OZ;Cp+2t|?GSnd^75dDZhLUs)M^oa6Fc7p${6vo*me(3X2r zXgfEfWI?{wjC~tS1rvAKkLOlhc>1(fc)#jO*iw_FUN*hZDohoG?X>IPXTPjQt9-OW z^P7|AEtDOIoNA(3oj8ad8@GzQZ>8;+B2#!9oJ4XV2m4F@THHN(+E4%%P z8M`OG4m!f~xPevUR?IxyavrDB$r>nzS%dUi-ZV2r>+?$vkUy|9%y6NS7CfPa2W@=87Wk~o` z-+bS#Db&}s?A|fk=Wz%JmQM%ilns{QoZIZGWCO+dj3jXTthm zr}k2#*d>o!mh~{!L&XjE?^!C9rrR=Rt-bl|an-GsK6ZV_Ta!I&RTm~J7x#kO%Q@S=4q9PC%*HLH2}lB^HySDB z#j4QYSicZaY?O#8#?A9I_t3HcfDFYDSSyQ`t65q$&Vb7TWBoJ{2OC7NC^jxs5CD5C zR47a(PzfYFM=M=T!Fig)9xAbf73AYP2mzkhxJV3BvWP^DMnllJ5)`TkBALl#5=j&y zg@OkXc=Z}NhG_9}^)x-i0EQ2$7OA94OsbH>dQ3#9h{4!699V}x`zKQh1Viw0^&ks? z526-P63GM-Q6?h}*HB}e)c|DBp+D46hk)-2Vi2lU#Hd6lXEiFvrVWP>i-z=-F{)@o zIAReIjYefaR1K_>zcR_?3j&5T^b|x$WlDnppiR}A3{cLb;p;eI9k zId+3EkP--3J_=Ec-aWn#8>hF=5-UVfG0QNd3&j)?>MFq_WC?<&Qcy7%Ayhma5xOBl zA(=rIxebHj%hebn7omD608Wqs9HFb&%@w7);i)Jh!c%Ev3Laq~3_Mj#MMNkQL4-8= zFbIE@6l5h5J=`ljlo&vXgb0~TAxrRdk{CcC3_2b`fO8CykV;~pbXU5BVSo~gSiTCC z3<29Il_3!*Q7MlwEa(Ymc?IyhdB&>NTo%?0!-;!v|1YgPD$C(gfoRI3{f-)~3_v6g0Mhe~BOp-^VM2aYGdDXp|F9f_yzx{V9Q4 z7U}x?VP{UKG9RsyR^T%Fwm%tr$ud1F*fGEY5+)dXJU9JEB+!QV96z7J1>y0(1LFK4 A*8l(j literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/tex_minus.rgba16.png b/textures/segment2/custom/tex_minus.rgba16.png new file mode 100644 index 0000000000000000000000000000000000000000..fa27ca151be293d2962f7eec70dead59904b7328 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`1)eUBAr*6y6C_xtH2+ulz|++~ zso^?5PS@0{)DTR2}v_{r`V8Pjthnexa2+B||^| z-+Y5d;ZoX!XaB!X;1y7CGM=!%ZJ`viaRak6qwi)0zM~Pzjg2fv7c*!xFdWo0t!&rT RJ_fX#!PC{xWt~$(699@JHzfc7 literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/segment2.02600.rgba16.png b/textures/segment2/predone/segment2.02600.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.02600.rgba16.png rename to textures/segment2/predone/segment2.02600.rgba16.png diff --git a/textures/segment2/custom/segment2.03400.rgba16.png b/textures/segment2/predone/segment2.03400.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.03400.rgba16.png rename to textures/segment2/predone/segment2.03400.rgba16.png diff --git a/textures/segment2/custom/segment2.03E00.rgba16.png b/textures/segment2/predone/segment2.03E00.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.03E00.rgba16.png rename to textures/segment2/predone/segment2.03E00.rgba16.png diff --git a/textures/segment2/custom/segment2.04200.rgba16.png b/textures/segment2/predone/segment2.04200.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.04200.rgba16.png rename to textures/segment2/predone/segment2.04200.rgba16.png diff --git a/textures/segment2/custom/segment2.04600.rgba16.png b/textures/segment2/predone/segment2.04600.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.04600.rgba16.png rename to textures/segment2/predone/segment2.04600.rgba16.png diff --git a/textures/segment2/custom/segment2.04C00.rgba16.png b/textures/segment2/predone/segment2.04C00.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.04C00.rgba16.png rename to textures/segment2/predone/segment2.04C00.rgba16.png diff --git a/textures/segment2/custom/segment2.04E00.rgba16.png b/textures/segment2/predone/segment2.04E00.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.04E00.rgba16.png rename to textures/segment2/predone/segment2.04E00.rgba16.png diff --git a/textures/segment2/custom/segment2.05000.rgba16.png b/textures/segment2/predone/segment2.05000.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.05000.rgba16.png rename to textures/segment2/predone/segment2.05000.rgba16.png diff --git a/textures/segment2/custom/segment2.05200.rgba16.png b/textures/segment2/predone/segment2.05200.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.05200.rgba16.png rename to textures/segment2/predone/segment2.05200.rgba16.png diff --git a/textures/segment2/custom/segment2.05400.rgba16.png b/textures/segment2/predone/segment2.05400.rgba16.png similarity index 100% rename from textures/segment2/custom/segment2.05400.rgba16.png rename to textures/segment2/predone/segment2.05400.rgba16.png diff --git a/textures/segment2/predone/segment2.05E00.rgba16.png b/textures/segment2/predone/segment2.05E00.rgba16.png new file mode 100644 index 0000000000000000000000000000000000000000..a7428d2c28735b9971ac715b5dacafb589e46b5b GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`8$4YcLn`8uQx5R{TkM$_+U+Z_ zX5)?>5=-P&_#YX6`}XY+kITj8yaV+M+;*rf;7mAs!sLR&jDrd6Mv9h`7o;tSa$9lw z!M$clhbd_@yeIHF7BZe-%Q<&U@f-uc$`=OZYXSiW4#gbsXgYg>@iYTJv(Q|AyKbS-!jm?-P7F;~ppzFUN`&cT& h9dDi)49ee`7}OF9Ds4T#?*_V^!PC{xWt~$(69D?`R;~a5 literal 0 HcmV?d00001 diff --git a/textures/segment2/predone/segment2.06000.rgba16.png b/textures/segment2/predone/segment2.06000.rgba16.png new file mode 100644 index 0000000000000000000000000000000000000000..fcc87afc29a49ecb632aaa392816e754447501e1 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Gd*1#Ln`8uQyf_TOLj09)cSb5 zIymb;vuDhYd$v2W)``L668$0Iw z+Mt%YC#^AwO;hvm)k#lSGq_wgcBn9K*x4Z1zx!iq?hZQ!%dG`VKYY493+PA&Pgg&e IbxsLQ0Hk+JuK)l5 literal 0 HcmV?d00001 diff --git a/textures/segment2/predone/segment2.umlaut.rgba16.png b/textures/segment2/predone/segment2.umlaut.rgba16.png new file mode 100644 index 0000000000000000000000000000000000000000..15240ab71669efb5ae5c044813f10fb67f790de4 GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`$(}BbAr*1S3$%Xlvs5?EczFB& ze;&{8{|@sUSM5u*j3^fHFcvWW(=OfMEtA5)y-D-j{YD#Cg=Y??($g(GM1?n9((zlt zc-?VP@WY@TM+^_^b3Xf``9Dylu+zAw>7syyjv@oYyETr1KRti;0j*>3boFyt=akR{ E01hoS<^TWy literal 0 HcmV?d00001 diff --git a/tools/Makefile b/tools/Makefile index 0ed88c68d..c290d0243 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -7,7 +7,7 @@ CC ?= gcc CXX ?= g++ CFLAGS := -I. -O2 -s LDFLAGS := -lm -ALL_PROGRAMS := armips n64graphics n64graphics_ci mio0 n64cksum textconv patch_elf_32bit aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv +ALL_PROGRAMS := armips n64graphics n64graphics_ci mio0 n64cksum patch_elf_32bit aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv LIBAUDIOFILE := audiofile/libaudiofile.a # Only build armips from tools if it is not found on the system @@ -30,8 +30,6 @@ mio0_CFLAGS := -DMIO0_STANDALONE n64cksum_SOURCES := n64cksum.c utils.c n64cksum_CFLAGS := -DN64CKSUM_STANDALONE -textconv_SOURCES := textconv.c utf8.c hashtable.c - patch_elf_32bit_SOURCES := patch_elf_32bit.c aifc_decode_SOURCES := aifc_decode.c From 798aee3cdf6a51ff9721cb8721803a55e55de828 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sat, 24 Dec 2022 17:42:52 -0500 Subject: [PATCH 02/14] fixed zelda level select on ascii --- defines.mk | 2 +- include/qol_defines.h | 2 +- src/extras/redone/title_screen.inc.c | 35 ++++++++++++++-------------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/defines.mk b/defines.mk index 8fd5ed94c..2fb9fc399 100644 --- a/defines.mk +++ b/defines.mk @@ -122,7 +122,7 @@ endif # !TARGET_N64 ifeq ($(DEBUG),1) CUSTOM_C_DEFINES += -DDEBUG COMPILER_OPT := debug - EXT_DEBUG_MENU := 1 + #EXT_DEBUG_MENU := 1 endif # Check for Debug Menu option diff --git a/include/qol_defines.h b/include/qol_defines.h index 12262f690..465b105f4 100644 --- a/include/qol_defines.h +++ b/include/qol_defines.h @@ -22,7 +22,7 @@ // --| Quality of life redone files /// Adds Zelda level select used on OOT, MM and Animal Forest /// Credits: (AloXado320) -//#define ZELDA_STYLE_LEVEL_SELECT (0 || QOL_REDONE) +#define ZELDA_STYLE_LEVEL_SELECT (0 || QOL_REDONE) /// Adds improved platform displacement with intertia #define PLATFORM_DISPLACEMENT_2 (0 || QOL_REDONE) /// Uses optimized shadows which are faster than vanilla diff --git a/src/extras/redone/title_screen.inc.c b/src/extras/redone/title_screen.inc.c index d12232404..15adc4787 100644 --- a/src/extras/redone/title_screen.inc.c +++ b/src/extras/redone/title_screen.inc.c @@ -9,6 +9,7 @@ #include "game/segment2.h" #include "game/ingame_menu.h" #include "extras/draw_util.h" +#include #define MAX_PAGE_STRINGS 12 #define PAGE_DOWN_STOPS_MAX (LEVEL_MAX / MAX_PAGE_STRINGS) @@ -40,15 +41,13 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { char *levelName; s32 courseNum; u8 *courseName; - s32 xPos; char *chrTemp; u8 levelNumStr[4]; u8 courseNumStr[4]; gDPSetEnvColor(gDisplayListHead++, 255, 155, 150, 255); chrTemp = "SUPER MARIO LEVEL SELECT"; - xPos = get_str_x_pos_from_center_custom_ascii(LUT_TYPE_STR_ASCII, SCREEN_WIDTH / 2, chrTemp, FALSE, 0); - print_generic_string(xPos, 210, chrTemp); + print_generic_string_aligned(SCREEN_CENTER_X, 210, chrTemp, TEXT_ALIGN_CENTER); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); if (this->toggleControlsView) { @@ -98,7 +97,7 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { chrTemp = "COURSE NAME"; print_generic_string(72, 180 - i * 11, courseNumStr); if (courseName != NULL && courseNum >= COURSE_MIN && courseNum <= COURSE_MAX) { - if (check_number_string_in_course_names(courseName)) { + if (check_number_string_in_course_name(courseName)) { print_generic_string(100, 180 - i * 11, &courseName[3]); } else { print_generic_string(100, 180 - i * 11, courseName); @@ -111,14 +110,15 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { } void print_debug_level_select_settings(struct ZDebugLevelSelect *this) { - u8 strSaveNum[4]; - u8 strActNum[4]; + char str[20]; + char strSaveNum[8]; + char strActNum[8]; char *chrTemp; s16 saveNum = gCurrSaveFileNum; s16 actNum = gDialogCourseActNum = gCurrActNum; - int_to_str(saveNum, strSaveNum); - int_to_str(actNum, strActNum); + format_int_to_string(strSaveNum, saveNum); + format_int_to_string(strActNum, actNum); u8 *actName; void **actNameTbl; @@ -144,22 +144,23 @@ void print_debug_level_select_settings(struct ZDebugLevelSelect *this) { gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - chrTemp = "Save File: "; - print_generic_string(20, 42, chrTemp); - print_generic_string(20 + get_string_width_ascii(chrTemp), 42, strSaveNum); + chrTemp = "Save File: %s"; + sprintf(str, chrTemp, strSaveNum); + print_generic_string(20, 42, str); + + chrTemp = "Level Act: %s"; + sprintf(str, chrTemp, strActNum); + print_generic_string(20, 28, str); - chrTemp = "Level Act: "; - print_generic_string(20, 28, chrTemp); - print_generic_string(20 + get_string_width_ascii(chrTemp), 28, strActNum); if (actName != NULL && courseNum >= COURSE_MIN && courseNum <= COURSE_STAGES_MAX) { - print_generic_string(20 + 20 + get_string_width_ascii(chrTemp), 28, actName); + print_generic_string(100, 28, actName); } chrTemp = "(C Down) - Show-Hide Controls"; print_generic_string(20, 14, chrTemp); } -const char lvlSelectDbgCtrlStr[][40] = { +char lvlSelectDbgCtrlStr[][40] = { "(D Pad) - Select Level", "(R) - Change List Page", "(Z) - Change Save File", @@ -169,7 +170,7 @@ const char lvlSelectDbgCtrlStr[][40] = { "(A), (Start) - Load Level", }; -const char lvlSelectDbgCtrlViewStr[] = { "(C Down) - Show-Hide Controls" }; +char lvlSelectDbgCtrlViewStr[] = { "(C Down) - Show-Hide Controls" }; void print_debug_level_select_controls(void) { s32 i; From 3beb778fd4a52b4727140228339d0fc71db5eeea Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sat, 24 Dec 2022 18:25:29 -0500 Subject: [PATCH 03/14] fixed hud --- src/game/hud.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/game/hud.c b/src/game/hud.c index ba5bbdce3..4dba6eedd 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -300,8 +300,8 @@ void render_hud_power_meter(void) { * Renders the amount of lives Mario has. */ void render_hud_mario_lives(void) { - print_text(set_hud_auto_x_pos(HUD_LIVES_MARIO_X), HUD_LIVES_MARIO_Y, ","); // 'Mario Head' glyph - print_text(set_hud_auto_x_pos(HUD_LIVES_CROSS_X), HUD_LIVES_CROSS_Y, "*"); // 'X' glyph + print_text(set_hud_auto_x_pos(HUD_LIVES_MARIO_X), HUD_LIVES_MARIO_Y, "☺"); // 'Mario Head' glyph + print_text(set_hud_auto_x_pos(HUD_LIVES_CROSS_X), HUD_LIVES_CROSS_Y, "×"); // 'X' glyph print_text_fmt_int(set_hud_auto_x_pos(HUD_LIVES_NUM_X), HUD_LIVES_NUM_Y, "%d", gHudDisplay.lives); } @@ -309,8 +309,8 @@ void render_hud_mario_lives(void) { * Renders the amount of coins collected. */ void render_hud_coins(void) { - print_text(set_hud_auto_x_pos(HUD_COINS_X), HUD_COINS_Y, "+"); // 'Coin' glyph - print_text(set_hud_auto_x_pos(HUD_COINS_CROSS_X), HUD_COINS_Y, "*"); // 'X' glyph + print_text(set_hud_auto_x_pos(HUD_COINS_X), HUD_COINS_Y, "✪"); // 'Coin' glyph + print_text(set_hud_auto_x_pos(HUD_COINS_CROSS_X), HUD_COINS_Y, "×"); // 'X' glyph print_text_fmt_int(set_hud_auto_x_pos(HUD_COINS_NUM_X), HUD_COINS_Y, "%d", gHudDisplay.coins); } @@ -329,9 +329,9 @@ void render_hud_stars(void) { showX = 1; } - print_text(set_hud_auto_x_pos(HUD_STARS_X), HUD_STARS_Y, "-"); // 'Star' glyph + print_text(set_hud_auto_x_pos(HUD_STARS_X), HUD_STARS_Y, "★"); // 'Star' glyph if (showX == 1) { - print_text(set_hud_auto_x_pos(HUD_STARS_CROSS_X), HUD_STARS_CROSS_Y, "*"); // 'X' glyph + print_text(set_hud_auto_x_pos(HUD_STARS_CROSS_X), HUD_STARS_CROSS_Y, "×"); // 'X' glyph } print_text_fmt_int((showX * 14) + set_hud_auto_x_pos(HUD_STARS_NUM_X), HUD_STARS_NUM_Y, "%d", gHudDisplay.stars); } @@ -344,19 +344,17 @@ void render_hud_keys(void) { s16 i; for (i = 0; i < gHudDisplay.keys; i++) { - print_text((i * 16) + 220, 142, "/"); // unused glyph - beta key + print_text((i * 16) + 220, 142, "|"); // unused glyph - beta key } } /** * Renders the timer when Mario start sliding in PSS. */ -/** void render_hud_timer(void) { - u8 *(*hudLUT)[58] = segmented_to_virtual(&main_hud_lut); u16 timerValFrames = gHudDisplay.timer; // 30 frames * 60 seconds (1 minute) = 1800 - u16 timerMins = timerValFrames / 1800; + u16 timerMins = timerValFrames / (30 * 60); u16 timerSecs = (timerValFrames - (timerMins * 1800)) / 30; u16 timerFracSecs = (timerValFrames - (timerMins * 1800) - (timerSecs * 30)) / 3; char *str; @@ -379,15 +377,12 @@ void render_hud_timer(void) { #endif print_text_fmt_int(set_hud_auto_x_pos(HUD_TIME_MIN_X), HUD_TIME_Y, "%0d", timerMins); + print_text(set_hud_auto_x_pos(HUD_TIME_MIN_A_X), HUD_TIME_Y, "'"); print_text_fmt_int(set_hud_auto_x_pos(HUD_TIME_SEC_X), HUD_TIME_Y, "%02d", timerSecs); + print_text(set_hud_auto_x_pos(HUD_TIME_SEC_AA_X), HUD_TIME_Y, "\""); print_text_fmt_int(set_hud_auto_x_pos(HUD_TIME_FSEC_X), HUD_TIME_Y, "%d", timerFracSecs); - - gSPDisplayList(gDisplayListHead++, dl_hud_img_begin); - render_hud_tex_lut(set_hud_auto_x_pos(HUD_TIME_MIN_A_X), HUD_TIME_A_Y, (*hudLUT)[GLYPH_APOSTROPHE]); - render_hud_tex_lut(set_hud_auto_x_pos(HUD_TIME_SEC_AA_X), HUD_TIME_A_Y, (*hudLUT)[GLYPH_DOUBLE_QUOTE]); - gSPDisplayList(gDisplayListHead++, dl_hud_img_end); } - */ + /** * Sets HUD status camera value depending of the actions * defined in update_camera_status. @@ -508,7 +503,7 @@ void render_hud(void) { } #if SHOW_TIMER if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER) { - //render_hud_timer(); + render_hud_timer(); } #endif } From 3636b7a587e2d27375bf8fa8914168b1d816e97f Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sun, 25 Dec 2022 01:52:02 -0500 Subject: [PATCH 04/14] fixed ext options menu --- defines.mk | 2 +- src/extras/draw_util.c | 14 ++-- src/extras/draw_util.h | 1 + src/extras/options_menu.c | 168 +++++++++++++++++--------------------- src/extras/options_menu.h | 6 +- src/game/ingame_menu.c | 15 ++++ 6 files changed, 102 insertions(+), 104 deletions(-) diff --git a/defines.mk b/defines.mk index 2fb9fc399..33eaf58f9 100644 --- a/defines.mk +++ b/defines.mk @@ -5,7 +5,7 @@ # Build debug version DEBUG ?= 0 # Enable extended options menu by default -EXT_OPTIONS_MENU ?= 0 +EXT_OPTIONS_MENU ?= 1 # Enable debug options menu (Enabled if DEBUG=1) EXT_DEBUG_MENU ?= 0 # Enable better camera (Puppycam 2) diff --git a/src/extras/draw_util.c b/src/extras/draw_util.c index d48d1e8d9..6ea0b3ddf 100644 --- a/src/extras/draw_util.c +++ b/src/extras/draw_util.c @@ -149,17 +149,21 @@ static void allocate_quad_vertices(Gfx *dlHead, u16 w, u16 h) { ******************/ /** - * An detailed version of print_generic_string that let's you + * A detailed version of print_generic_string that let's you * color the font and add shadow to it. */ -void print_generic_string_detail(s16 x, s16 y, u8 *str, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad) { +void print_generic_string_detail_aligned(s16 x, s16 y, u8 *str, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad, u32 alignment) { if (hasShadow) { - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); - print_generic_string(x + shadowPad, y - shadowPad, str); + gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, a); + print_generic_string_aligned(x + shadowPad, y - shadowPad, str, alignment); } gDPSetEnvColor(gDisplayListHead++, r, g, b, a); - print_generic_string(x, y, str); + print_generic_string_aligned(x, y, str, alignment); +} + +void print_generic_string_detail(s16 x, s16 y, u8 *str, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad) { + print_generic_string_detail_aligned(x, y, str, r, g, b, a, hasShadow, shadowPad, TEXT_ALIGN_LEFT); } /** diff --git a/src/extras/draw_util.h b/src/extras/draw_util.h index 677daf7f6..9a452e52a 100644 --- a/src/extras/draw_util.h +++ b/src/extras/draw_util.h @@ -8,6 +8,7 @@ extern Gfx dl_texture_rect_ex_end[]; extern Gfx dl_tri_quad_ex_start[]; extern Gfx dl_tri_quad_ex_end[]; +void print_generic_string_detail_aligned(s16 x, s16 y, u8 *str, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad, u32 alignment); void print_generic_string_detail(s16 x, s16 y, u8 *text, u8 r, u8 g, u8 b, u8 a, s8 hasShadow, s8 shadowPad); void print_solid_color_quad(s16 x1, s16 y1, s16 x2, s16 y2, u8 r, u8 g, u8 b, u8 a); diff --git a/src/extras/options_menu.c b/src/extras/options_menu.c index cca0a244c..b046e13ce 100644 --- a/src/extras/options_menu.c +++ b/src/extras/options_menu.c @@ -1,7 +1,6 @@ #ifdef EXT_OPTIONS_MENU #include "sm64.h" -#include "text_strings.h" #include "gfx_dimensions.h" #include "engine/math_util.h" #include "audio/external.h" @@ -19,6 +18,8 @@ #include "pc/configfile.h" +#include // non-n64 + #ifndef TARGET_N64 #include "pc/pc_main.h" #include "pc/controller/controller_api.h" @@ -50,95 +51,94 @@ static u8 optmenu_bind_idx = 0; static s32 l_counter = 0; // How to add stuff: -// strings: add them to include/text_strings.h.in -// and to optMainStr[] / opts*Str[] +// strings: add them to optMainStr[] / opts*Str[] // options: add them to the relevant options list // menus: add a new submenu definition and a new // option to the optsMain list -static const u8 toggleStr[][16] = { - { TEXT_OPT_DISABLED }, - { TEXT_OPT_ENABLED }, +static char toggleStr[][16] = { + "Disabled", + "Enabled", }; -static const u8 optSmallStr[][32] = { - { TEXT_OPT_BUTTON1 }, - { TEXT_OPT_BUTTON2 }, - { TEXT_OPT_L_HIGHLIGHT }, - { TEXT_OPT_R_HIGHLIGHT }, +static char optSmallStr[][32] = { + "Ⓡ Options", + "Ⓡ Return", + "▶", + "◀", }; -static const u8 optMainStr[][32] = { - { TEXT_OPT_OPTIONS }, - { TEXT_OPT_CAMERA }, - { TEXT_OPT_CONTROLS }, - { TEXT_OPT_VIDEO }, - { TEXT_OPT_AUDIO }, - { TEXT_OPT_SETTINGS }, - { TEXT_EXIT_GAME }, +static char optMainStr[][32] = { + "OPTIONS", + "CAMERA", + "CONTROLS", + "DISPLAY", + "SOUND", + "SETTINGS", + "EXIT GAME", }; -const u8 optsCameraStr[][32] = { - { TEXT_OPT_VANILLA_CAM }, - { TEXT_OPT_LAKITU_PARALLEL }, - { TEXT_OPT_SR_MARIO_CAM }, - { TEXT_OPT_CAM_C_UP_SOUNDS }, - { TEXT_OPT_CAM_PARALLEL_COL }, +char optsCameraStr[][32] = { + "VANILLA CAMERA", + "Parallel Lakitu Cam", + "Star Road Mario Cam", + "Camera Sound Effects", + "Parallel Cam Collision", }; #ifndef TARGET_N64 -static const u8 optsVideoStr[][32] = { - { TEXT_OPT_FSCREEN }, - { TEXT_OPT_TEXFILTER }, - { TEXT_OPT_NEAREST }, - { TEXT_OPT_LINEAR }, - { TEXT_OPT_RESETWND }, - { TEXT_OPT_VSYNC }, - { TEXT_OPT_APPLY }, +static char optsVideoStr[][32] = { + "Fullscreen", + "Texture Filtering", + "Nearest", + "Linear", + "Reset Window", + "Vertical Sync", + "Apply", }; #endif -static const u8 optsAudioStr[][32] = { - { TEXT_OPT_MVOLUME }, - { TEXT_OPT_MUSVOLUME }, - { TEXT_OPT_SFXVOLUME }, - { TEXT_OPT_ENVVOLUME }, +static char optsAudioStr[][32] = { + "Master Volume", + "Music Volume", + "Sfx Volume", + "Env Volume", }; -static const u8 optsSettingsStr[][32] = { - { TEXT_OPT_HUD }, - { TEXT_OPT_MOUSE }, +static char optsSettingsStr[][32] = { + "HUD", + "Mouse", }; #if !defined(TARGET_N64) && !defined(TARGET_PORT_CONSOLE) -static const u8 optBindStr[][32] = { - { TEXT_OPT_UNBOUND }, - { TEXT_OPT_PRESSKEY }, - { TEXT_BIND_A }, - { TEXT_BIND_B }, - { TEXT_BIND_START }, - { TEXT_BIND_L }, - { TEXT_BIND_R }, - { TEXT_BIND_Z }, - { TEXT_BIND_C_UP }, - { TEXT_BIND_C_DOWN }, - { TEXT_BIND_C_LEFT }, - { TEXT_BIND_C_RIGHT }, - { TEXT_BIND_D_UP }, - { TEXT_BIND_D_DOWN }, - { TEXT_BIND_D_LEFT }, - { TEXT_BIND_D_RIGHT }, - { TEXT_BIND_UP }, - { TEXT_BIND_DOWN }, - { TEXT_BIND_LEFT }, - { TEXT_BIND_RIGHT }, - { TEXT_OPT_DEADZONE }, - { TEXT_OPT_RUMBLE }, +static char optBindStr[][32] = { + "NONE", + "・・・", + "A Button", + "B Button", + "Start Button", + "L Trigger", + "R Trigger", + "Z Trigger", + "C-Up", + "C-Down", + "C-Left", + "C-Right", + "D-Up", + "D-Down", + "D-Left", + "D-Right", + "Stick Up", + "Stick Down", + "Stick Left", + "Stick Right", + "Stick Deadzone", + "Rumble Strength", }; #endif #ifndef TARGET_N64 -static const u8 *filterChoices[] = { +static char *filterChoices[] = { optsVideoStr[2], optsVideoStr[3], }; @@ -315,26 +315,15 @@ static inline s32 wrap_add(s32 a, const s32 b, const s32 min, const s32 max) { return a; } -static void uint_to_hex(u32 num, u8 *dst) { - u8 places = 4; - while (places--) { - const u32 digit = num & 0xF; - dst[places] = digit; - num >>= 4; - } - dst[4] = DIALOG_CHAR_TERMINATOR; -} - -static void optmenu_draw_text(s16 x, s16 y, const u8 str[], u8 col) { - u8 textX = get_str_x_pos_from_center(x, (u8 *) str, 10.0f); +static void optmenu_draw_text(s16 x, s16 y, char *str, u8 col) { gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); - print_generic_string(textX + 1, y - 1, str); + print_generic_string_aligned(x + 1, y - 1, str, TEXT_ALIGN_CENTER); if (col == 0) { gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); } else { gDPSetEnvColor(gDisplayListHead++, 255, 32, 32, 255); } - print_generic_string(textX, y, str); + print_generic_string_aligned(x, y, str, TEXT_ALIGN_CENTER); } // TODO: Fix the hardcoded values @@ -388,7 +377,7 @@ static void optmenu_draw_opt(const struct Option *opt, s16 x, s16 y, u8 sel, s16 else optmenu_draw_text(x, y-13, optBindStr[0], white); } else { - uint_to_hex(opt->uval[i], buf); + sprintf(buf, "%04x", opt->uval[i]); optmenu_draw_text(x, y-13, buf, white); } } @@ -442,15 +431,6 @@ static void optmenu_opt_change(struct Option *opt, s32 val) { } } -#define STRIDE (HUD_LUT_STRIDE_GLOBAL / 2) // stride is 12 (14 in JP) -static inline s16 get_hudstr_centered_x(const s16 sx, const u8 *str) { - const u8 *chr = str; - s16 len = 0; - while (*chr != GLOBAL_CHAR_TERMINATOR) ++chr, ++len; - return sx - len * STRIDE; -} -#undef STRIDE - //Options menu void optmenu_draw(void) { u8 i; @@ -466,10 +446,9 @@ void optmenu_draw(void) { print_solid_color_quad(48, 84, 272, 218, 0x0, 0x0, 0x0, 0x50); - const s16 labelX = get_hudstr_centered_x(SCREEN_WIDTH / 2, currentMenu->label); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); - print_hud_lut_string(HUD_LUT_GLOBAL, labelX, 40, currentMenu->label); + print_hud_lut_string_aligned(SCREEN_CENTER_X, 40, currentMenu->label, TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); if (currentMenu->numOpts > 4) @@ -499,13 +478,12 @@ void optmenu_draw(void) { //This has been separated for interesting reasons. Don't question it. void optmenu_draw_prompt(void) { - u8 *str = (u8 *) optSmallStr[optmenu_open]; - s16 strW = get_string_width(str); + char *str = (char *) optSmallStr[optmenu_open]; gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - print_generic_string_detail(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(57 + strW), 212, str, 255, 255, 255, 255, TRUE, 1); - + print_generic_string_detail_aligned(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(57), 212, str, 255, 255, 255, gDialogTextAlpha, TRUE, 1, TEXT_ALIGN_CENTER); + gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } diff --git a/src/extras/options_menu.h b/src/extras/options_menu.h index c94c9805a..b81f47ce7 100644 --- a/src/extras/options_menu.h +++ b/src/extras/options_menu.h @@ -41,14 +41,14 @@ enum OptType { struct Option { enum OptType type; - const u8 *label; + char *label; union { u32 *uval; bool *bval; }; union { struct { - const u8 **choices; + char **choices; u32 numChoices; }; struct { @@ -63,7 +63,7 @@ struct Option { struct SubMenu { struct SubMenu *prev; // this is set at runtime to avoid needless complication - const u8 *label; + char *label; struct Option *opts; s32 numOpts; s32 select; diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 8b36db6ff..196de3b49 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -25,6 +25,10 @@ #include "main.h" // n64 #include // non-n64 +#ifdef EXT_OPTIONS_MENU +#include "extras/options_menu.h" +#endif + u16 gDialogColorFadeTimer; s8 gLastDialogLineNum; DialogVariable gDialogVariable; @@ -1864,6 +1868,9 @@ s8 gHudFlash = HUD_FLASH_NONE; s32 render_pause_courses_and_castle(void) { s16 index; +#ifdef EXT_OPTIONS_MENU + if (optmenu_open == 0) { +#endif switch (gDialogBoxState) { case DIALOG_STATE_OPENING: gDialogLineNum = MENU_OPT_DEFAULT; @@ -1932,6 +1939,14 @@ s32 render_pause_courses_and_castle(void) { if (gDialogTextAlpha < 250) { gDialogTextAlpha += 25; } +#ifdef EXT_OPTIONS_MENU + } else { + shade_screen(); + optmenu_draw(); + } + optmenu_check_buttons(); + optmenu_draw_prompt(); +#endif return MENU_OPT_NONE; } From f02e007e0849f88f242548e3f57613463a758dae Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sun, 25 Dec 2022 02:54:01 -0500 Subject: [PATCH 05/14] fixed bettercamera --- defines.mk | 2 +- src/extras/bettercamera.c | 48 +++++++++++++++++++-------------------- src/extras/bettercamera.h | 2 +- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/defines.mk b/defines.mk index 33eaf58f9..5045db36b 100644 --- a/defines.mk +++ b/defines.mk @@ -9,7 +9,7 @@ EXT_OPTIONS_MENU ?= 1 # Enable debug options menu (Enabled if DEBUG=1) EXT_DEBUG_MENU ?= 0 # Enable better camera (Puppycam 2) -BETTERCAMERA ?= 0 +BETTERCAMERA ?= 1 # Enable cheats CHEATS_ACTIONS ?= 0 # Enable rumble functions (Originally in Shindou) diff --git a/src/extras/bettercamera.c b/src/extras/bettercamera.c index a060c539d..4aa6dc438 100644 --- a/src/extras/bettercamera.c +++ b/src/extras/bettercamera.c @@ -18,7 +18,6 @@ #include "game/print.h" #include "engine/surface_collision.h" #include "engine/surface_load.h" -#include "include/text_strings.h" #include "game/segment2.h" #include "game/ingame_menu.h" #include "game/memory.h" @@ -86,40 +85,40 @@ static inline float softClamp(float x, float a, float b) { /// CONFIG -const u8 optsPuppyCamStr[][32] = { - { TEXT_OPT_PUPPYCAM }, - { TEXT_OPT_PUPPYON }, - { TEXT_OPT_ANALOGUE }, - { TEXT_OPT_CAMMOUSE }, - { TEXT_OPT_INVERTX }, - { TEXT_OPT_INVERTY }, - { TEXT_OPT_CAMX }, - { TEXT_OPT_CAMY }, - { TEXT_OPT_CAMC }, - { TEXT_OPT_CAMSCHEME }, - { TEXT_OPT_OPA_TYPE }, - { TEXT_OPT_DBG_CAM }, +char optsPuppyCamStr[][32] = { + "PUPPY CAMERA", + "PuppyCam 2", + "Analogue Camera", + "Camera Mouse Control", + "Invert X Axis", + "Invert Y Axis", + "Camera X Sensitivity", + "Camera Y Sensitivity", + "Camera Center Speed", + "Control Scheme", + "Opacity Type", + "Debug Camera", }; -static const u8 optsPuppyCamSchemeStr[][64] = { - { TEXT_OPT_CAM_SCH1 }, - { TEXT_OPT_CAM_SCH2 }, - { TEXT_OPT_CAM_SCH3 }, +static char optsPuppyCamSchemeStr[][64] = { + "Double Tap", + "Single Press", + "Classic", }; -static const u8 *puppycamChoicesScheme[] = { +static char *puppycamChoicesScheme[] = { optsPuppyCamSchemeStr[0], optsPuppyCamSchemeStr[1], optsPuppyCamSchemeStr[2], }; -static const u8 optsPuppyCamOpacityStr[][64] = { - { TEXT_OPT_OPA_T1 }, - { TEXT_OPT_OPA_T2 }, - { TEXT_OPT_OPA_T3 }, +static char optsPuppyCamOpacityStr[][64] = { + "None", + "Fade In-Out", + "Pop In-Out", }; -static const u8 *puppycamChoicesOpacity[] = { +static char *puppycamChoicesOpacity[] = { optsPuppyCamOpacityStr[0], optsPuppyCamOpacityStr[1], optsPuppyCamOpacityStr[2], @@ -142,7 +141,6 @@ static struct Option optsPuppyCam[] = { struct SubMenu menuPuppyCam = DEF_SUBMENU( optsPuppyCamStr[0], optsPuppyCam ); - void puppycam_default_config(void) { gPuppyCam.enabled = configPuppyCam.enable; gPuppyCam.options.analogue = configPuppyCam.analog; diff --git a/src/extras/bettercamera.h b/src/extras/bettercamera.h index 3af2c7a7e..48fc817e8 100644 --- a/src/extras/bettercamera.h +++ b/src/extras/bettercamera.h @@ -55,7 +55,7 @@ enum PuppyCamOpacityTypes #include "include/command_macros_base.h" #include "options_menu.h" -extern const u8 optsPuppyCamStr[][32]; +extern char optsPuppyCamStr[][32]; extern struct SubMenu menuPuppyCam; From c2e8211afe2b6c3f6a749ac6c8226e9a2aecf582 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sun, 25 Dec 2022 03:07:11 -0500 Subject: [PATCH 06/14] fix cheat actions menu --- defines.mk | 2 +- src/extras/cheats.c | 77 ++++++++++++++++++++++----------------------- src/extras/cheats.h | 2 +- 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/defines.mk b/defines.mk index 5045db36b..dc07e5576 100644 --- a/defines.mk +++ b/defines.mk @@ -11,7 +11,7 @@ EXT_DEBUG_MENU ?= 0 # Enable better camera (Puppycam 2) BETTERCAMERA ?= 1 # Enable cheats -CHEATS_ACTIONS ?= 0 +CHEATS_ACTIONS ?= 1 # Enable rumble functions (Originally in Shindou) RUMBLE_FEEDBACK ?= 1 # Disable no drawing distance by default diff --git a/src/extras/cheats.c b/src/extras/cheats.c index ff16df445..75fb36097 100644 --- a/src/extras/cheats.c +++ b/src/extras/cheats.c @@ -1,7 +1,6 @@ #ifdef CHEATS_ACTIONS #include "sm64.h" -#include "text_strings.h" #include "gfx_dimensions.h" #include "audio/external.h" @@ -23,63 +22,63 @@ struct CheatList Cheats; -const u8 optCheatMenuStr[][32] = { - { TEXT_OPT_CHEATS }, - { TEXT_OPT_CHEATS_WALKON }, - { TEXT_OPT_CHEATS_BLJANY }, +char optCheatMenuStr[][32] = { + "CHEATS", + "WALK ON SURFACE", + "BLJ ANYWHERE", }; -static const u8 optsCheatsStr[][64] = { - { TEXT_OPT_CHEAT0 }, - { TEXT_OPT_CHEAT1 }, - { TEXT_OPT_CHEAT2 }, - { TEXT_OPT_CHEAT3 }, - { TEXT_OPT_CHEAT4 }, - { TEXT_OPT_CHEAT5 }, - { TEXT_OPT_CHEAT6 }, - { TEXT_OPT_CHEAT7 }, - { TEXT_OPT_CHEAT8 }, - { TEXT_OPT_CHEAT9 }, - { TEXT_OPT_CHEAT10 }, - { TEXT_OPT_CHEAT11 }, +static char optsCheatsStr[][64] = { + "Enable cheats", + "Moon-jump (Press L)", + "Infinite health", + "Infinite lives", + "Invincible player", + "Super speed", + "Super responsive controls", + "Exit course at any time", + "No fall damage", + "Player size", + "BLJ anywhere", + "Walk on surface", }; -static const u8 optsMarioSizeCheatStr[][64] = { - { TEXT_CHEAT_MSIZE0 }, - { TEXT_CHEAT_MSIZE1 }, - { TEXT_CHEAT_MSIZE2 }, +static char optsMarioSizeCheatStr[][64] = { + "Normal", + "Tiny", + "Huge", }; -static const u8 *cheatChoicesMarioSize[] = { +static char *cheatChoicesMarioSize[] = { optsMarioSizeCheatStr[0], optsMarioSizeCheatStr[1], optsMarioSizeCheatStr[2], }; -static const u8 optsWalkOnCheatStr[][64] = { - { TEXT_CHEAT_WALKON0 }, - { TEXT_CHEAT_WALKON1 }, - { TEXT_CHEAT_WALKON2 }, - { TEXT_CHEAT_WALKON3 }, - { TEXT_CHEAT_WALKON4 }, - { TEXT_CHEAT_WALKON5 }, +static char optsWalkOnCheatStr[][64] = { + "Walk on lava", + "Walk on quicksand", + "Walk on water", + "Walk on gas", + "Walk on slope", + "Walk on death barrier", }; -static const u8 optsBljOptAnyCheatStr[][64] = { - { TEXT_CHEAT_BLJOPT0 }, - { TEXT_CHEAT_BLJOPT1 }, - { TEXT_CHEAT_BLJOPT2 }, +static char optsBljOptAnyCheatStr[][64] = { + "Disabled", + "Pressing", + "Holding", }; -static const u8 *cheatChoicesBljOptAny[] = { +static char *cheatChoicesBljOptAny[] = { optsBljOptAnyCheatStr[0], optsBljOptAnyCheatStr[1], optsBljOptAnyCheatStr[2], }; -static const u8 optsBljAnyCheatStr[][64] = { - { TEXT_CHEAT_BLJANY0 }, - { TEXT_CHEAT_BLJANY1 }, +static char optsBljAnyCheatStr[][64] = { + "BLJ toggle", + "BLJ start speed", }; static struct Option optWalkOnCheats[] = { @@ -94,7 +93,7 @@ static struct Option optWalkOnCheats[] = { static struct SubMenu menuCheatWalkOn = DEF_SUBMENU( optCheatMenuStr[1], optWalkOnCheats ); static struct Option optBljAnyCheats[] = { - DEF_OPT_CHOICE( optsCheatsStr[10], &Cheats.BljAny.Mode, cheatChoicesBljOptAny ), + DEF_OPT_CHOICE( optsBljAnyCheatStr[0], &Cheats.BljAny.Mode, cheatChoicesBljOptAny ), DEF_OPT_SCROLL( optsBljAnyCheatStr[1], &Cheats.BljAny.VelForce, 0, 10, 1 ), }; diff --git a/src/extras/cheats.h b/src/extras/cheats.h index 9185af3fd..c44a9e58f 100644 --- a/src/extras/cheats.h +++ b/src/extras/cheats.h @@ -22,7 +22,7 @@ #define bool int #endif -extern const u8 optCheatMenuStr[][32]; +extern char optCheatMenuStr[][32]; struct CheatListWalkOn { bool Lava; From d68600b732087255a5cfcb32202a4b5fa8a35d0d Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sun, 25 Dec 2022 12:44:01 -0500 Subject: [PATCH 07/14] fix debug menu --- defines.mk | 2 +- src/extras/debug_menu.c | 41 ++++++++++++++++++++--------------------- src/extras/debug_menu.h | 2 +- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/defines.mk b/defines.mk index dc07e5576..02c16c1a4 100644 --- a/defines.mk +++ b/defines.mk @@ -122,7 +122,7 @@ endif # !TARGET_N64 ifeq ($(DEBUG),1) CUSTOM_C_DEFINES += -DDEBUG COMPILER_OPT := debug - #EXT_DEBUG_MENU := 1 + EXT_DEBUG_MENU := 1 endif # Check for Debug Menu option diff --git a/src/extras/debug_menu.c b/src/extras/debug_menu.c index 30a1c91ab..6187eadf8 100644 --- a/src/extras/debug_menu.c +++ b/src/extras/debug_menu.c @@ -3,7 +3,6 @@ #include #include "sm64.h" -#include "text_strings.h" #include "gfx_dimensions.h" #include "seq_ids.h" @@ -31,7 +30,7 @@ extern bool gShowDebugText; extern bool gDebugLevelSelect; extern bool gShowProfiler; extern s16 gMenuMode; -extern s8 gMenuState; +extern s8 gDialogBoxState; extern struct CreditsEntry sCreditsSequence[]; extern void try_modify_debug_controls(void); extern void try_change_debug_page(void); @@ -40,35 +39,35 @@ extern void set_play_mode(s16 playMode); struct DebugOptList DebugOpt; -const u8 optDebugMenuStr[][32] = { - { TEXT_OPT_DEBUG }, - { TEXT_OPT_DEBUG_WARP }, +char optDebugMenuStr[][32] = { + "DEBUG", + "WARP DEBUG", }; -static const u8 optsDebugStr[][64] = { - { TEXT_OPT_DEBUG0 }, - { TEXT_OPT_DEBUG1 }, - { TEXT_OPT_DEBUG2 }, - { TEXT_OPT_DEBUG3 }, - { TEXT_OPT_DEBUG4 }, - { TEXT_OPT_DEBUG5 }, - { TEXT_OPT_DEBUG6 }, - { TEXT_OPT_DEBUG7 }, - { TEXT_OPT_DEBUG8 }, +static char optsDebugStr[][64] = { + "Simple Debug Display", + "Complex Debug Display", + "Level Select", + "Free Movement (Press L)", + "Debug Cap Changer", + "Show Profiler", + "Show FPS", + "Complete Save", + "Warp Debug", }; -static const u8 optsDebugWarpDestStr[][64] = { - { TEXT_DEBUG_WARP0 }, - { TEXT_DEBUG_WARP1 }, - { TEXT_DEBUG_WARP2 }, - { TEXT_DEBUG_WARP3 }, +static char optsDebugWarpDestStr[][64] = { + "Warp to Ending", + "Warp to Credits", + "Warp to Level Success", + "Warp to Level Failure", }; static void force_quit_pause_debug(void) { level_set_transition(0, NULL); optmenu_open = 0; gMenuMode = -1; - gMenuState = 0; + gDialogBoxState = 0; raise_background_noise(1); gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; set_play_mode(0); diff --git a/src/extras/debug_menu.h b/src/extras/debug_menu.h index 72b889713..3fe43a60b 100644 --- a/src/extras/debug_menu.h +++ b/src/extras/debug_menu.h @@ -23,7 +23,7 @@ #define bool int #endif -extern const u8 optDebugMenuStr[][32]; +extern char optDebugMenuStr[][32]; struct DebugOptList { bool ComplexDbgTxt; From e941400180958071038500d87562f42c45d604f9 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Mon, 26 Dec 2022 17:50:55 -0500 Subject: [PATCH 08/14] fix discord rich presence --- src/game/ingame_menu.c | 57 +++++++++++++++++++++--- src/game/ingame_menu.h | 3 +- src/pc/discord/discordrpc.c | 89 +++++-------------------------------- 3 files changed, 66 insertions(+), 83 deletions(-) diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 196de3b49..83a388c44 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -123,20 +123,67 @@ static u8 sGenericFontLineHeight = 0; static u8 sGenericFontLineAlignment = TEXT_ALIGN_LEFT; /************************************************** - * COMPATIBILITY * + * MISCELLANEOUS * **************************************************/ +/* + * Vanilla course names has the course number on the same string. + * Since the course number is now rendered separately, + * there's no need to do that anymore. + * This function checks if the number is still part of the name, it's + * mostly used just so the strings are displayed using &courseName[3] + */ u8 check_number_string_in_course_name(char *courseName) { - // TODO JP Support - if ((courseName[0] == 0x20 || courseName[0] == 0x31) && - (courseName[1] == 0x20 || courseName[1] >= 0x30 && courseName[1] <= 0x39) && - courseName[2] == 0x20) { + // TODO: Add Japanese char Support + if ((courseName[0] == ' ' || courseName[0] == '1') && + (courseName[1] == ' ' || courseName[1] >= '0' && courseName[1] <= '9') && + courseName[2] == ' ') { return TRUE; } return FALSE; } +// From https://www.includehelp.com/c-programs/capitalize-first-character-of-each-word-in-string.aspx +/* + * Only makes the first letter of each word separated by a space and + * also checks the first character of a strings. + * This could be used for vanilla course names and acts since they are all uppercase. +*/ +void captialize_first_character_only(char *str) +{ + int i; + + //capitalize first character of words + for(i=0; str[i]!='\0'; i++) + { + //check first character is lowercase alphabet + if(i==0) + { + if((str[i]>='a' && str[i]<='z')) + str[i]=str[i]-32; //subtract 32 to make it capital + continue; //continue to the loop + } + if(str[i]==' ')//check space + { + //if space is are found, check next character + ++i; + //check next character is lowercase alphabet + if(str[i]>='a' && str[i]<='z') + { + str[i]=str[i]-32; //subtract 32 to make it capital + continue; //continue to the loop + } + } + else + { + //all other uppercase characters should be in lowercase + if(str[i]>='A' && str[i]<='Z') + str[i]=str[i]+32; //subtract 32 to make it small/lowercase + } + } +} + /************************************************** * MATRIX * **************************************************/ diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index df0f4a05d..66978c417 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -161,11 +161,12 @@ extern s8 gRedCoinsCollected; /* * Regarding get_str_x_pos_from_center / get_str_x_pos_from_center_scale: * They cannot use a macro due to the new print_generic_string function. - * Instead as a replacement you can use print_generic_string_aligned and + * Instead as a replacement you can use print_generic_string_aligned and * set TEXT_ALIGN_CENTER as it's alignment value. */ u8 check_number_string_in_course_name(char *courseName); +void captialize_first_character_only(char *str); void create_dl_identity_matrix(void); void create_dl_translation_matrix(s8 pushOp, f32 x, f32 y, f32 z); diff --git a/src/pc/discord/discordrpc.c b/src/pc/discord/discordrpc.c index 4e9bcee4a..6125937aa 100644 --- a/src/pc/discord/discordrpc.c +++ b/src/pc/discord/discordrpc.c @@ -5,6 +5,7 @@ #include "macros.h" #include "PR/ultratypes.h" +#include "game/ingame_menu.h" #include "game/memory.h" #include "game/save_file.h" #include "pc/configfile.h" @@ -65,78 +66,6 @@ static char act[188]; static char smallImageKey[5]; static char largeImageKey[5]; -static const char charset[0xFF+1] = { - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7 - ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', // 15 - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 23 - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 31 - 'w', 'x', 'y', 'z', ' ', ' ', ' ', ' ', // 39 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 49 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 55 - ' ', ' ', ' ', ' ', ' ', ' ', '\'', ' ', // 63 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 71 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 79 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 87 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 95 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 103 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ',', // 111 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 119 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 127 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 135 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 143 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 151 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', // 159 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 167 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 175 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 183 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 192 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 199 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 207 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 215 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 223 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 231 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 239 - ' ', ' ', '!', ' ', ' ', ' ', ' ', ' ', // 247 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' // 255 -}; - -static void convertstring(const u8 *str, char* output) { - s32 strPos = 0; - bool capitalizeChar = true; - - while (str[strPos] != 0xFF) { - if (str[strPos] < 0xFF) { - output[strPos] = charset[str[strPos]]; - - // if the char is a letter we can capatalize it - if (capitalizeChar && 0x0A <= str[strPos] && str[strPos] <= 0x23) { - output[strPos] -= ('a' - 'A'); - capitalizeChar = false; - } - - } else { - output[strPos] = ' '; - } - - // decide if the next character should be capitalized - switch (output[strPos]) { - case ' ': - if (str[strPos] != 158) - fprintf(stdout, "Unknown Character (%i)\n", str[strPos]); // inform that an unknown char was found - case '-': - capitalizeChar = true; - break; - default: - capitalizeChar = false; - break; - } - - strPos++; - } - - output[strPos] = '\0'; -} - static void on_ready(UNUSED const DiscordUser* user) { discord_reset(); } @@ -172,9 +101,14 @@ static void set_details(void) { break; } #endif - u8 *courseName = segmented_to_virtual(courseNameTbl[gCurrCourseNum - 1]); - - convertstring(&courseName[3], stage); + char *courseName = segmented_to_virtual(courseNameTbl[gCurrCourseNum - 1]); + + if (check_number_string_in_course_name(courseName)) { + strcpy(stage, &courseName[3]); + } else { + strcpy(stage, courseName); + } + captialize_first_character_only(stage); } else { strcpy(stage, "Peach's Castle"); } @@ -205,9 +139,10 @@ static void set_state(void) { break; } #endif - u8 *actName = actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gCurrActNum - 1]); + char *actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gCurrActNum - 1]); - convertstring(actName, act); + strcpy(act, actName); + captialize_first_character_only(act); } else { act[0] = '\0'; gCurrActNum = 0; From ef80da9f9b8b3f24225e95365ff0675d1aa240a7 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Sun, 1 Jan 2023 03:51:09 -0500 Subject: [PATCH 09/14] JP now builds, fixes and extra checks, add small jp font --- Makefile.split | 2 + bin/segment2.c | 234 +++++++++++++++++- include/config/config_language.h | 6 +- .../main_menu_seg7.kana_dakuten_ge.rgba16.png | Bin 0 -> 882 bytes .../main_menu_seg7.kana_dakuten_ji.rgba16.png | Bin 0 -> 904 bytes .../main_menu_seg7.katakana_ra.rgba16.png | Bin 0 -> 766 bytes levels/menu/leveldata.c | 6 +- src/extras/redone/title_screen.inc.c | 15 +- src/game/ingame_menu.c | 106 +++++--- src/game/ingame_menu.h | 24 +- src/game/object_helpers.c | 2 +- src/menu/star_select.c | 4 +- src/pc/discord/discordrpc.c | 8 +- .../custom/font_graphics_jp.a.ia1.png | Bin 0 -> 888 bytes .../custom/font_graphics_jp.b.ia1.png | Bin 0 -> 890 bytes .../custom/font_graphics_jp.c.ia1.png | Bin 0 -> 886 bytes .../custom/font_graphics_jp.d.ia1.png | Bin 0 -> 892 bytes .../custom/font_graphics_jp.e.ia1.png | Bin 0 -> 890 bytes .../custom/font_graphics_jp.f.ia1.png | Bin 0 -> 891 bytes .../custom/font_graphics_jp.g.ia1.png | Bin 0 -> 891 bytes .../custom/font_graphics_jp.h.ia1.png | Bin 0 -> 887 bytes .../custom/font_graphics_jp.i.ia1.png | Bin 0 -> 882 bytes .../custom/font_graphics_jp.j.ia1.png | Bin 0 -> 887 bytes .../custom/font_graphics_jp.k.ia1.png | Bin 0 -> 898 bytes .../custom/font_graphics_jp.l.ia1.png | Bin 0 -> 874 bytes .../custom/font_graphics_jp.m.ia1.png | Bin 0 -> 885 bytes .../custom/font_graphics_jp.n.ia1.png | Bin 0 -> 886 bytes .../custom/font_graphics_jp.o.ia1.png | Bin 0 -> 887 bytes .../custom/font_graphics_jp.p.ia1.png | Bin 0 -> 889 bytes .../custom/font_graphics_jp.q.ia1.png | Bin 0 -> 894 bytes .../custom/font_graphics_jp.r.ia1.png | Bin 0 -> 880 bytes .../custom/font_graphics_jp.s.ia1.png | Bin 0 -> 884 bytes .../custom/font_graphics_jp.t.ia1.png | Bin 0 -> 891 bytes .../custom/font_graphics_jp.u.ia1.png | Bin 0 -> 884 bytes .../custom/font_graphics_jp.v.ia1.png | Bin 0 -> 885 bytes .../custom/font_graphics_jp.w.ia1.png | Bin 0 -> 890 bytes .../custom/font_graphics_jp.x.ia1.png | Bin 0 -> 893 bytes .../custom/font_graphics_jp.y.ia1.png | Bin 0 -> 889 bytes .../custom/font_graphics_jp.z.ia1.png | Bin 0 -> 887 bytes 39 files changed, 338 insertions(+), 69 deletions(-) create mode 100644 levels/menu/custom/main_menu_seg7.kana_dakuten_ge.rgba16.png create mode 100644 levels/menu/custom/main_menu_seg7.kana_dakuten_ji.rgba16.png create mode 100644 levels/menu/custom/main_menu_seg7.katakana_ra.rgba16.png create mode 100644 textures/segment2/custom/font_graphics_jp.a.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.b.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.c.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.d.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.e.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.f.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.g.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.h.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.i.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.j.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.k.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.l.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.m.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.n.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.o.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.p.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.q.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.r.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.s.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.t.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.u.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.v.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.w.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.x.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.y.ia1.png create mode 100644 textures/segment2/custom/font_graphics_jp.z.ia1.png diff --git a/Makefile.split b/Makefile.split index 953f767bd..9d193c1e6 100644 --- a/Makefile.split +++ b/Makefile.split @@ -217,6 +217,8 @@ $(BUILD_DIR)/levels/ending/cake.inc.c: levels/ending/cake.png # Others SEGMENT2_TEXTURES := $(wildcard $(TEXTURE_DIR)/segment2/*.png) $(wildcard $(TEXTURE_DIR)/segment2/custom/*.png) $(wildcard $(TEXTURE_DIR)/segment2/predone/*.png) +SEGMENT2_TEXTURES += $(CUSTOM_MENU_SEG7_FILES) # For JP colorful font + TITLE_SCREEN_BG_TEXTURES := $(wildcard $(TEXTURE_DIR)/title_screen_bg/*.png) SPOOKY_TEXTURES := $(wildcard $(TEXTURE_DIR)/spooky/*.png) GENERIC_TEXTURES := $(wildcard $(TEXTURE_DIR)/generic/*.png) diff --git a/bin/segment2.c b/bin/segment2.c index 8e69bc4c2..81f65bdf9 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -488,6 +488,112 @@ ALIGNED8 static const Texture texture_font_char_jp_Z[] = { #include "textures/segment2/segment2.07330.ia1.inc.c" }; +#if (defined(VERSION_JP) || defined(VERSION_SH)) && !defined(MULTILANG) +ALIGNED8 static const Texture texture_font_char_jp_a[] = { +#include "textures/segment2/custom/font_graphics_jp.a.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_b[] = { +#include "textures/segment2/custom/font_graphics_jp.b.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_c[] = { +#include "textures/segment2/custom/font_graphics_jp.c.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_d[] = { +#include "textures/segment2/custom/font_graphics_jp.d.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_e[] = { +#include "textures/segment2/custom/font_graphics_jp.e.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_f[] = { +#include "textures/segment2/custom/font_graphics_jp.f.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_g[] = { +#include "textures/segment2/custom/font_graphics_jp.g.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_h[] = { +#include "textures/segment2/custom/font_graphics_jp.h.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_i[] = { +#include "textures/segment2/custom/font_graphics_jp.i.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_j[] = { +#include "textures/segment2/custom/font_graphics_jp.j.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_k[] = { +#include "textures/segment2/custom/font_graphics_jp.k.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_l[] = { +#include "textures/segment2/custom/font_graphics_jp.l.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_m[] = { +#include "textures/segment2/custom/font_graphics_jp.m.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_n[] = { +#include "textures/segment2/custom/font_graphics_jp.n.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_o[] = { +#include "textures/segment2/custom/font_graphics_jp.o.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_p[] = { +#include "textures/segment2/custom/font_graphics_jp.p.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_q[] = { +#include "textures/segment2/custom/font_graphics_jp.q.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_r[] = { +#include "textures/segment2/custom/font_graphics_jp.r.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_s[] = { +#include "textures/segment2/custom/font_graphics_jp.s.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_t[] = { +#include "textures/segment2/custom/font_graphics_jp.t.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_u[] = { +#include "textures/segment2/custom/font_graphics_jp.u.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_v[] = { +#include "textures/segment2/custom/font_graphics_jp.v.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_w[] = { +#include "textures/segment2/custom/font_graphics_jp.w.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_x[] = { +#include "textures/segment2/custom/font_graphics_jp.x.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_y[] = { +#include "textures/segment2/custom/font_graphics_jp.y.ia1.inc.c" +}; + +ALIGNED8 static const Texture texture_font_char_jp_z[] = { +#include "textures/segment2/custom/font_graphics_jp.z.ia1.inc.c" +}; +#endif + ALIGNED8 static const Texture texture_font_char_jp_long_vowel[] = { #include "textures/segment2/segment2.07340.ia1.inc.c" }; @@ -1978,15 +2084,15 @@ ALIGNED8 static const Texture texture_hud_char_kana_dakuten_do[] = { }; ALIGNED8 static const Texture texture_hud_char_katakana_ra[] = { -#include "levels/menu/main_menu_seg7.katakana_ra.rgba16.inc.c" +#include "levels/menu/custom/main_menu_seg7.katakana_ra.rgba16.inc.c" }; ALIGNED8 static const Texture texture_hud_char_kana_dakuten_ge[] = { -#include "levels/menu/main_menu_seg7.kana_dakuten_ge.rgba16.inc.c" +#include "levels/menu/custom/main_menu_seg7.kana_dakuten_ge.rgba16.inc.c" }; ALIGNED8 static const Texture texture_hud_char_kana_dakuten_ji[] = { -#include "levels/menu/main_menu_seg7.kana_dakuten_ji.rgba16.inc.c" +#include "levels/menu/custom/main_menu_seg7.kana_dakuten_ji.rgba16.inc.c" }; #endif @@ -2174,13 +2280,121 @@ const struct DiacriticLUTEntry main_font_diacritic_lut[] = { [TEXT_DIACRITIC_UMLAUT] = { 0, 0, "¨"}, [TEXT_DIACRITIC_UMLAUT_UPPERCASE] = { 1, 4, "¨"}, [TEXT_DIACRITIC_CEDILLA] = { 0, 0, "¸"}, -#ifdef JAPANESE_CHARACTERS +#if JAPANESE_CHARACTERS [TEXT_DIACRITIC_DAKUTEN] = { 4, 6, "゛"}, [TEXT_DIACRITIC_HANDAKUTEN] = { 7, 10, "゜"}, #endif }; +// If you build JP or SH without multilanguage, textures for these versions are used instead +#if !defined(MULTILANG) +#if defined(VERSION_JP) || defined(VERSION_SH) +#define EXCLUSIVE_TEXTURE_FONT 1 +#else +#define EXCLUSIVE_TEXTURE_FONT 0 +#endif +#endif + +#if EXCLUSIVE_TEXTURE_FONT == 1 // ASCII lookup table for the generic white font +const struct AsciiCharLUTEntry main_font_lut[] = { + {NULL, 5}, // 32 " " + {texture_font_char_jp_exclamation, 8}, // 33 "!" + {texture_font_char_us_double_quote_open, 6}, // 34 "\"" + {NULL, 0}, // 35 "#" (Unimplemented) + {NULL, 0}, // 36 "$" (Unimplemented) + {texture_font_char_jp_percent, 10}, // 37 "%" + {texture_font_char_us_ampersand, 8}, // 38 "&" + {texture_font_char_us_apostrophe, 4}, // 39 "'" + {texture_font_char_jp_open_parentheses, 10}, // 40 "(" + {texture_font_char_jp_close_parentheses, 10}, // 41 ")" + {NULL, 0}, // 42 "*" (Unimplemented) + {texture_font_char_plus, 7}, // 43 "+" + {texture_font_char_jp_comma, 6}, // 44 "," + {texture_font_char_jp_long_vowel, 10}, // 45 "-" + {texture_font_char_jp_period, 7}, // 46 "." + {texture_font_char_slash, 5}, // 47 "/" + {texture_font_char_jp_0, 10}, // 48 "0" + {texture_font_char_jp_1, 10}, // 49 "1" + {texture_font_char_jp_2, 10}, // 50 "2" + {texture_font_char_jp_3, 10}, // 51 "3" + {texture_font_char_jp_4, 10}, // 52 "4" + {texture_font_char_jp_5, 10}, // 53 "5" + {texture_font_char_jp_6, 10}, // 54 "6" + {texture_font_char_jp_7, 10}, // 55 "7" + {texture_font_char_jp_8, 10}, // 56 "8" + {texture_font_char_jp_9, 10}, // 57 "9" + {texture_font_char_us_colon, 4}, // 58 ":" + {NULL, 0}, // 59 ";" (Unimplemented) + {NULL, 0}, // 60 "<" (Unimplemented) + {NULL, 0}, // 61 "=" (Unimplemented) + {NULL, 0}, // 62 ">" (Unimplemented) + {texture_font_char_jp_question, 10}, // 63 "?" + {NULL, 0}, // 64 "@" (Unimplemented, used for color codes by default) + {texture_font_char_jp_A, 10}, // 65 "A" + {texture_font_char_jp_B, 10}, // 66 "B" + {texture_font_char_jp_C, 10}, // 67 "C" + {texture_font_char_jp_D, 10}, // 68 "D" + {texture_font_char_jp_E, 10}, // 69 "E" + {texture_font_char_jp_F, 10}, // 70 "F" + {texture_font_char_jp_G, 10}, // 71 "G" + {texture_font_char_jp_H, 10}, // 72 "H" + {texture_font_char_jp_I, 10}, // 73 "I" + {texture_font_char_jp_J, 10}, // 74 "J" + {texture_font_char_jp_K, 10}, // 75 "K" + {texture_font_char_jp_L, 10}, // 76 "L" + {texture_font_char_jp_M, 10}, // 77 "M" + {texture_font_char_jp_N, 10}, // 78 "N" + {texture_font_char_jp_O, 10}, // 79 "O" + {texture_font_char_jp_P, 10}, // 80 "P" + {texture_font_char_jp_Q, 10}, // 81 "Q" + {texture_font_char_jp_R, 10}, // 82 "R" + {texture_font_char_jp_S, 10}, // 83 "S" + {texture_font_char_jp_T, 10}, // 84 "T" + {texture_font_char_jp_U, 10}, // 85 "U" + {texture_font_char_jp_V, 10}, // 86 "V" + {texture_font_char_jp_W, 10}, // 87 "W" + {texture_font_char_jp_X, 10}, // 88 "X" + {texture_font_char_jp_Y, 10}, // 89 "Y" + {texture_font_char_jp_Z, 10}, // 90 "Z" + {NULL, 0}, // 91 "[" (Unimplemented) + {texture_font_char_backslash, 6}, // 92 "\\" + {NULL, 0}, // 93 "]" (Unimplemented) + {NULL, 0}, // 94 "^" (Unimplemented) + {NULL, 0}, // 95 "_" (Unimplemented) + {NULL, 0}, // 96 "`" (Unimplemented) + {texture_font_char_jp_a, 9}, // 97 "a" + {texture_font_char_jp_b, 8}, // 98 "b" + {texture_font_char_jp_c, 8}, // 99 "c" + {texture_font_char_jp_d, 8}, // 100 "d" + {texture_font_char_jp_e, 8}, // 101 "e" + {texture_font_char_jp_f, 8}, // 102 "f" + {texture_font_char_jp_g, 9}, // 103 "g" + {texture_font_char_jp_h, 8}, // 104 "h" + {texture_font_char_jp_i, 6}, // 105 "i" + {texture_font_char_jp_j, 8}, // 106 "j" + {texture_font_char_jp_k, 8}, // 107 "k" + {texture_font_char_jp_l, 4}, // 108 "l" + {texture_font_char_jp_m, 10}, // 109 "m" + {texture_font_char_jp_n, 8}, // 110 "n" + {texture_font_char_jp_o, 8}, // 111 "o" + {texture_font_char_jp_p, 8}, // 112 "p" + {texture_font_char_jp_q, 9}, // 113 "q" + {texture_font_char_jp_r, 8}, // 114 "r" + {texture_font_char_jp_s, 8}, // 115 "s" + {texture_font_char_jp_t, 8}, // 116 "t" + {texture_font_char_jp_u, 8}, // 117 "u" + {texture_font_char_jp_v, 8}, // 118 "v" + {texture_font_char_jp_w, 10}, // 119 "w" + {texture_font_char_jp_x, 9}, // 120 "x" + {texture_font_char_jp_y, 8}, // 121 "y" + {texture_font_char_jp_z, 8}, // 122 "z" + {NULL, 0}, // 123 "{" (Unimplemented) + {NULL, 0}, // 124 "|" (Unimplemented) + {NULL, 0}, // 125 "}" (Unimplemented) + {texture_font_char_jp_tilde, 10}, // 126 "~" +}; +#else const struct AsciiCharLUTEntry main_font_lut[] = { {NULL, 5}, // 32 " " {texture_font_char_us_exclamation, 5}, // 33 "!" @@ -2215,6 +2429,7 @@ const struct AsciiCharLUTEntry main_font_lut[] = { {NULL, 0}, // 62 ">" (Unimplemented) {texture_font_char_us_question, 7}, // 63 "?" {NULL, 0}, // 64 "@" (Unimplemented, used for color codes by default) + {texture_font_char_us_A, 6}, // 65 "A" {texture_font_char_us_B, 6}, // 66 "B" {texture_font_char_us_C, 6}, // 67 "C" @@ -2241,12 +2456,14 @@ const struct AsciiCharLUTEntry main_font_lut[] = { {texture_font_char_us_X, 7}, // 88 "X" {texture_font_char_us_Y, 6}, // 89 "Y" {texture_font_char_us_Z, 6}, // 90 "Z" + {NULL, 0}, // 91 "[" (Unimplemented) {texture_font_char_backslash, 6}, // 92 "\\" {NULL, 0}, // 93 "]" (Unimplemented) {NULL, 0}, // 94 "^" (Unimplemented) {NULL, 0}, // 95 "_" (Unimplemented) {NULL, 0}, // 96 "`" (Unimplemented) + {texture_font_char_us_a, 6}, // 97 "a" {texture_font_char_us_b, 5}, // 98 "b" {texture_font_char_us_c, 5}, // 99 "c" @@ -2273,11 +2490,13 @@ const struct AsciiCharLUTEntry main_font_lut[] = { {texture_font_char_us_x, 7}, // 120 "x" {texture_font_char_us_y, 5}, // 121 "y" {texture_font_char_us_z, 5}, // 122 "z" + {NULL, 0}, // 123 "{" (Unimplemented) {NULL, 0}, // 124 "|" (Unimplemented) {NULL, 0}, // 125 "}" (Unimplemented) {texture_font_char_us_tilde, 8}, // 126 "~" }; +#endif /* * This struct defines the UTF-8 characters supported by the main white font! @@ -2395,7 +2614,7 @@ const struct Utf8CharLUTEntry main_font_utf8_3byte_lut[] = { {0x2606, 10, 0, texture_font_char_us_star_hollow}, // ☆ {0x272A, 8, 0, texture_font_char_us_coin}, // ✪ -#ifdef JAPANESE_CHARACTERS +#if JAPANESE_CHARACTERS {0x3000, 10, 0, NULL}, // " " (ideographic space) {0x3001, 10, TEXT_FLAG_PACKED, texture_font_char_jp_comma}, // 、 {0x3002, 10, TEXT_FLAG_PACKED, texture_font_char_jp_period}, // 。 @@ -2748,8 +2967,13 @@ const Texture *const main_hud_camera_lut[] = { #define ACT_NAME_TABLE seg2_act_name_table #define DIALOG_TABLE seg2_dialog_table +#if defined(VERSION_JP) || defined(VERSION_SH) +#define DIALOG_FILE "jp/dialogs.h" +#define COURSE_FILE "jp/courses.h" +#else #define DIALOG_FILE "us/dialogs.h" #define COURSE_FILE "us/courses.h" +#endif #include "text/define_text.inc.c" #undef DIALOG_FILE #undef COURSE_FILE diff --git a/include/config/config_language.h b/include/config/config_language.h index 6dcff15a1..54be085c3 100644 --- a/include/config/config_language.h +++ b/include/config/config_language.h @@ -15,7 +15,7 @@ * This define enables support for Japanese characters even when multilang or Japanese is not enabled. * Requires a Japanese baserom. */ -// #define JAPANESE_CHARACTERS +#define JAPANESE_CHARACTERS (0 || VERSION_JP || VERSION_SH || ENABLE_JAPANESE) /** * This replaces translation specific defines to general ones to be used for more languages. @@ -27,7 +27,3 @@ #undef ENABLE_GERMAN #undef ENABLE_JAPANESE #endif // !MULTILANG - -#ifdef ENABLE_JAPANESE - #define JAPANESE_CHARACTERS -#endif // ENABLE_JAPANESE diff --git a/levels/menu/custom/main_menu_seg7.kana_dakuten_ge.rgba16.png b/levels/menu/custom/main_menu_seg7.kana_dakuten_ge.rgba16.png new file mode 100644 index 0000000000000000000000000000000000000000..160a87e30e96559416c03d697b4ad58250627299 GIT binary patch literal 882 zcmV-&1C9KNP)EX>4Tx04R}tkv&MmKpe$iQ>CI62Rler$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oi`@MGpo63?nQtQ%|H9GVmN<_we!cF3PjK&;2=imAuISpGZ8*bi*QEC!XH4 zbk6(4Ay$$U;&b9LgDyz?$aUG}H_kh$D)sQNECM zS>e3JSuIyt^Pc>L!MwJd<~q$G#IcA3k`N)IiVc)uAxf)8iis5M$2|OD$DbsZOs)+u za?GOw6_Voz|AXJ%nuW;;Hz^ncI$v!2V+0870*#t&e;?a+;{@ zj20<-&Ewr&?Y;ebrrF;QciVEQ^42kj00006VoOIv0RI5)0059%fmr|m010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_jAEDeSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00Bx#L_t(I%YBlqP6JU8g};STwx!VW2uP?zq5we%JOVf* z!65noG<^b0lWsynfPeNcDuJMon*2*cjlb=g_20ml2G_|C#9Ii zXwfDNKD3|!fV68m!tEQRp4lrbN(>wWXOPSwi~Ox)?koaYK*Q{i;QQ4Aw_SlQMA^rJ zJ(v^Jit?w3u?NPGOyCNl+}|IEh4y>)jRJxbpzZ80z&p!j-zzAxw}DOX`2rXMbx-r- z?EX>4Tx04R}tkv&MmKpe$iQ>CI62Rler$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oi`@MGpo63?nQtQ%|H9GVmN<_we!cF3PjK&;2=imAuISpGZ8*bi*QEC!XH4 zbk6(4Ay$$U;&b9LgDyz?$aUG}H_kh$D)sQNECM zS>e3JSuIyt^Pc>L!MwJd<~q$G#IcA3k`N)IiVc)uAxf)8iis5M$2|OD$DbsZOs)+u za?GOw6_Voz|AXJ%nuW;;Hz^ncI$v!2V+0870*#t&e;?a+;{@ zj20<-&Ewr&?Y;ebrrF;QciVEQ^42kj00006VoOIv0001-0RJFJ6=nbc010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_jAG10A+(GV=fc02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00Cf0L_t(I%Z<`IZj@0B1>n!gke7fEL;(d0ARW_AIXj>w z4N|r-RaU?rGDsBAK!+wBh>D163Mgo(5JHHEhmc~5-+$%}Sh93|ug|f4uERfUl$o#U zJm@ld!*qOMnVG(qn|+}5ZQcp=DriY|B6M*BKXHaGZsIe3v(^&y;S0VMQLicQ zG{SA{R^n-dTe#MQ7XgU5A9cAC(HxGabU26wWiwM$ z?kF?eEng<$oE>GRhgo70GE)zm*v2}ZLBulfU|4xy@qmtfjBCDo_c>2IT3UJVxWL=E zf}mqORq3f*wM_jd1#CNg*Sy95Y-0a;0oUty#yD)ojLgiFzYz3a;1V{<-%h~QL8hZ( zzg!hMRdKicYQ4Xn1*_CXkhKDDR=j~dT(A4lB6vcuh4X54ufVNXFL5|rxm4j!rt#d` eF4)0JvHt*(DUl5s0H(SC0000EX>4Tx04R}tkv&MmKpe$iQ>CI62Rler$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oi`@MGpo63?nQtQ%|H9GVmN<_we!cF3PjK&;2=imAuISpGZ8*bi*QEC!XH4 zbk6(4Ay$$U;&b9LgDyz?$aUG}H_kh$D)sQNECM zS>e3JSuIyt^Pc>L!MwJd<~q$G#IcA3k`N)IiVc)uAxf)8iis5M$2|OD$DbsZOs)+u za?GOw6_Voz|AXJ%nuW;;Hz^ncI$v!2V+0870*#t&e;?a+;{@ zj20<-&Ewr&?Y;ebrrF;QciVEQ^42kj00006VoOIv0001-0RJFJ6=nbc010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_jAK3kQVW>0JN-02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{007oWL_t(I%bk%iZo@DPMIQ^pK1-({bEYOY=-6w>*U;u} zJwT>zDbS(b+G}{rl1`nn{S3AoML`tTA0Q+Vdi5*I)j~ wp!%g>{re?1s&UtD!7topDisplayedScene + i + this->count) % this->count; - int_to_str(scene + 1, levelNumStr); - + format_int_to_string(levelNumStr, scene + 1); + if (scene == this->currentScene) { gDPSetEnvColor(gDisplayListHead++, 255, 126, 0, 255); } else { @@ -88,6 +88,7 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { courseNum = gLevelToCourseNumTable[scene]; courseName = segmented_to_virtual(courseNameTbl[courseNum - 1]); int_to_str(courseNum, courseNumStr); + format_int_to_string(courseNumStr, courseNum); if (this->toggleCourseLevelView) { chrTemp = "LEVEL NAME"; @@ -97,11 +98,7 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { chrTemp = "COURSE NAME"; print_generic_string(72, 180 - i * 11, courseNumStr); if (courseName != NULL && courseNum >= COURSE_MIN && courseNum <= COURSE_MAX) { - if (check_number_string_in_course_name(courseName)) { - print_generic_string(100, 180 - i * 11, &courseName[3]); - } else { - print_generic_string(100, 180 - i * 11, courseName); - } + print_generic_string(100, 180 - i * 11, check_number_string_in_course_name(courseName)); } } gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 83a388c44..e31d4f642 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -35,8 +35,10 @@ DialogVariable gDialogVariable; u16 gDialogTextAlpha; s8 gRedCoinsCollected; +#ifdef MULTILANG // The language to display the game's text in. u8 gInGameLanguage = LANGUAGE_ENGLISH; +#endif extern u8 dialog_table_en[]; extern u8 course_name_table_en[]; @@ -126,32 +128,60 @@ static u8 sGenericFontLineAlignment = TEXT_ALIGN_LEFT; * MISCELLANEOUS * **************************************************/ +/* + * JP, EU and SH likes to use texture conversions from ia1 to ia8/ia4 respectively. + * To still support these without altering the AsciiCharLUTEntry struct, + * this look up table exists so that specific chars are only converted. + */ + +#if (defined(VERSION_JP) || defined(VERSION_EU) || defined(VERSION_SH)) && !defined(MULTILANG) +u8 gCharTextureConvBool[] = { + 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, +}; +#endif + /* * Vanilla course names has the course number on the same string. * Since the course number is now rendered separately, * there's no need to do that anymore. - * This function checks if the number is still part of the name, it's - * mostly used just so the strings are displayed using &courseName[3] + * This function checks if the number is still part of the name. */ -u8 check_number_string_in_course_name(char *courseName) { - // TODO: Add Japanese char Support - if ((courseName[0] == ' ' || courseName[0] == '1') && - (courseName[1] == ' ' || courseName[1] >= '0' && courseName[1] <= '9') && - courseName[2] == ' ') { - return TRUE; +char *check_number_string_in_course_name(u8 *str) { +#if JAPANESE_CHARACTERS + // Make assumptions of specific char values in Japanese. + #ifdef ENABLE_JAPANESE + if (gInGameLanguage == LANGUAGE_JAPANESE) { + #endif + if ((str[2] == 0x80 || str[2] == 0x91) && + (str[5] == 0x80 || str[5] >= 0x90 && str[5] <= 0x99) && + str[8] == 0x80) { + return &str[9]; } - - return FALSE; + #ifdef ENABLE_JAPANESE + } + #endif +#endif + if ((str[0] == ' ' || str[0] == '1') && + (str[1] == ' ' || str[1] >= '0' && str[1] <= '9') && + str[2] == ' ') { + return &str[3]; + } + + return str; } // From https://www.includehelp.com/c-programs/capitalize-first-character-of-each-word-in-string.aspx /* * Only makes the first letter of each word separated by a space and - * also checks the first character of a strings. - * This could be used for vanilla course names and acts since they are all uppercase. + * also checks the first character of a string. + * This could be used for course names and acts since they are all uppercase. */ -void captialize_first_character_only(char *str) -{ +void captialize_first_character_only(char *str) { int i; //capitalize first character of words @@ -272,6 +302,10 @@ void create_dl_ortho_matrix(void) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH); } +/************************************************** + * ASCII/UTF-8 UTILS * + **************************************************/ + /** * Determine which UTF-8 character to render, given a string and the current position in the string. * Returns the table entry of the relevant character. @@ -410,8 +444,11 @@ static s32 get_alignment_x_offset(char *str, u32 alignment, struct AsciiCharLUTE * If the language is set to Japanese, the number is written in full-width digits. */ void format_int_to_string(char *buf, s32 value) { -#ifdef ENABLE_JAPANESE - if (gInGameLanguage == LANGUAGE_JAPANESE) { +#if JAPANESE_CHARACTERS + #ifdef ENABLE_JAPANESE + if (gInGameLanguage == LANGUAGE_JAPANESE) + #endif + { u8 digits[10]; s32 numDigits = 0; // Minus sign @@ -435,10 +472,14 @@ void format_int_to_string(char *buf, s32 value) { return; } #endif - + // This is unreachable if JP or SH are defined sprintf(buf, "%d", value); } +/************************************************** + * TEXTURE CONVERSION * + **************************************************/ + /** * Unpacks a packed I1 character texture into a usable IA8 texture when TEXT_FLAG_PACKED is used. * By default this is used for all the Japanese characters. @@ -446,6 +487,7 @@ void format_int_to_string(char *buf, s32 value) { static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) { s32 inPos; u16 bitMask; + u16 inWord; u8 *out; s16 outPos = 0; @@ -456,10 +498,11 @@ static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) { } for (inPos = 0; inPos < (width * height) / 16; inPos++) { + inWord = BE_TO_HOST16(in[inPos]); bitMask = 0x8000; while (bitMask != 0) { - if (in[inPos] & bitMask) { + if (inWord & bitMask) { out[outPos] = 0xFF; } else { out[outPos] = 0x00; @@ -482,6 +525,15 @@ static u32 render_generic_ascii_char(char c) { if (texture != NULL) { gDPPipeSync(gDisplayListHead++); + +#if (defined(VERSION_JP) || defined(VERSION_EU) || defined(VERSION_SH)) && !defined(MULTILANG) + if (gCharTextureConvBool[ASCII_LUT_INDEX(c)]) { + void *unpackedTexture = alloc_ia8_text_from_i1(segmented_to_virtual(texture), 8, 16); + gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, unpackedTexture); + gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings_packed); + return fontLUT[ASCII_LUT_INDEX(c)].kerning; + } +#endif gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, texture); gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); } @@ -1448,7 +1500,9 @@ void print_peach_letter_message(void) { gSPDisplayList(gDisplayListHead++, dl_ia_text_end); gDPSetEnvColor(gDisplayListHead++, 200, 80, 120, gDialogTextAlpha); +#ifndef VERSION_JP gSPDisplayList(gDisplayListHead++, castle_grounds_seg7_us_dl_0700F2E8); +#endif // at the start/end of message, reset the fade. if (gCutsceneMsgTimer == 0) { @@ -1612,7 +1666,7 @@ void render_pause_my_score_coins(void) { gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); - char *courseName = segmented_to_virtual(courseNameTbl[courseIndex]); + u8 *courseName = segmented_to_virtual(courseNameTbl[courseIndex]); if (courseIndex <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { char courseNumText[8]; @@ -1629,11 +1683,7 @@ void render_pause_my_score_coins(void) { } print_generic_string(PAUSE_MENU_RIGHT_X, PAUSE_MENU_ACT_Y, actName); - if (check_number_string_in_course_name(courseName)) { - print_generic_string(PAUSE_MENU_RIGHT_X, PAUSE_MENU_COURSE_Y, &courseName[3]); - } else { - print_generic_string(PAUSE_MENU_RIGHT_X, PAUSE_MENU_COURSE_Y, courseName); - } + print_generic_string(PAUSE_MENU_RIGHT_X, PAUSE_MENU_COURSE_Y, check_number_string_in_course_name(courseName)); if (save_file_get_course_star_count(gCurrSaveFileNum - 1, courseIndex) != 0) { print_generic_string_aligned(PAUSE_MENU_LEFT_X + 3, PAUSE_MENU_MY_SCORE_Y, LANG_ARRAY(textMyScore), TEXT_ALIGN_RIGHT); @@ -1838,7 +1888,7 @@ LangArray textStarX = DEFINE_LANGUAGE_ARRAY( void render_pause_castle_main_strings(s16 x, s16 y) { void **courseNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]); - char *courseName; + u8 *courseName; char str[8]; char countText[10]; @@ -1879,11 +1929,7 @@ void render_pause_castle_main_strings(s16 x, s16 y) { if (gDialogLineNum <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { // Main courses courseName = segmented_to_virtual(courseNameTbl[gDialogLineNum]); - if (check_number_string_in_course_name(courseName)) { - print_generic_string(x - 50, y + 35, &courseName[3]); - } else { - print_generic_string(x - 50, y + 35, courseName); - } + print_generic_string(x - 50, y + 35, check_number_string_in_course_name(courseName)); render_pause_castle_course_stars(x - 65, y, gCurrSaveFileNum - 1, gDialogLineNum); diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index 66978c417..c75a3b2f3 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -33,12 +33,16 @@ enum HUDFlashModes { extern s8 gHudFlash; extern s8 gDialogCourseActNum; +#ifdef MULTILANG extern u8 gInGameLanguage; +#else +#define gInGameLanguage 0 +#endif extern void *languageTable[][3]; struct AsciiCharLUTEntry { const Texture *texture; - const s8 kerning; + u16 kerning; // can support flags if desired }; // Convert an ASCII char to the index in the ASCII LUT. ASCII LUTs start at the space character. @@ -87,7 +91,7 @@ enum TextDiacriticMarks { TEXT_DIACRITIC_UMLAUT, TEXT_DIACRITIC_UMLAUT_UPPERCASE, TEXT_DIACRITIC_CEDILLA, -#ifdef JAPANESE_CHARACTERS +#if JAPANESE_CHARACTERS TEXT_DIACRITIC_DAKUTEN, TEXT_DIACRITIC_HANDAKUTEN, #endif @@ -99,9 +103,12 @@ enum TextAlignments { TEXT_ALIGN_RIGHT, }; +//#define TEXT_FLAG_PACKED_IA4 0x4000 // EU, has fonts flipped (Converts from IA1 to IA4) +//#define TEXT_FLAG_PACKED_IA8 0x8000 // JP, no fonts flipped (Converts from IA1 to IA8) +//#define TEXT_FLAG_PACKED_MASK (TEXT_FLAG_PACKED_IA4 | TEXT_FLAG_PACKED_IA8) #define TEXT_FLAG_PACKED 0x8000 #define TEXT_DIACRITIC_MASK 0x00FF -// bits 0x0100 through 0x4000 are free for use, and the mask can be reduced if necessary +// bits 0x0100 through 0x2000 are free for use, and the mask can be reduced if necessary struct DialogEntry { /*0x00*/ s32 voice; @@ -136,13 +143,14 @@ typedef char * LangArray[LANGUAGE_COUNT]; #define DEFINE_LANGUAGE_ARRAY(english, french, german, japanese) {english, french, german, japanese} #else - -// If multilang is off, ignore all other languages and only include English. -#define LANGUAGE_ENGLISH 0 - typedef char * LangArray; #define LANG_ARRAY(cmd) (cmd) + +#if defined(VERSION_JP) || defined(VERSION_SH) +#define DEFINE_LANGUAGE_ARRAY(english, french, german, japanese) japanese +#else #define DEFINE_LANGUAGE_ARRAY(english, french, german, japanese) english +#endif #endif @@ -165,7 +173,7 @@ extern s8 gRedCoinsCollected; * set TEXT_ALIGN_CENTER as it's alignment value. */ -u8 check_number_string_in_course_name(char *courseName); +char *check_number_string_in_course_name(u8 *str); void captialize_first_character_only(char *str); void create_dl_identity_matrix(void); diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 20f799193..9e3428a38 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -1624,8 +1624,8 @@ static void cur_obj_update_floor(void) { #endif o->oMoveFlags |= OBJ_MOVE_ABOVE_DEATH_BARRIER; break; - } #endif + } } } diff --git a/src/menu/star_select.c b/src/menu/star_select.c index 9133740d6..0f108735a 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -266,7 +266,7 @@ LangArray textActMyScore = DEFINE_LANGUAGE_ARRAY( */ void print_act_selector_strings(void) { char **levelNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][1]); - char *currLevelName = segmented_to_virtual(levelNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum)]); + u8 *courseName = segmented_to_virtual(levelNameTbl[COURSE_NUM_TO_INDEX(gCurrCourseNum)]); char **actNameTbl = segmented_to_virtual(languageTable[gInGameLanguage][2]); char *selectedActName; s8 i; @@ -287,7 +287,7 @@ void print_act_selector_strings(void) { print_generic_string_aligned(145, 118, LANG_ARRAY(textActMyScore), TEXT_ALIGN_RIGHT); } - print_generic_string_aligned(SCREEN_CENTER_X, 33, currLevelName, TEXT_ALIGN_CENTER); + print_generic_string_aligned(SCREEN_CENTER_X, 33, check_number_string_in_course_name(courseName), TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); diff --git a/src/pc/discord/discordrpc.c b/src/pc/discord/discordrpc.c index 6125937aa..a79038e0e 100644 --- a/src/pc/discord/discordrpc.c +++ b/src/pc/discord/discordrpc.c @@ -101,13 +101,9 @@ static void set_details(void) { break; } #endif - char *courseName = segmented_to_virtual(courseNameTbl[gCurrCourseNum - 1]); + u8 *courseName = segmented_to_virtual(courseNameTbl[gCurrCourseNum - 1]); - if (check_number_string_in_course_name(courseName)) { - strcpy(stage, &courseName[3]); - } else { - strcpy(stage, courseName); - } + strcpy(stage, check_number_string_in_course_name(courseName)); captialize_first_character_only(stage); } else { strcpy(stage, "Peach's Castle"); diff --git a/textures/segment2/custom/font_graphics_jp.a.ia1.png b/textures/segment2/custom/font_graphics_jp.a.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..ef8dc8814b1e9f66c1c505cc707376a07d0d472c GIT binary patch literal 888 zcmV-;1Bd*HP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HCP_p=RCwBBWPk!javA@@BqPIrAOcd1|3Q-f(HUSVuv#DskAVP8WD5~}0;z-m O00006ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HC`m*?RCwBBWPk!jOvZmkVi^CyT7VRg1PVi>Fc=`r$N*7`%`O-N02qJ|5x%pm Q@&Et;07*qoM6N<$f;CQ_U;qFB literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.c.ia1.png b/textures/segment2/custom/font_graphics_jp.c.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..98a5bcb59e3e87eb4aee8897e54322d16be25487 GIT binary patch literal 886 zcmV-+1Bv{JP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HBuPX;RCwBBWPk!javA@@BqPIr5Sx*K@jp}&!GKF46yr1y0Kr=b5#NjAlmGw# M07*qoM6N<$g5qPIM*si- literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.d.ia1.png b/textures/segment2/custom/font_graphics_jp.d.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..ad42a497e3b92787c7aa56fae6debcce3ae950bd GIT binary patch literal 892 zcmV-?1B3jDP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HDoI2^RCwBBWPk!j9E|^r1Q`FpN*O`C{~*SHMyM1r<3Cgl1DMB%+fo42ZVwT! SZ87!$00006ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HC`m*?RCwBBWPk!javA@@BqPIr5Sx*K5ll0H7*GXZ5eWM~R0Owy0M=Cq5yCpT QzyJUM07*qoM6N<$f-hvAF#rGn literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.f.ia1.png b/textures/segment2/custom/font_graphics_jp.f.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..a84d134cd2bb7734f0aa99820cb198b37c2d7cef GIT binary patch literal 891 zcmV->1BCpEP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HDM>^@RCwBBWPk!jtc?F45{UjYLPY*Ez!;1SFcC1t2$eyR!p*>GDFEzc3K6-m R1&jay002ovPDHLkV1g4rpj`j} literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.g.ia1.png b/textures/segment2/custom/font_graphics_jp.g.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..14b25a5e7db17f8fa2418848da54700eb4c4d4fb GIT binary patch literal 891 zcmV->1BCpEP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HDM>^@RCwBBWPk!jQW^h2G?4Khj2Xc+8iN6h86j$c46qDT3Tz6d$pF?|4H2Mu Ro238%002ovPDHLkV1mLDoIP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HB}qgTw; literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.i.ia1.png b/textures/segment2/custom/font_graphics_jp.i.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..9cd00966f9996b8d87477f3a4fe04d344d055372 GIT binary patch literal 882 zcmV-&1C9KNP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HAW1|)RCwBBWPk!je2o7P4pu2fGzOGLVLIP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HB}qg6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HFiAu~RCwBBWPk!jER6q*XbdQg#`q6Z0b+m!8UI6#0E+x)V1%jxvmm;F1S4)s Y0RVsx5oRuA;{X5v07*qoM6N<$f?v0xaR2}S literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.l.ia1.png b/textures/segment2/custom/font_graphics_jp.l.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..ef259fd7d425986afdf7e318c2d22fd82d2d7c6e GIT binary patch literal 874 zcmV-w1C{)VP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*H7)eAyRCwBBWPk!jER6q*xEN5HTn27S0rhMO5i-K3&j0`b07*qoM6N<$f^*xM A761SM literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.m.ia1.png b/textures/segment2/custom/font_graphics_jp.m.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..bb2ee49b07419313cdc4c23eb0f292a31f5dce80 GIT binary patch literal 885 zcmV-*1B(2KP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HBS}O-RCwBBWPk!j@)-Xa|1*FPBg20n0`VCz5JU!6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HBuPX;RCwBBWPk!j@)-Xa|AV=V4F7=$NP!t3j9`FhR0eJX0h(tF5w3|H-2eap M07*qoM6N<$g5IP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HB}qg6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HCrLy>RCwBBWPk!jk{JJ?JjVY(@;{IXW-$CmV}NAP6f>YOFiZvj%3=%=qBMC_ P00000NkvXXu0mjf)xDnZ literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.q.ia1.png b/textures/segment2/custom/font_graphics_jp.q.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9bcc6cac288e81af6754a947fb0d20d5afa6b0 GIT binary patch literal 894 zcmV-^1A+XBP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HEJ;K`RCwBBWPk!j5*h!&6eGib5F5w<(QpO`BN$M%5bghg;t+E{iZM(E0NG;= U5nR9&D*ylh07*qoM6N<$f~5SO^#A|> literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.r.ia1.png b/textures/segment2/custom/font_graphics_jp.r.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..59764ce87d7f7e862f70244d15a7404a6000bd8b GIT binary patch literal 880 zcmV-$1CRWPP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*H9!W$&RCwBBWPk!j@)-Xa;f()a2_VIYA%)JsZ6E-nTn7<{HcmzW00006ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HB1uF+RCwBBWPk!jG8z9NT*m*52oXk@n*RtXAc0Vf+du$+SO*dLHgiq@0000< KMNUMnLSTZ78Juwd literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.t.ia1.png b/textures/segment2/custom/font_graphics_jp.t.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..04d87fbd62aee5d6770512f9f0f735a70da74f5f GIT binary patch literal 891 zcmV->1BCpEP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HDM>^@RCwBBWPk!jY>fYmXbcFA!hk4X{Lg?X#fW4M5P`U0WsJBj1ppCs3lSA5 RFEs!F002ovPDHLkV1oaDo_PQO literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.u.ia1.png b/textures/segment2/custom/font_graphics_jp.u.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..a2851a940de1a2cc469fb962368475d1bcdd501b GIT binary patch literal 884 zcmV-)1B?8LP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HB1uF+RCwBBWPk!jG8zAYY#?R?(RdjDfl7gj8NfU|1_A(>XABXR8#|8x0000< KMNUMnLSTYxc$)|S literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.v.ia1.png b/textures/segment2/custom/font_graphics_jp.v.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..368b2e4401fd0b250a0c6c5539cae648d0afa5cd GIT binary patch literal 885 zcmV-*1B(2KP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HBS}O-RCwBBWPk!j@)-X?Odx^E0AWTT2^Iu0AUdEDcnt&qQ)&tk=5AXE00000 LNkvXXu0mjf(sr3+ literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.w.ia1.png b/textures/segment2/custom/font_graphics_jp.w.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..3c913d8db101cae522748906980916ce609c6574 GIT binary patch literal 890 zcmV-=1BLvFP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HC`m*?RCwBBWPk!jG8z9t?Ej36Ao@QeoB?Jd82=$E{{wXZnRpBY0A=bB4njZ@ Q$^ZZW07*qoM6N<$f=kDq8~^|S literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.x.ia1.png b/textures/segment2/custom/font_graphics_jp.x.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..8d02012e2359613256a92f235cc6e4d27bfbae63 GIT binary patch literal 893 zcmV-@1A_dCP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HD@jB_RCwBBWPk!j@)-ZY?Ej363?SBjMiBQuSOF5_KSY-CKUggTBOU_*Dr5=~ TLjGy100000NkvXXu0mjfY5kyO literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.y.ia1.png b/textures/segment2/custom/font_graphics_jp.y.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..849b688dd0a37d8fec3c977b0638c165ee90cf0a GIT binary patch literal 889 zcmV-<1BU#GP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HCrLy>RCwBBWPk!jk{JI%Od!DsB2XD{DX0KQ3ZfS(0n!dN4AW!)7IF;{GnMVE P00000NkvXXu0mjfNq(EA literal 0 HcmV?d00001 diff --git a/textures/segment2/custom/font_graphics_jp.z.ia1.png b/textures/segment2/custom/font_graphics_jp.z.ia1.png new file mode 100644 index 0000000000000000000000000000000000000000..4c826466ebb0cd994d391124fa710a6f7a193195 GIT binary patch literal 887 zcmV--1Bm>IP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~IYDF%00001bW%=J06^y0 zW&i*HB}qgQe2B<@2;)D9WQ0&4HH=UxRK>{V002Ey2N6O8jX(eZ N002ovPDHLkV1j6_ocI6$ literal 0 HcmV?d00001 From 587addc465fd8729aff25484dd35768856021976 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Tue, 3 Jan 2023 01:42:56 -0500 Subject: [PATCH 10/14] get_string_width_preset, misc formatting --- bin/segment2.c | 2 +- src/extras/redone/title_screen.inc.c | 4 +-- src/game/ingame_menu.c | 49 ++++++++++++++++++++-------- src/game/ingame_menu.h | 13 +++++--- src/menu/file_select.c | 7 ++-- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/bin/segment2.c b/bin/segment2.c index 81f65bdf9..70ea22770 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -2282,7 +2282,7 @@ const struct DiacriticLUTEntry main_font_diacritic_lut[] = { [TEXT_DIACRITIC_CEDILLA] = { 0, 0, "¸"}, #if JAPANESE_CHARACTERS [TEXT_DIACRITIC_DAKUTEN] = { 4, 6, "゛"}, - [TEXT_DIACRITIC_HANDAKUTEN] = { 7, 10, "゜"}, + [TEXT_DIACRITIC_HANDAKUTEN] = { 7, 6, "゜"}, #endif }; diff --git a/src/extras/redone/title_screen.inc.c b/src/extras/redone/title_screen.inc.c index 2f55d661a..928e621e4 100644 --- a/src/extras/redone/title_screen.inc.c +++ b/src/extras/redone/title_screen.inc.c @@ -74,7 +74,7 @@ void print_debug_level_select_menu(struct ZDebugLevelSelect *this) { for (i = 0; i < MAX_PAGE_STRINGS; i++) { scene = (this->topDisplayedScene + i + this->count) % this->count; format_int_to_string(levelNumStr, scene + 1); - + if (scene == this->currentScene) { gDPSetEnvColor(gDisplayListHead++, 255, 126, 0, 255); } else { @@ -150,7 +150,7 @@ void print_debug_level_select_settings(struct ZDebugLevelSelect *this) { print_generic_string(20, 28, str); if (actName != NULL && courseNum >= COURSE_MIN && courseNum <= COURSE_STAGES_MAX) { - print_generic_string(100, 28, actName); + print_generic_string(20 + 8 + get_string_width_preset(chrTemp, STR_PRESET_MAIN_FONT), 28, actName); } chrTemp = "(C Down) - Show-Hide Controls"; diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index e31d4f642..168f8087e 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -128,7 +128,7 @@ static u8 sGenericFontLineAlignment = TEXT_ALIGN_LEFT; * MISCELLANEOUS * **************************************************/ -/* +/* * JP, EU and SH likes to use texture conversions from ia1 to ia8/ia4 respectively. * To still support these without altering the AsciiCharLUTEntry struct, * this look up table exists so that specific chars are only converted. @@ -145,7 +145,7 @@ u8 gCharTextureConvBool[] = { }; #endif -/* +/* * Vanilla course names has the course number on the same string. * Since the course number is now rendered separately, * there's no need to do that anymore. @@ -171,7 +171,7 @@ char *check_number_string_in_course_name(u8 *str) { str[2] == ' ') { return &str[3]; } - + return str; } @@ -183,7 +183,7 @@ char *check_number_string_in_course_name(u8 *str) { */ void captialize_first_character_only(char *str) { int i; - + //capitalize first character of words for(i=0; str[i]!='\0'; i++) { @@ -305,7 +305,7 @@ void create_dl_ortho_matrix(void) { /************************************************** * ASCII/UTF-8 UTILS * **************************************************/ - + /** * Determine which UTF-8 character to render, given a string and the current position in the string. * Returns the table entry of the relevant character. @@ -424,6 +424,27 @@ s32 get_string_width(char *str, struct AsciiCharLUTEntry *asciiLut, struct Utf8L return MAX(width, maxWidth); } +/** + * Get the exact width of the line of a string of any font in pixels, + * using presets that give fixed ASCII and UTF-8 tables. + */ +s32 get_string_width_preset(char *str, u16 preset) { + switch (preset) { + case STR_PRESET_HUD_FONT: + return get_string_width(str, main_hud_lut, &main_hud_utf8_lut); + case STR_PRESET_MAIN_FONT: + return get_string_width(str, main_font_lut, &main_font_utf8_lut); + case STR_PRESET_MENU_FONT: + return get_string_width(str, menu_font_lut, &menu_font_utf8_lut); +#if !CREDITS_TEXT_STRING_FONT + case STR_PRESET_CREDIT_FONT: + return get_string_width(str, main_credits_font_lut, NULL); +#endif + default: + return get_string_width(str, main_font_lut, &main_font_utf8_lut); + } +} + /** * Get the value to shift the X position of a string by, given a specific alignment. */ @@ -472,14 +493,14 @@ void format_int_to_string(char *buf, s32 value) { return; } #endif - // This is unreachable if JP or SH are defined + sprintf(buf, "%d", value); } /************************************************** * TEXTURE CONVERSION * **************************************************/ - + /** * Unpacks a packed I1 character texture into a usable IA8 texture when TEXT_FLAG_PACKED is used. * By default this is used for all the Japanese characters. @@ -565,7 +586,7 @@ static u32 render_generic_unicode_char(char *str, s32 *strPos) { if (utf8Entry->flags & TEXT_DIACRITIC_MASK) { struct DiacriticLUTEntry *diacriticLUT = segmented_to_virtual(&main_font_diacritic_lut); struct DiacriticLUTEntry *diacritic = &diacriticLUT[utf8Entry->flags & TEXT_DIACRITIC_MASK]; - + if (diacritic->xOffset | diacritic->yOffset) { create_dl_translation_matrix(MENU_MTX_PUSH, diacritic->xOffset, diacritic->yOffset, 0.0f); } @@ -607,8 +628,8 @@ static u32 render_generic_unicode_char(char *str, s32 *strPos) { * Prints a generic white string. Used for both dialog entries and regular prints. * Only prints a total of maxLines lines of text. If maxLines is -1, it will print * until the end of the string. - * - * Uses the global variables sGenericFontLineHeight and sGenericFontLineAlignment + * + * Uses the global variables sGenericFontLineHeight and sGenericFontLineAlignment * to control printing. */ static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { @@ -674,14 +695,14 @@ static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { strPos++; format_int_to_string(dialogVarText, gDialogVariable.asInt); render_main_font_text(0, 0, dialogVarText, -1); - kerning = get_string_width(dialogVarText, main_font_lut, &main_font_utf8_lut); + kerning = get_string_width_preset(dialogVarText, STR_PRESET_MAIN_FONT); create_dl_translation_matrix(MENU_MTX_NOPUSH, kerning, 0.0f, 0.0f); break; // %s: Display dialog var as a pointer to a string. } else if (str[strPos + 1] == 's') { strPos++; render_main_font_text(0, 0, gDialogVariable.asStr, -1); - kerning = get_string_width(gDialogVariable.asStr, main_font_lut, &main_font_utf8_lut); + kerning = get_string_width_preset(gDialogVariable.asStr, STR_PRESET_MAIN_FONT); create_dl_translation_matrix(MENU_MTX_NOPUSH, kerning, 0.0f, 0.0f); break; // %%: Special case, print only a single %. @@ -2171,7 +2192,7 @@ void render_course_complete_lvl_info_and_hud_str(void) { gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } else if (gLastCompletedCourseNum == COURSE_BITDW || gLastCompletedCourseNum == COURSE_BITFS) { // Bowser courses name = segmented_to_virtual(courseNameTbl[COURSE_NUM_TO_INDEX(gLastCompletedCourseNum)]); - u32 clearX = get_string_width(name, main_font_lut, &main_font_utf8_lut) + COURSE_COMPLETE_COURSE_X + 16; + u32 clearX = get_string_width_preset(name, STR_PRESET_MAIN_FONT) + COURSE_COMPLETE_COURSE_X + 16; // Print course name and clear text gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); @@ -2255,7 +2276,7 @@ void render_save_confirmation(s16 x, s16 y, s8 *index, s16 yPos) { // Save option strings are longer in French, so render them further to the left. #define SAVE_CONFIRMATION_X_EN 100 -#define SAVE_CONFIRMATION_X_FR 80 +#define SAVE_CONFIRMATION_X_FR 80 #ifdef ENABLE_FRENCH #define SAVE_CONFIRMATION_X ((gInGameLanguage == LANGUAGE_FRENCH) ? SAVE_CONFIRMATION_X_FR : SAVE_CONFIRMATION_X_EN) diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index c75a3b2f3..1da87bd79 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -103,12 +103,16 @@ enum TextAlignments { TEXT_ALIGN_RIGHT, }; -//#define TEXT_FLAG_PACKED_IA4 0x4000 // EU, has fonts flipped (Converts from IA1 to IA4) -//#define TEXT_FLAG_PACKED_IA8 0x8000 // JP, no fonts flipped (Converts from IA1 to IA8) -//#define TEXT_FLAG_PACKED_MASK (TEXT_FLAG_PACKED_IA4 | TEXT_FLAG_PACKED_IA8) +enum StringWidthPresets { + STR_PRESET_HUD_FONT, + STR_PRESET_MAIN_FONT, + STR_PRESET_MENU_FONT, + STR_PRESET_CREDIT_FONT, +}; + #define TEXT_FLAG_PACKED 0x8000 #define TEXT_DIACRITIC_MASK 0x00FF -// bits 0x0100 through 0x2000 are free for use, and the mask can be reduced if necessary +// bits 0x0100 through 0x4000 are free for use, and the mask can be reduced if necessary struct DialogEntry { /*0x00*/ s32 voice; @@ -182,6 +186,7 @@ void create_dl_ortho_matrix(void); void create_dl_scale_matrix(s8 pushOp, f32 x, f32 y, f32 z); s32 get_string_width(char *str, struct AsciiCharLUTEntry *asciiLut, struct Utf8LUT *utf8LUT); +s32 get_string_width_preset(char *str, u16 preset); void format_int_to_string(char *buf, s32 value); #define int_to_str(int, str) format_int_to_string(str, int); // backwards compatibility void print_generic_string(s16 x, s16 y, char *str); diff --git a/src/menu/file_select.c b/src/menu/file_select.c index c202f55b5..ad4e16187 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -1195,8 +1195,11 @@ void print_menu_cursor(void) { */ void string_format_file_letter(char *buf, char *str, s32 fileIndex) { char letterBuf[4]; -#ifdef ENABLE_JAPANESE - if (gInGameLanguage == LANGUAGE_JAPANESE) { +#if JAPANESE_CHARACTERS + #ifdef ENABLE_JAPANESE + if (gInGameLanguage == LANGUAGE_JAPANESE) + #endif + { // The UTF-8 encoding of "A" is 0xEF, 0xBC, 0xA1 letterBuf[0] = 0xEF; letterBuf[1] = 0xBC; From 3554891831586ca1dcd5291ec4fde15be79ba452 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Mon, 13 May 2024 01:20:26 -0500 Subject: [PATCH 11/14] remove textconv and unrelated changes --- src/game/hud.c | 2 +- src/game/ingame_menu.c | 2 +- src/game/save_file.h | 12 - src/menu/file_select.c | 4 +- src/menu/star_select.c | 62 +++-- src/menu/star_select.h | 4 + tools/hashtable.c | 89 ------- tools/textconv.c | 564 ----------------------------------------- tools/utf8.c | 74 ------ 9 files changed, 54 insertions(+), 759 deletions(-) delete mode 100644 tools/hashtable.c delete mode 100644 tools/textconv.c delete mode 100644 tools/utf8.c diff --git a/src/game/hud.c b/src/game/hud.c index 6cfde9fcd..fd2dc1c3a 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -354,7 +354,7 @@ void render_hud_keys(void) { void render_hud_timer(void) { u16 timerValFrames = gHudDisplay.timer; // 30 frames * 60 seconds (1 minute) = 1800 - u16 timerMins = timerValFrames / (30 * 60); + u16 timerMins = timerValFrames / 1800; u16 timerSecs = (timerValFrames - (timerMins * 1800)) / 30; u16 timerFracSecs = ((u16) (timerValFrames - (timerMins * 1800) - (timerSecs * 30))) / 3; #ifdef VERSION_CN diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 8206910ab..0606c77ae 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -1875,7 +1875,7 @@ void render_pause_castle_course_stars(s16 x, s16 y, s16 fileIndex, s16 courseInd u16 nextStar = 0; - if (starFlags & STAR_FLAG_ACT_100_COINS) { + if (starFlags & (1 << 6)) { starCount--; print_generic_string(x + 98, y, "★"); } diff --git a/src/game/save_file.h b/src/game/save_file.h index 36f315d26..93bcbd045 100644 --- a/src/game/save_file.h +++ b/src/game/save_file.h @@ -115,18 +115,6 @@ extern s8 gLevelToCourseNumTable[]; #define SAVE_FLAG_COLLECTED_MIPS_STAR_1 /* 0x08000000 */ (1 << 27) #define SAVE_FLAG_COLLECTED_MIPS_STAR_2 /* 0x10000000 */ (1 << 28) -enum StarFlags { - STAR_FLAGS_NONE = (0 << 0), // 0x00 - STAR_FLAG_ACT_1 = (1 << 0), // 0x01 - STAR_FLAG_ACT_2 = (1 << 1), // 0x02 - STAR_FLAG_ACT_3 = (1 << 2), // 0x04 - STAR_FLAG_ACT_4 = (1 << 3), // 0x08 - STAR_FLAG_ACT_5 = (1 << 4), // 0x10 - STAR_FLAG_ACT_6 = (1 << 5), // 0x20 - STAR_FLAG_ACT_100_COINS = (1 << 6), // 0x40 - STAR_FLAG_LAST = STAR_FLAG_ACT_100_COINS -}; - #define SAVE_FLAG_TO_STAR_FLAG(cmd) (((cmd) >> 24) & 0x7F) #define STAR_FLAG_TO_SAVE_FLAG(cmd) ((cmd) << 24) diff --git a/src/menu/file_select.c b/src/menu/file_select.c index c2a314bcd..3f4cef56f 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -2010,7 +2010,7 @@ void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s16 x, s1 sprintf(str, "✪×%s", coinScoreText); print_menu_generic_string(x + 25, y, str); // If collected, print 100 coin star - if (stars & STAR_FLAG_ACT_100_COINS) { + if (stars & (1 << 6)) { print_menu_generic_string(x + 70, y, "★"); } } @@ -2043,7 +2043,7 @@ void print_score_file_star_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { u8 stars = save_file_get_star_flags(fileIndex, courseIndex); s8 starCount = save_file_get_course_star_count(fileIndex, courseIndex); // Don't count 100 coin star - if (stars & STAR_FLAG_ACT_100_COINS) { + if (stars & (1 << 6)) { starCount--; } // Add 1 star character for every star collected diff --git a/src/menu/star_select.c b/src/menu/star_select.c index fcc925e0b..958d2841b 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -20,9 +20,6 @@ #include "game/main.h" // n64 #include // non-n64 -// from hackersm64 -#define o gCurrentObject - /** * @file star_select.c * This file implements how the star select screen (act selector) function. @@ -63,17 +60,17 @@ void bhv_act_selector_star_type_loop(void) { switch (gCurrentObject->oStarSelectorType) { // If a star is not selected, don't rotate or change size case STAR_SELECTOR_NOT_SELECTED: - gCurrentObject->oStarSelectorSize -= 0.1f; - if (gCurrentObject->oStarSelectorSize < 1.0f) { - gCurrentObject->oStarSelectorSize = 1.0f; + gCurrentObject->oStarSelectorSize -= 0.1; + if (gCurrentObject->oStarSelectorSize < 1.0) { + gCurrentObject->oStarSelectorSize = 1.0; } gCurrentObject->oFaceAngleYaw = 0; break; // If a star is selected, rotate and slightly increase size case STAR_SELECTOR_SELECTED: - gCurrentObject->oStarSelectorSize += 0.1f; - if (gCurrentObject->oStarSelectorSize > 1.3f) { - gCurrentObject->oStarSelectorSize = 1.3f; + gCurrentObject->oStarSelectorSize += 0.1; + if (gCurrentObject->oStarSelectorSize > 1.3) { + gCurrentObject->oStarSelectorSize = 1.3; } gCurrentObject->oFaceAngleYaw += 0x800; break; @@ -92,9 +89,9 @@ void bhv_act_selector_star_type_loop(void) { * Renders the 100 coin star with an special star selector type. */ void render_100_coin_star(u8 stars) { - if (stars & STAR_FLAG_ACT_100_COINS) { + if (stars & (1 << 6)) { // If the 100 coin star has been collected, create a new star selector next to the coin score. - sStarSelectorModels[6] = spawn_object_abs_with_rot(o, 0, MODEL_STAR, + sStarSelectorModels[6] = spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_STAR, bhvActSelectorStarType, 370, 24, -300, 0, 0, 0); sStarSelectorModels[6]->oStarSelectorSize = 0.8f; @@ -311,14 +308,29 @@ void print_act_selector_strings(void) { } gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_end); - } +} /** * Geo function that Print act selector strings. + *!@bug: This geo function is missing the third param. Harmless in practice due to o32 convention. */ -Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node, UNUSED void *context) { +#ifdef AVOID_UB +Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node, UNUSED void *context) +#else +Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node) +#endif +{ if (callContext == GEO_CONTEXT_RENDER) { +#ifdef TARGET_N3DS + gDPForceFlush(gDisplayListHead++); + gDPSet2d(gDisplayListHead++, 1); + gDPSetIod(gDisplayListHead++, iodStarSelect); +#endif print_act_selector_strings(); +#ifdef TARGET_N3DS + gDPForceFlush(gDisplayListHead++); + gDPSet2d(gDisplayListHead++, 0); +#endif } return NULL; } @@ -334,15 +346,22 @@ s32 lvl_init_act_selector_values_and_stars(UNUSED s32 arg, UNUSED s32 unused) { sInitSelectedActNum = 0; sVisibleStars = 0; sActSelectorMenuTimer = 0; +#ifdef NO_SEGMENTED_MEMORY + sSelectedActIndex = 0; + sSelectableStarIndex = 0; +#endif sObtainedStars = save_file_get_course_star_count(gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum)); // Don't count 100 coin star - if (stars & STAR_FLAG_ACT_100_COINS) { + if (stars & (1 << 6)) { sObtainedStars--; } + //! no return value +#ifdef AVOID_UB return 0; +#endif } /** @@ -352,9 +371,20 @@ s32 lvl_init_act_selector_values_and_stars(UNUSED s32 arg, UNUSED s32 unused) { s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused) { if (sActSelectorMenuTimer > 10) { // If any of these buttons are pressed, play sound and go to course act - if ((gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | B_BUTTON | Z_TRIG))) { +#if !QOL_FEATURE_Z_BUTTON_EXTRA_OPTION + if ((gPlayer3Controller->buttonPressed & A_BUTTON) + || (gPlayer3Controller->buttonPressed & START_BUTTON) + || (gPlayer3Controller->buttonPressed & B_BUTTON)) +#else + if ((gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | B_BUTTON | Z_TRIG))) +#endif + { +#ifdef VERSION_JP + play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); +#else play_sound(SOUND_MENU_STAR_SOUND_LETS_A_GO, gGlobalSoundSource); -#if ENABLE_RUMBLE +#endif +#ifdef RUMBLE_FEEDBACK queue_rumble_data(60, 70); queue_rumble_decay(1); #endif diff --git a/src/menu/star_select.h b/src/menu/star_select.h index 86cdd576b..d00afb1ab 100644 --- a/src/menu/star_select.h +++ b/src/menu/star_select.h @@ -12,7 +12,11 @@ enum StarSelectorTypes { STAR_SELECTOR_100_COINS }; +#ifdef AVOID_UB Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node, UNUSED void *context); +#else +Gfx *geo_act_selector_strings(s16 callContext, UNUSED struct GraphNode *node); +#endif s32 lvl_init_act_selector_values_and_stars(UNUSED s32 arg, UNUSED s32 unused); s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused); diff --git a/tools/hashtable.c b/tools/hashtable.c deleted file mode 100644 index 2c881c267..000000000 --- a/tools/hashtable.c +++ /dev/null @@ -1,89 +0,0 @@ -#include -#include -#include -#include - -#include "hashtable.h" - -struct HashNode -{ - struct HashNode *next; - uint8_t value[]; -}; - -struct HashTable -{ - HashFunc func; - HashValueCmpFunc cmp; - int size; - int elemSize; - struct HashNode *table[]; -}; - -struct HashTable *hashtable_new(HashFunc func, HashValueCmpFunc cmp, int size, - int elemSize) -{ - struct HashTable *ht = malloc(sizeof(*ht) + size * sizeof(ht->table[0])); - - ht->func = func; - ht->cmp = cmp; - ht->size = size; - ht->elemSize = elemSize; - memset(ht->table, 0, ht->size * sizeof(ht->table[0])); - return ht; -} - -void hashtable_free(struct HashTable *ht) -{ - int i; - - for (i = 0; i < ht->size; i++) - { - struct HashNode *node = ht->table[i]; - - while (node != NULL) - { - struct HashNode *next = node->next; - - free(node); - node = next; - } - } - free(ht); -} - -void hashtable_insert(struct HashTable *ht, const void *value) -{ - unsigned int key = ht->func(value) % ht->size; - struct HashNode *node = malloc(sizeof(*node) + ht->elemSize); - - node->next = NULL; - memcpy(node->value, value, ht->elemSize); - - if (ht->table[key] == NULL) - { - ht->table[key] = node; - } - else - { - struct HashNode *parent = ht->table[key]; - - while (parent->next != NULL) - parent = parent->next; - parent->next = node; - } -} - -void *hashtable_query(struct HashTable *ht, const void *value) -{ - unsigned int key = ht->func(value) % ht->size; - struct HashNode *node = ht->table[key]; - - while (node != NULL) - { - if (ht->cmp(node->value, value)) - return node->value; - node = node->next; - } - return NULL; -} diff --git a/tools/textconv.c b/tools/textconv.c deleted file mode 100644 index 53cb9a3c1..000000000 --- a/tools/textconv.c +++ /dev/null @@ -1,564 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "hashtable.h" -#include "utf8.h" - -#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0])) - -#define INVALID_CHAR 0xFFFFFFFF - -struct CharmapEntry -{ - uint32_t unicode[3]; - int length; // length of the unicode array. TODO: use dynamic memory allocation - int bytesCount; - uint8_t bytes[4]; // bytes to convert unicode array to, (e.g. 'A' = 0x0A) -}; - -static struct HashTable *charmap; - -static void fatal_error(const char *msgfmt, ...) -{ - va_list args; - - fputs("error: ", stderr); - - va_start(args, msgfmt); - vfprintf(stderr, msgfmt, args); - va_end(args); - - fputc('\n', stderr); - - exit(1); -} - -static void parse_error(const char *filename, int lineNum, const char *msgfmt, ...) -{ - va_list args; - - fprintf(stderr, "%s: line %i: ", filename, lineNum); - - va_start(args, msgfmt); - vfprintf(stderr, msgfmt, args); - va_end(args); - - fputc('\n', stderr); - - exit(1); -} - -// Reads the whole file and returns a null-terminated buffer with its contents -void *read_text_file(const char *filename) -{ - if (strcmp(filename, "-") != 0) - { - FILE *file = fopen(filename, "rb"); - uint8_t *buffer; - size_t size; - - if (file == NULL) - fatal_error("failed to open file '%s' for reading: %s", filename, strerror(errno)); - - // get size - fseek(file, 0, SEEK_END); - size = ftell(file); - - // allocate buffer - buffer = malloc(size + 1); - if (buffer == NULL) - fatal_error("could not allocate buffer of size %u", (uint32_t)(size + 1)); - - // read file - fseek(file, 0, SEEK_SET); - if (fread(buffer, size, 1, file) != 1) - fatal_error("error reading from file '%s': %s", filename, strerror(errno)); - - // null-terminate the buffer - buffer[size] = 0; - - fclose(file); - - return buffer; - } - else - { - size_t size = 0; - size_t capacity = 1024; - uint8_t *buffer = malloc(capacity + 1); - - if (buffer == NULL) - fatal_error("could not allocate buffer of size %u", (uint32_t)(capacity + 1)); - - for (;;) - { - size += fread(buffer + size, 1, capacity - size, stdin); - if (size == capacity) - { - capacity *= 2; - buffer = realloc(buffer, capacity + 1); - if (buffer == NULL) - fatal_error("could not allocate buffer of size %u", (uint32_t)(capacity + 1)); - } - else if (feof(stdin)) - { - break; - } - else - { - fatal_error("error reading from stdin: %s", strerror(errno)); - } - } - - // null-terminate the buffer - buffer[size] = 0; - return buffer; - } -} - -static char *skip_whitespace(char *str) -{ - while (isspace(*str)) - str++; - return str; -} - -// null terminates the current line and returns a pointer to the next line -static char *line_split(char *str) -{ - while (*str != '\n') - { - if (*str == 0) - return str; // end of string - str++; - } - *str = 0; // terminate line - return str + 1; -} - -static char *parse_number(const char *str, unsigned int *num) -{ - char *endptr; - unsigned int n = strtol(str, &endptr, 0); - - *num = n; - if (endptr > str) - return endptr; - else - return NULL; -} - -static int is_identifier_char(char c) -{ - return isalnum(c) || c == '_'; -} - -static uint32_t get_escape_char(int c) -{ - const uint8_t escapeTable[] = - { - ['0'] = '\0', - ['a'] = '\a', - ['b'] = '\b', - ['f'] = '\f', - ['n'] = '\n', - ['r'] = '\r', - ['t'] = '\t', - ['v'] = '\v', - ['\\'] = '\\', - ['\''] = '\'', - ['"'] = '"', - }; - - if ((unsigned int)c < ARRAY_COUNT(escapeTable) && (escapeTable[c] != 0 || c == '0')) - return escapeTable[c]; - else - return INVALID_CHAR; -} - -static void read_charmap(const char *filename) -{ - char *filedata = read_text_file(filename); - char *line = filedata; - int lineNum = 1; - - while (line[0] != 0) - { - char *nextLine = line_split(line); - - struct CharmapEntry entry; - struct CharmapEntry *existing; - - line = skip_whitespace(line); - if (line[0] != 0 && !(line[0] == '/' && line[1] == '/')) // ignore empty lines and comments - { - int len = 0; - /* Read Character */ - - // opening quote - if (*line != '\'') - parse_error(filename, lineNum, "expected '"); - line++; - - // perform analysis of charmap entry, we are in the quote - while(1) - { - if(*line == '\'') - { - line++; - break; - } - else if(len == ARRAY_COUNT(entry.unicode)) - { - // TODO: Use dynamic memory allocation so this is unnecessary. - parse_error(filename, lineNum, "string limit exceeded"); - } - else if (*line == '\\') - { - line++; // advance to get the character being escaped - if (*line == '\r') - line++; - if (*line == '\n') - { - // Backslash at end of line is ignored - continue; - } - entry.unicode[len] = get_escape_char(*line); - if (entry.unicode[len] == INVALID_CHAR) - parse_error(filename, lineNum, "unknown escape sequence \\%c", *line); - line++; // increment again to get past the escape sequence. - } - else - { - line = utf8_decode(line, &entry.unicode[len]); - if (line == NULL) - parse_error(filename, lineNum, "invalid UTF8"); - } - len++; - } - entry.length = len; - - // equals sign - line = skip_whitespace(line); - if (*line != '=') - parse_error(filename, lineNum, "expected = after character \\%c", *line); - line++; - - entry.bytesCount = 0; - - // value - while (1) - { - uint32_t value; - - if (entry.bytesCount >= 4) - parse_error(filename, lineNum, "more than 4 values specified"); - - line = skip_whitespace(line); - - line = parse_number(line, &value); - if (line == NULL) - parse_error(filename, lineNum, "expected number after ="); - if (value > 0xFF) - parse_error(filename, lineNum, "0x%X is larger than 1 byte", value); - - entry.bytes[entry.bytesCount] = value; - entry.bytesCount++; - - line = skip_whitespace(line); - if (*line == 0) - break; - if (*line != ',') - parse_error(filename, lineNum, "junk at end of line"); - line++; - } - - existing = hashtable_query(charmap, &entry); - - if (existing != NULL) { - const char *fmt = "0x%02X, "; - int fmtlen = 6; - - char str[32]; - int i; - - for (i = 0; i < existing->bytesCount; i++) { - sprintf(&str[fmtlen * i], fmt, existing->bytes[i]); - } - - str[fmtlen * i - 2] = '\0'; - - parse_error(filename, lineNum, "entry for character already exists (%s)", str); - } else { - hashtable_insert(charmap, &entry); - } - } - - line = nextLine; - lineNum++; - } - - free(filedata); -} - -static int count_line_num(const char *start, const char *pos) -{ - const char *c; - int lineNum = 1; - - for (c = start; c < pos; c++) - { - if (*c == '\n') - lineNum++; - } - return lineNum; -} - -static char *convert_string(char *pos, FILE *fout, const char *inputFileName, char *start, int uncompressed, int cnOneByte) -{ - const struct CharmapEntry terminatorInput = {.unicode = {'\0'}, .length = 1}; - struct CharmapEntry *terminator; - int hasString = 0; - int i; - - while (1) - { - pos = skip_whitespace(pos); - if (*pos == ')') - { - if (hasString) - break; - else - parse_error(inputFileName, count_line_num(start, pos), "expected quoted string after '_('"); - } - else if (*pos != '"') - parse_error(inputFileName, count_line_num(start, pos), "unexpected character '%c'", *pos); - pos++; - - hasString = 1; - - // convert quoted string - while (*pos != '"') - { - struct CharmapEntry input; - struct CharmapEntry *last_valid_entry = NULL; - struct CharmapEntry *entry; - uint32_t c; - int length = 0; - char* last_valid_pos = NULL; - // safely erase the unicode area before use - memset(input.unicode, 0, sizeof (input.unicode)); - input.length = 0; - - // Find a charmap entry of longest length possible starting from this position - while (*pos != '"') - { - if ((uncompressed && length == 1) || length == ARRAY_COUNT(entry->unicode)) - { - // Stop searching after length 3; we only support strings of lengths up - // to that right now. Unless uncompressed is set, in which we ignore multi - // texts by discarding entries longer than 1. - break; - } - - if (*pos == 0) - parse_error(inputFileName, count_line_num(start, pos), "EOF in string literal"); - if (*pos == '\\') - { - pos++; - c = get_escape_char(*pos); - if (c == INVALID_CHAR) - parse_error(inputFileName, count_line_num(start, pos), "unknown escape sequence \\%c", *pos); - input.unicode[length] = c; - pos++; - } - else - { - pos = utf8_decode(pos, &input.unicode[length]); - if (pos == NULL) - parse_error(inputFileName, count_line_num(start, pos), "invalid unicode encountered in file"); - } - length++; - input.length = length; - - entry = hashtable_query(charmap, &input); - if (entry != NULL) - { - last_valid_entry = entry; - last_valid_pos = pos; - } - } - - entry = last_valid_entry; - pos = last_valid_pos; - if (entry == NULL) - parse_error(inputFileName, count_line_num(start, pos), "no charmap entry for U+%X", input.unicode[0]); - for (i = 0; i < entry->bytesCount; i++) { - if (entry->bytesCount > 1 && cnOneByte && i % 2 == 0) { - continue; - } - fprintf(fout, "0x%02X,", entry->bytes[i]); - } - } - pos++; // skip over closing '"' - } - pos++; // skip over closing ')' - // use terminator \0 from charmap if provided, otherwise default 0xFF - terminator = hashtable_query(charmap, &terminatorInput); - if (terminator == NULL) - fputs("0xFF", fout); - else - { - for (i = 0; i < (cnOneByte ? 1 : terminator->bytesCount); i++) - fprintf(fout, "0x%02X,", terminator->bytes[i]); - } - return pos; -} - -static void convert_file(const char *infilename, const char *outfilename) -{ - char *in = read_text_file(infilename); - FILE *fout = strcmp(outfilename, "-") != 0 ? fopen(outfilename, "wb") : stdout; - - if (fout == NULL) - fatal_error("failed to open file '%s' for writing: %s", strerror(errno)); - - char *start = in; - char *end = in; - char *pos = in; - - while (1) - { - if (*pos == 0) // end of file - goto eof; - - // check for comment - if (*pos == '/') - { - pos++; - // skip over // comment - if (*pos == '/') - { - pos++; - // skip over next newline - while (*pos != '\n') - { - if (*pos == 0) - goto eof; - pos++; - } - pos++; - } - // skip over /* */ comment - else if (*pos == '*') - { - pos++; - while (*pos != '*' && pos[1] != '/') - { - if (*pos == 0) - goto eof; - pos++; - } - pos += 2; - } - } - // skip over normal string literal - else if (*pos == '"') - { - pos++; - while (*pos != '"') - { - if (*pos == 0) - goto eof; - if (*pos == '\\') - pos++; - pos++; - } - pos++; - } - // check for _( sequence - else if ((*pos == '_') && (pos == in || !is_identifier_char(pos[-1]))) - { - int uncompressed = 0; - int cnOneByte = 0; - end = pos; - pos++; - if (*pos == '_') // an extra _ signifies uncompressed strings. Enable uncompressed flag - { - pos++; - uncompressed = 1; - } - if (*pos == '%') // an extra % signifies a one-byte long characters on iQue instead of two-byte - { - pos++; - cnOneByte = 1; - } - if (*pos == '(') - { - pos++; - fwrite(start, end - start, 1, fout); - pos = convert_string(pos, fout, infilename, in, uncompressed, cnOneByte); - start = pos; - } - } - else - { - pos++; - } - } - - eof: - fwrite(start, pos - start, 1, fout); - if (strcmp(outfilename, "-") != 0) - fclose(fout); - free(in); -} - -static unsigned int charmap_hash(const void *value) -{ - const struct CharmapEntry* entry = value; - unsigned int ret = 0; - for (int i = 0; i < entry->length; i++) - ret = ret * 17 + entry->unicode[i]; - return ret; -} - -static int charmap_cmp(const void *a, const void *b) -{ - const struct CharmapEntry *ea = a; - const struct CharmapEntry *eb = b; - if (ea->length != eb->length) - return 0; - for(int i = 0; i < ea->length; i++) - if(ea->unicode[i] != eb->unicode[i]) - return 0; - return 1; -} - -static void usage(const char *execName) -{ - fprintf(stderr, "Usage: %s CHARMAP INPUT OUTPUT\n", execName); -} - -int main(int argc, char **argv) -{ - if (argc != 4) - { - usage(argv[0]); - return 1; - } - - charmap = hashtable_new(charmap_hash, charmap_cmp, 256, sizeof(struct CharmapEntry)); - - read_charmap(argv[1]); - convert_file(argv[2], argv[3]); - - hashtable_free(charmap); - - return 0; -} diff --git a/tools/utf8.c b/tools/utf8.c deleted file mode 100644 index 3d923c6db..000000000 --- a/tools/utf8.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include - -#include "utf8.h" - -/* Copyright (c) 2008-2009 Bjoern Hoehrmann - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define UTF8_ACCEPT 0 -#define UTF8_REJECT 1 - -static const uint8_t utf8d[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df - 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef - 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff - 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 - 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 - 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 - 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 -}; - -static uint32_t -decode(uint32_t* state, uint32_t* codep, uint32_t byte) { - uint32_t type = utf8d[byte]; - - *codep = (*state != UTF8_ACCEPT) ? - (byte & 0x3fu) | (*codep << 6) : - (0xff >> type) & (byte); - - *state = utf8d[256 + *state*16 + type]; - return *state; -} - -char *utf8_decode(char *str, uint32_t *codep) -{ - uint32_t state = UTF8_ACCEPT; - - *codep = 0; - while (*str != 0) - { - int result = decode(&state, codep, (unsigned char)*str); - str++; - if (result == UTF8_ACCEPT) - return str; - if (result == UTF8_REJECT) - return NULL; - } - return NULL; -} From 6e10e084ff06cf2a88e3ec865f7ae465258a5906 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Mon, 13 May 2024 11:33:57 -0500 Subject: [PATCH 12/14] Recover qol changes and renames --- src/extras/debug_menu.c | 4 +- src/extras/options_menu.c | 2 +- src/game/ingame_menu.c | 217 +++++++++++++++++++++++--------------- 3 files changed, 134 insertions(+), 89 deletions(-) diff --git a/src/extras/debug_menu.c b/src/extras/debug_menu.c index 5ab0170cf..2617b2d90 100644 --- a/src/extras/debug_menu.c +++ b/src/extras/debug_menu.c @@ -30,7 +30,7 @@ extern bool gShowDebugText; extern bool gDebugLevelSelect; extern bool gShowProfiler; extern s16 gMenuMode; -extern s8 gDialogBoxState; +extern s8 gMenuState; extern struct CreditsEntry sCreditsSequence[]; extern void try_modify_debug_controls(void); extern void try_change_debug_page(void); @@ -67,7 +67,7 @@ static void force_quit_pause_debug(void) { level_set_transition(0, NULL); optmenu_open = 0; gMenuMode = -1; - gDialogBoxState = 0; + gMenuState = 0; raise_background_noise(1); gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; set_play_mode(0); diff --git a/src/extras/options_menu.c b/src/extras/options_menu.c index 0419d52dc..e1651f9af 100644 --- a/src/extras/options_menu.c +++ b/src/extras/options_menu.c @@ -378,7 +378,7 @@ static void optmenu_draw_opt(const struct Option *opt, s16 x, s16 y, u8 sel, s16 else optmenu_draw_text(x, y-13, optBindStr[0], white); } else { - sprintf(buf, "%04x", opt->uval[i]); + sprintf(buf, "%04X", opt->uval[i]); optmenu_draw_text(x, y-13, buf, white); } } diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 0606c77ae..a7ca83507 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -25,6 +25,10 @@ #include "main.h" // n64 #include // non-n64 +#ifdef CHEATS_ACTIONS +#include "extras/cheats.h" +#endif + #ifdef EXT_OPTIONS_MENU #include "extras/options_menu.h" #endif @@ -92,33 +96,49 @@ void *languageTable[][3] = { extern u8 gLastCompletedCourseNum; extern u8 gLastCompletedStarNum; -enum DialogBoxState { - DIALOG_STATE_OPENING, - DIALOG_STATE_VERTICAL, - DIALOG_STATE_HORIZONTAL, - DIALOG_STATE_CLOSING -}; - enum DialogBoxType { DIALOG_TYPE_ROTATE, // used in NPCs and level messages DIALOG_TYPE_ZOOM // used in signposts and wall signs and etc }; -#define DEFAULT_DIALOG_BOX_ANGLE 90.0f -#define DEFAULT_DIALOG_BOX_SCALE 19.0f +enum MenuState { + MENU_STATE_0, + MENU_STATE_1, + MENU_STATE_2, + MENU_STATE_3, + MENU_STATE_DEFAULT = MENU_STATE_0, + + // Dialog + MENU_STATE_DIALOG_OPENING = MENU_STATE_0, + MENU_STATE_DIALOG_OPEN = MENU_STATE_1, + MENU_STATE_DIALOG_SCROLLING = MENU_STATE_2, + MENU_STATE_DIALOG_CLOSING = MENU_STATE_3, + + // Pause Screen + MENU_STATE_PAUSE_SCREEN_OPENING = MENU_STATE_0, + MENU_STATE_PAUSE_SCREEN_COURSE = MENU_STATE_1, + MENU_STATE_PAUSE_SCREEN_CASTLE = MENU_STATE_2, + + // Course Complete Screen + MENU_STATE_COURSE_COMPLETE_SCREEN_OPENING = MENU_STATE_0, + MENU_STATE_COURSE_COMPLETE_SCREEN_OPEN = MENU_STATE_1 +}; + +#define DIALOG_BOX_ANGLE_DEFAULT 90.0f +#define DIALOG_BOX_SCALE_DEFAULT 19.0f -s8 gDialogBoxState = DIALOG_STATE_OPENING; s8 gDialogBoxType = DIALOG_TYPE_ROTATE; s8 gDialogHasResponse = FALSE; u8 gMenuHoldKeyIndex = 0; u8 gMenuHoldKeyTimer = 0; s8 gMenuLineNum = 1; +s8 gMenuState = MENU_STATE_DEFAULT; s16 gDialogScrollOffsetY = 0; s16 gDialogID = DIALOG_NONE; s16 gLastDialogPageStrPos = 0; s16 gDialogTextPos = 0; -f32 gDialogBoxOpenTimer = DEFAULT_DIALOG_BOX_ANGLE; -f32 gDialogBoxScale = DEFAULT_DIALOG_BOX_SCALE; +f32 gDialogBoxAngle = DIALOG_BOX_ANGLE_DEFAULT; +f32 gDialogBoxScale = DIALOG_BOX_SCALE_DEFAULT; s32 gDialogResponse = DIALOG_RESPONSE_NONE; /* @@ -968,36 +988,39 @@ void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8 u8 index = 0; if (scrollDirection == MENU_SCROLL_VERTICAL) { - if ((gPlayer3Controller->rawStickY > 60) || (gPlayer3Controller->buttonDown & (U_CBUTTONS | U_JPAD))) index++; - if ((gPlayer3Controller->rawStickY < -60) || (gPlayer3Controller->buttonDown & (D_CBUTTONS | D_JPAD))) index += 2; + if (gPlayer3Controller->rawStickY > 60) index |= 0b01; // Up + if (gPlayer3Controller->rawStickY < -60) index |= 0b10; // Down } else if (scrollDirection == MENU_SCROLL_HORIZONTAL) { - if ((gPlayer3Controller->rawStickX > 60) || (gPlayer3Controller->buttonDown & (R_CBUTTONS | R_JPAD))) index += 2; - if ((gPlayer3Controller->rawStickX < -60) || (gPlayer3Controller->buttonDown & (L_CBUTTONS | L_JPAD))) index++; + if (gPlayer3Controller->rawStickX > 60) index |= 0b10; // Right + if (gPlayer3Controller->rawStickX < -60) index |= 0b01; // Left } - if (((index ^ gMenuHoldKeyIndex) & index) == 2) { + // Only increase/decrese if not holding that direction on the previous frame: + if (((index ^ gMenuHoldKeyIndex) & index) == 0b10) { if (*currentIndex != maxIndex) { play_sound(SOUND_MENU_CHANGE_SELECT, gGlobalSoundSource); (*currentIndex)++; } } - if (((index ^ gMenuHoldKeyIndex) & index) == 1) { + if (((index ^ gMenuHoldKeyIndex) & index) == 0b01) { if (*currentIndex != minIndex) { play_sound(SOUND_MENU_CHANGE_SELECT, gGlobalSoundSource); (*currentIndex)--; } } + // If there has been input for 10 frames, set the timer to 8 and set gMenuHoldKeyIndex to 0 so the above becomes true. if (gMenuHoldKeyTimer == 10) { gMenuHoldKeyTimer = 8; - gMenuHoldKeyIndex = 0; + gMenuHoldKeyIndex = 0b00; } else { + // Otherwise, increment the timer while there is input. gMenuHoldKeyTimer++; gMenuHoldKeyIndex = index; } - if ((index & 3) == 0) { + if (index == 0) { gMenuHoldKeyTimer = 0; } } @@ -1093,9 +1116,9 @@ void create_dialog_box_with_response(s16 dialog) { void reset_dialog_render_state(void) { level_set_transition(0, NULL); - gDialogBoxScale = 19.0f; - gDialogBoxOpenTimer = 90.0f; - gDialogBoxState = DIALOG_STATE_OPENING; + gDialogBoxScale = DIALOG_BOX_SCALE_DEFAULT; + gDialogBoxAngle = DIALOG_BOX_ANGLE_DEFAULT; + gMenuState = MENU_STATE_DEFAULT; gDialogID = DIALOG_NONE; gDialogTextPos = 0; gDialogHasResponse = FALSE; @@ -1108,16 +1131,15 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) { switch (gDialogBoxType) { case DIALOG_TYPE_ROTATE: // Renders a dialog black box with zoom and rotation - if ((gDialogBoxState == DIALOG_STATE_OPENING) - || (gDialogBoxState == DIALOG_STATE_CLOSING)) { + if (gMenuState == MENU_STATE_DIALOG_OPENING || gMenuState == MENU_STATE_DIALOG_CLOSING) { create_dl_scale_matrix(MENU_MTX_NOPUSH, (1.0f / gDialogBoxScale), (1.0f / gDialogBoxScale), 1.0f); // convert the speed into angle - create_dl_rotation_matrix(MENU_MTX_NOPUSH, (gDialogBoxOpenTimer * 4.0f), 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, (gDialogBoxAngle * 4.0f), 0, 0, 1.0f); } gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 150); break; case DIALOG_TYPE_ZOOM: // Renders a dialog white box with zoom - if (gDialogBoxState == DIALOG_STATE_OPENING || gDialogBoxState == DIALOG_STATE_CLOSING) { + if (gMenuState == MENU_STATE_DIALOG_OPENING || gMenuState == MENU_STATE_DIALOG_CLOSING) { create_dl_translation_matrix(MENU_MTX_NOPUSH, (65.0f - (65.0f / gDialogBoxScale)), ((40.0f / gDialogBoxScale) - 40), 0); create_dl_scale_matrix(MENU_MTX_NOPUSH, (1.0f / gDialogBoxScale), (1.0f / gDialogBoxScale), 1.0f); } @@ -1142,7 +1164,7 @@ static void handle_dialog_text_and_pages(struct DialogEntry *dialog) { s32 printResult; s16 yPos = 2 - DIALOG_LINE_HEIGHT; - if (gDialogBoxState == DIALOG_STATE_HORIZONTAL) { + if (gMenuState == MENU_STATE_DIALOG_SCROLLING) { // If scrolling, consider the number of lines for both // the current page and the page being scrolled to. totalLines = dialog->linesPerBox * 2; @@ -1161,7 +1183,7 @@ static void handle_dialog_text_and_pages(struct DialogEntry *dialog) { } /* - if (gDialogBoxState == DIALOG_STATE_OPENING) { + if (gMenuState == MENU_STATE_DIALOG_OPEN) { bcopy(sActiveTextColor, gDialogCarryoverColor, sizeof(gDialogCarryoverColor)); } else { // Deliberately not using set_text_color here, as gDialogCarryoverColor isn't @@ -1176,7 +1198,7 @@ static void handle_dialog_text_and_pages(struct DialogEntry *dialog) { gSPDisplayList(gDisplayListHead++, dl_ia_text_end); - if (gDialogBoxState == DIALOG_STATE_VERTICAL) { + if (gMenuState == MENU_STATE_DIALOG_OPEN) { if (printResult == -1) { // Reached end of dialog box gLastDialogPageStrPos = -1; } else { @@ -1186,7 +1208,7 @@ static void handle_dialog_text_and_pages(struct DialogEntry *dialog) { } void render_dialog_triangle_choice(void) { - if (gDialogBoxState == DIALOG_STATE_VERTICAL) { + if (gMenuState == MENU_STATE_DIALOG_OPEN) { handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, &gMenuLineNum, 1, 2); } @@ -1210,7 +1232,7 @@ void render_dialog_triangle_next(s8 linesPerBox) { create_dl_translation_matrix(MENU_MTX_PUSH, 118.f, (linesPerBox * -DIALOG_LINE_HEIGHT) + 5, 0); create_dl_scale_matrix(MENU_MTX_NOPUSH, 0.8f, 0.8f, 1.0f); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, -DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, -90.0f, 0, 0, 1.0f); if (gDialogBoxType == DIALOG_TYPE_ROTATE) { // White Text gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); @@ -1349,63 +1371,63 @@ void render_dialog_entries(void) { return; } - switch (gDialogBoxState) { - case DIALOG_STATE_OPENING: - if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) { + switch (gMenuState) { + case MENU_STATE_DIALOG_OPENING: + if (gDialogBoxAngle == DIALOG_BOX_ANGLE_DEFAULT) { play_dialog_sound(gDialogID); play_sound(SOUND_MENU_MESSAGE_APPEAR, gGlobalSoundSource); } if (gDialogBoxType == DIALOG_TYPE_ROTATE) { - gDialogBoxOpenTimer -= 7.5f; + gDialogBoxAngle -= 7.5f; gDialogBoxScale -= 1.5f; } else { - gDialogBoxOpenTimer -= 10.0f; + gDialogBoxAngle -= 10.0f; gDialogBoxScale -= 2.0f; } - if (gDialogBoxOpenTimer == 0.0f) { - gDialogBoxState = DIALOG_STATE_VERTICAL; + if (gDialogBoxAngle == 0.0f) { + gMenuState = MENU_STATE_DIALOG_OPEN; gMenuLineNum = 1; } break; - case DIALOG_STATE_VERTICAL: - gDialogBoxOpenTimer = 0.0f; + case MENU_STATE_DIALOG_OPEN: + gDialogBoxAngle = 0.0f; - if (gPlayer3Controller->buttonPressed & (A_BUTTON | B_BUTTON | START_BUTTON | D_CBUTTONS | R_CBUTTONS | D_JPAD | R_JPAD)) { + if (gPlayer3Controller->buttonPressed & (A_BUTTON | B_BUTTON)) { if (gLastDialogPageStrPos == -1) { handle_special_dialog_text(gDialogID); - gDialogBoxState = DIALOG_STATE_CLOSING; + gMenuState = MENU_STATE_DIALOG_CLOSING; } else { - gDialogBoxState = DIALOG_STATE_HORIZONTAL; + gMenuState = MENU_STATE_DIALOG_SCROLLING; play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, gGlobalSoundSource); } } break; - case DIALOG_STATE_HORIZONTAL: // scrolling + case MENU_STATE_DIALOG_SCROLLING: gDialogScrollOffsetY += (dialog->linesPerBox * 2); if (gDialogScrollOffsetY >= dialog->linesPerBox * DIALOG_LINE_HEIGHT) { gDialogTextPos = gLastDialogPageStrPos; - gDialogBoxState = DIALOG_STATE_VERTICAL; + gMenuState = MENU_STATE_DIALOG_OPEN; gDialogScrollOffsetY = 0; } break; - case DIALOG_STATE_CLOSING: - if (gDialogBoxOpenTimer == 20.0f) { + case MENU_STATE_DIALOG_CLOSING: + if (gDialogBoxAngle == 20.0f) { level_set_transition(0, NULL); play_sound(SOUND_MENU_MESSAGE_DISAPPEAR, gGlobalSoundSource); gDialogResponse = gMenuLineNum; } - gDialogBoxOpenTimer = gDialogBoxOpenTimer + 10.0f; + gDialogBoxAngle = gDialogBoxAngle + 10.0f; gDialogBoxScale = gDialogBoxScale + 2.0f; - if (gDialogBoxOpenTimer == DEFAULT_DIALOG_BOX_ANGLE) { - gDialogBoxState = DIALOG_STATE_OPENING; + if (gDialogBoxAngle == DIALOG_BOX_ANGLE_DEFAULT) { + gMenuState = MENU_STATE_DEFAULT; gDialogID = DIALOG_NONE; gDialogTextPos = 0; gDialogHasResponse = FALSE; @@ -1429,7 +1451,7 @@ void render_dialog_entries(void) { render_dialog_triangle_choice(); } gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 2, 2, SCREEN_WIDTH - BORDER_HEIGHT / 2, SCREEN_HEIGHT - BORDER_HEIGHT / 2); - if (gLastDialogPageStrPos != -1 && gDialogBoxState == DIALOG_STATE_VERTICAL) { + if (gLastDialogPageStrPos != -1 && gMenuState == MENU_STATE_DIALOG_OPEN) { render_dialog_triangle_next(dialog->linesPerBox); } } @@ -1585,12 +1607,12 @@ void render_hud_cannon_reticle(void) { gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); create_dl_translation_matrix(MENU_MTX_PUSH, 8.0f, -20.0f, 0); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, 90.0f, 0, 0, 1.0f); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); create_dl_translation_matrix(MENU_MTX_PUSH, -8.0f, 20.0f, 0); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, -DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, -90.0f, 0, 0, 1.0f); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); @@ -1827,7 +1849,7 @@ void render_pause_castle_menu_box(s16 x, s16 y) { gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); create_dl_translation_matrix(MENU_MTX_PUSH, x + 6, y - 28, 0); - create_dl_rotation_matrix(MENU_MTX_NOPUSH, DEFAULT_DIALOG_BOX_ANGLE, 0, 0, 1.0f); + create_dl_rotation_matrix(MENU_MTX_NOPUSH, 90.0f, 0, 0, 1.0f); gDPPipeSync(gDisplayListHead++); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gSPDisplayList(gDisplayListHead++, dl_draw_triangle); @@ -1984,7 +2006,7 @@ void render_pause_castle_main_strings(s16 x, s16 y) { } s8 gCourseCompleteCoinsEqual = FALSE; -s32 gCourseDoneMenuTimer = 0; +s32 gCourseCompleteScreenTimer = 0; s32 gCourseCompleteCoins = 0; s8 gHudFlash = HUD_FLASH_NONE; @@ -1994,8 +2016,8 @@ s32 render_pause_courses_and_castle(void) { #ifdef EXT_OPTIONS_MENU if (optmenu_open == 0) { #endif - switch (gDialogBoxState) { - case DIALOG_STATE_OPENING: + switch (gMenuState) { + case MENU_STATE_PAUSE_SCREEN_OPENING: gMenuLineNum = MENU_OPT_DEFAULT; gDialogTextAlpha = 0; level_set_transition(-1, NULL); @@ -2004,32 +2026,40 @@ s32 render_pause_courses_and_castle(void) { if (gCurrCourseNum >= COURSE_MIN && gCurrCourseNum <= COURSE_MAX) { change_dialog_camera_angle(); - gDialogBoxState = DIALOG_STATE_VERTICAL; + gMenuState = MENU_STATE_PAUSE_SCREEN_COURSE; } else { highlight_last_course_complete_stars(); - gDialogBoxState = DIALOG_STATE_HORIZONTAL; + gMenuState = MENU_STATE_PAUSE_SCREEN_CASTLE; } break; - case DIALOG_STATE_VERTICAL: + case MENU_STATE_PAUSE_SCREEN_COURSE: shade_screen(); render_pause_my_score_coins(); render_pause_red_coins(); -#ifndef DISABLE_EXIT_COURSE -#ifdef EXIT_COURSE_WHILE_MOVING - if ((gMarioStates[0].action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER | ACT_FLAG_PAUSE_EXIT)) - || (gMarioStates[0].pos[1] <= gMarioStates[0].floorHeight)) { -#else - if (gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) { + +#if !EXIT_COURSE_ANYWHERE +/* Added support for the "Exit course at any time" cheat */ + if ((gMarioStates[0].action & ACT_FLAG_PAUSE_EXIT) +#ifdef CHEATS_ACTIONS + || (Cheats.EnableCheats && Cheats.ExitAnywhere) #endif - render_pause_course_options(109, 91, &gMenuLineNum, 15); + ) { + render_pause_course_options(99, 93, &gMenuLineNum, 15); } #endif - if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON)) { +#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION + if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | Z_TRIG)) +#else + if (gPlayer3Controller->buttonPressed & A_BUTTON + || (gPlayer3Controller->buttonPressed & START_BUTTON)) +#endif + { + level_set_transition(0, NULL); play_sound(SOUND_MENU_PAUSE_CLOSE, gGlobalSoundSource); - gDialogBoxState = DIALOG_STATE_OPENING; + gMenuState = MENU_STATE_DEFAULT; gMenuMode = MENU_MODE_NONE; if (gMenuLineNum == MENU_OPT_EXIT_COURSE) { @@ -2042,17 +2072,23 @@ s32 render_pause_courses_and_castle(void) { } break; - case DIALOG_STATE_HORIZONTAL: + case MENU_STATE_PAUSE_SCREEN_CASTLE: shade_screen(); print_hud_pause_colorful_str(); render_pause_castle_menu_box(160, 143); render_pause_castle_main_strings(SCREEN_CENTER_X, 55); - if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | Z_TRIG)) { +#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION + if (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON | Z_TRIG)) +#else + if ((gPlayer3Controller->buttonPressed & A_BUTTON) + || (gPlayer3Controller->buttonPressed & START_BUTTON)) +#endif + { level_set_transition(0, NULL); play_sound(SOUND_MENU_PAUSE_CLOSE, gGlobalSoundSource); gMenuMode = MENU_MODE_NONE; - gDialogBoxState = DIALOG_STATE_OPENING; + gMenuState = MENU_STATE_DEFAULT; return MENU_OPT_DEFAULT; } @@ -2144,16 +2180,19 @@ void print_hud_course_complete_coins(s16 x, s16 y) { print_hud_course_complete_string(HUD_PRINT_HISCORE); } } else { - if ((gCourseDoneMenuTimer & 1) || gHudDisplay.coins > 70) { + if ((gCourseCompleteScreenTimer & 1) || gHudDisplay.coins > 70) { gCourseCompleteCoins++; play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gGlobalSoundSource); -#ifdef ENABLE_LIVES - if (gCourseCompleteCoins && ((gCourseCompleteCoins % 50) == 0)) { +#if QOL_FIX_COMPLETE_COURSE_50_COINS + if (gCourseCompleteCoins % 50 == 0) +#else + if (gCourseCompleteCoins == 50 || gCourseCompleteCoins == 100 || gCourseCompleteCoins == 150) +#endif + { play_sound(SOUND_GENERAL_COLLECT_1UP, gGlobalSoundSource); gMarioState->numLives++; } -#endif } if (gHudDisplay.coins == gCourseCompleteCoins && gGotFileCoinHiScore) { @@ -2313,28 +2352,34 @@ void render_save_confirmation(s16 x, s16 y, s8 *index, s16 yPos) { #endif s32 render_course_complete_screen(void) { - switch (gDialogBoxState) { - case DIALOG_STATE_OPENING: + switch (gMenuState) { + case MENU_STATE_COURSE_COMPLETE_SCREEN_OPENING: render_course_complete_lvl_info_and_hud_str(); - if (gCourseDoneMenuTimer > 100 && gCourseCompleteCoinsEqual) { - gDialogBoxState = DIALOG_STATE_VERTICAL; + if (gCourseCompleteScreenTimer > 100 && gCourseCompleteCoinsEqual) { + gMenuState = MENU_STATE_COURSE_COMPLETE_SCREEN_OPEN; level_set_transition(-1, NULL); gDialogTextAlpha = 0; gMenuLineNum = MENU_OPT_DEFAULT; } break; - case DIALOG_STATE_VERTICAL: + case MENU_STATE_COURSE_COMPLETE_SCREEN_OPEN: shade_screen(); render_course_complete_lvl_info_and_hud_str(); render_save_confirmation(SAVE_CONFIRMATION_X, 86, &gMenuLineNum, 20); - if (gCourseDoneMenuTimer > 110 && (gPlayer3Controller->buttonPressed & (A_BUTTON | START_BUTTON))) { + if (gCourseCompleteScreenTimer > 110 + && (gPlayer3Controller->buttonPressed & A_BUTTON + || gPlayer3Controller->buttonPressed & START_BUTTON +#if QOL_FEATURE_Z_BUTTON_EXTRA_OPTION + || gPlayer3Controller->buttonPressed & Z_TRIG +#endif + )) { level_set_transition(0, NULL); play_sound(SOUND_MENU_STAR_SOUND, gGlobalSoundSource); - gDialogBoxState = DIALOG_STATE_OPENING; + gMenuState = MENU_STATE_DEFAULT; gMenuMode = MENU_MODE_NONE; - gCourseDoneMenuTimer = 0; + gCourseCompleteScreenTimer = 0; gCourseCompleteCoins = 0; gCourseCompleteCoinsEqual = FALSE; gHudFlash = HUD_FLASH_NONE; @@ -2348,7 +2393,7 @@ s32 render_course_complete_screen(void) { gDialogTextAlpha += 25; } - gCourseDoneMenuTimer++; + gCourseCompleteScreenTimer++; return MENU_OPT_NONE; } From 2aaa6d05665ea95b1aaa29b9feb0e33dbd26e86d Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Mon, 13 May 2024 14:20:10 -0500 Subject: [PATCH 13/14] Consistent text preset names, use strcat to show star strings --- src/extras/redone/title_screen.inc.c | 2 +- src/game/ingame_menu.c | 24 +++++++++++++++--------- src/game/ingame_menu.h | 10 +++++----- src/menu/file_select.c | 13 ++++++++----- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/extras/redone/title_screen.inc.c b/src/extras/redone/title_screen.inc.c index fb89e18f7..1ddbfdae1 100644 --- a/src/extras/redone/title_screen.inc.c +++ b/src/extras/redone/title_screen.inc.c @@ -154,7 +154,7 @@ void print_debug_level_select_settings(struct ZDebugLevelSelect *this) { print_generic_string(20, 28, str); if (actName != NULL && courseNum >= COURSE_MIN && courseNum <= COURSE_STAGES_MAX) { - print_generic_string(20 + 8 + get_string_width_preset(chrTemp, STR_PRESET_MAIN_FONT), 28, actName); + print_generic_string(20 + 8 + get_string_width_preset(chrTemp, TEXT_PRESET_MAIN_FONT), 28, actName); } chrTemp = "(C Down) - Show-Hide Controls"; diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index a7ca83507..b4b095423 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -24,6 +24,7 @@ #include "config.h" #include "main.h" // n64 #include // non-n64 +#include // non-n64 #ifdef CHEATS_ACTIONS #include "extras/cheats.h" @@ -457,14 +458,14 @@ s32 get_string_width(char *str, struct AsciiCharLUTEntry *asciiLut, struct Utf8L */ s32 get_string_width_preset(char *str, u16 preset) { switch (preset) { - case STR_PRESET_HUD_FONT: + case TEXT_PRESET_HUD_FONT: return get_string_width(str, main_hud_lut, &main_hud_utf8_lut); - case STR_PRESET_MAIN_FONT: + case TEXT_PRESET_MAIN_FONT: return get_string_width(str, main_font_lut, &main_font_utf8_lut); - case STR_PRESET_MENU_FONT: + case TEXT_PRESET_MENU_FONT: return get_string_width(str, menu_font_lut, &menu_font_utf8_lut); #if !CREDITS_TEXT_STRING_FONT - case STR_PRESET_CREDIT_FONT: + case TEXT_PRESET_CREDIT_FONT: return get_string_width(str, main_credits_font_lut, NULL); #endif default: @@ -722,14 +723,14 @@ static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { strPos++; format_int_to_string(dialogVarText, gDialogVariable.asInt); render_main_font_text(0, 0, dialogVarText, -1); - kerning = get_string_width_preset(dialogVarText, STR_PRESET_MAIN_FONT); + kerning = get_string_width_preset(dialogVarText, TEXT_PRESET_MAIN_FONT); create_dl_translation_matrix(MENU_MTX_NOPUSH, kerning, 0.0f, 0.0f); break; // %s: Display dialog var as a pointer to a string. } else if (str[strPos + 1] == 's') { strPos++; render_main_font_text(0, 0, gDialogVariable.asStr, -1); - kerning = get_string_width_preset(gDialogVariable.asStr, STR_PRESET_MAIN_FONT); + kerning = get_string_width_preset(gDialogVariable.asStr, TEXT_PRESET_MAIN_FONT); create_dl_translation_matrix(MENU_MTX_NOPUSH, kerning, 0.0f, 0.0f); break; // %%: Special case, print only a single %. @@ -1889,8 +1890,9 @@ void print_hud_pause_colorful_str(void) { void render_pause_castle_course_stars(s16 x, s16 y, s16 fileIndex, s16 courseIndex) { s16 hasStar = 0; - char str[30]; + char str[30] = {'\0'}; char *entries[6]; + int i; u8 starFlags = save_file_get_star_flags(fileIndex, courseIndex); u16 starCount = save_file_get_course_star_count(fileIndex, courseIndex); @@ -1921,7 +1923,11 @@ void render_pause_castle_course_stars(s16 x, s16 y, s16 fileIndex, s16 courseInd nextStar++; } - sprintf(str, "%s %s %s %s %s %s", entries[0], entries[1], entries[2], entries[3], entries[4], entries[5]); + for (i = 0; i < 6; i++) { + strcat(str, entries[i]); + if (i < 5) strcat(str, " "); + } + print_generic_string(x + 23, y + 18, str); } @@ -2259,7 +2265,7 @@ void render_course_complete_lvl_info_and_hud_str(void) { gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } else if (gLastCompletedCourseNum == COURSE_BITDW || gLastCompletedCourseNum == COURSE_BITFS) { // Bowser courses name = segmented_to_virtual(courseNameTbl[COURSE_NUM_TO_INDEX(gLastCompletedCourseNum)]); - u32 clearX = get_string_width_preset(name, STR_PRESET_MAIN_FONT) + COURSE_COMPLETE_COURSE_X + 16; + u32 clearX = get_string_width_preset(name, TEXT_PRESET_MAIN_FONT) + COURSE_COMPLETE_COURSE_X + 16; // Print course name and clear text gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index 304d17c4d..266c7e7b2 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -103,11 +103,11 @@ enum TextAlignments { TEXT_ALIGN_RIGHT, }; -enum StringWidthPresets { - STR_PRESET_HUD_FONT, - STR_PRESET_MAIN_FONT, - STR_PRESET_MENU_FONT, - STR_PRESET_CREDIT_FONT, +enum TextFontPresets { + TEXT_PRESET_HUD_FONT, + TEXT_PRESET_MAIN_FONT, + TEXT_PRESET_MENU_FONT, + TEXT_PRESET_CREDIT_FONT, }; #define TEXT_FLAG_PACKED 0x8000 diff --git a/src/menu/file_select.c b/src/menu/file_select.c index 3f4cef56f..cf01c8263 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -22,6 +22,7 @@ #include "gfx_dimensions.h" #include "sm64.h" #include // non-n64 +#include // non-n64 // from hackersm64 #define o gCurrentObject @@ -2036,9 +2037,9 @@ void print_score_file_course_coin_score(s8 fileIndex, s16 courseIndex, s16 x, s1 * Prints stars collected in a score menu save file. */ void print_score_file_star_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { - s16 i = 0; - char starScoreText[30]; + char str[30] = {'\0'}; char *entries[6]; + int i; u8 stars = save_file_get_star_flags(fileIndex, courseIndex); s8 starCount = save_file_get_course_star_count(fileIndex, courseIndex); @@ -2053,8 +2054,10 @@ void print_score_file_star_score(s8 fileIndex, s16 courseIndex, s16 x, s16 y) { for (i = starCount; i < 6; i++) { entries[i] = ""; } - sprintf(starScoreText, "%s%s%s%s%s%s", entries[0], entries[1], entries[2], entries[3], entries[4], entries[5]); - print_menu_generic_string(x, y, starScoreText); + for (i = 0; i < 6; i++) { + strcat(str, entries[i]); + } + print_menu_generic_string(x, y, str); } LangArray textScoreMenuMarioX = DEFINE_LANGUAGE_ARRAY( @@ -2111,7 +2114,7 @@ void print_save_file_scores(s8 fileIndex) { for ((i = 0); (i < COURSE_STAGES_MAX); (i++)) { s32 lineY = 35 + (12 * i); format_int_to_string(str, i + 1); - print_menu_generic_string(41, lineY, segmented_to_virtual(levelNameTable[i])); + print_menu_generic_string(41, lineY, check_number_string_in_course_name(segmented_to_virtual(levelNameTable[i]))); print_menu_generic_string_aligned(37, lineY, str, TEXT_ALIGN_RIGHT); print_score_file_star_score( fileIndex, i, 171, lineY); print_score_file_course_coin_score(fileIndex, i, 213, lineY); From 5d6a3baaca3307c56a14ae9c28eda77e64c50b20 Mon Sep 17 00:00:00 2001 From: AloXado320 Date: Mon, 20 May 2024 13:10:11 -0500 Subject: [PATCH 14/14] add config text and color control command define --- include/config/config_text.h | 4 + include/macros.h | 3 + src/game/ingame_menu.c | 191 +++++++++++++++++++++++------------ src/game/ingame_menu.h | 53 +++++++++- src/menu/file_select.c | 40 ++++---- src/menu/star_select.c | 3 +- 6 files changed, 203 insertions(+), 91 deletions(-) create mode 100644 include/config/config_text.h diff --git a/include/config/config_text.h b/include/config/config_text.h new file mode 100644 index 000000000..33eebcc85 --- /dev/null +++ b/include/config/config_text.h @@ -0,0 +1,4 @@ +#pragma once + +// Adds control command character support for dialogs +#define CONTROL_COMMAND_FORMAT diff --git a/include/macros.h b/include/macros.h index e2a7231ff..9ea5fcafa 100644 --- a/include/macros.h +++ b/include/macros.h @@ -8,6 +8,9 @@ #define GLUE(a, b) a ## b #define GLUE2(a, b) GLUE(a, b) +#define STRING(s) #s +#define STRING2(s) STRING(s) + // Avoid compiler warnings for unused variables #ifdef __GNUC__ #define UNUSED __attribute__((unused)) diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index b4b095423..ef6c4cb52 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -26,6 +26,8 @@ #include // non-n64 #include // non-n64 +#include "config/config_text.h" + #ifdef CHEATS_ACTIONS #include "extras/cheats.h" #endif @@ -142,12 +144,12 @@ f32 gDialogBoxAngle = DIALOG_BOX_ANGLE_DEFAULT; f32 gDialogBoxScale = DIALOG_BOX_SCALE_DEFAULT; s32 gDialogResponse = DIALOG_RESPONSE_NONE; -/* -ColorRGBA gDialogColorByEnd; -ColorRGBA gDialogCarryoverColor; +#ifdef CONTROL_COMMAND_FORMAT +u8 gDialogColorByEnd[4]; +u8 gDialogCarryoverColor[4]; -static ColorRGBA sActiveTextColor; -*/ +static u8 sActiveTextColor[4]; +#endif static u8 sGenericFontLineHeight = 0; static u8 sGenericFontLineAlignment = TEXT_ALIGN_LEFT; @@ -385,6 +387,7 @@ struct Utf8CharLUTEntry *utf8_lookup(struct Utf8LUT *lut, char *str, s32 *strPos return segmented_to_virtual(lut->missingChar); } +#ifdef CONTROL_COMMAND_FORMAT /** * Convert a character in the range 0-9 or A-F to an integer value. Returns -1 if the character is * not a valid hex digit. @@ -403,50 +406,86 @@ static s32 hex_char_to_value(char c) { } /** - * Determine if the characters following an @ sign are a valid hex color code. + * Convert two hexadecimal text characters into an integer. Returns -1 if either of the two characters + * aren't hexadecimal values. + */ +static s32 hex_pair_to_value(char *str, s32 strPos) { + s32 firstDigit = hex_char_to_value(str[strPos]); + s32 secondDigit = hex_char_to_value(str[strPos + 1]); + + if (firstDigit == -1 || secondDigit == -1) { + return -1; + } + + return (firstDigit << 4) | secondDigit; +} + +/** + * Determine if the characters following a color command are a valid hex color code. */ static s32 is_color_code_valid(char *str, s32 strPos) { - for (s32 i = 0; i < 6; i++) { + for (u32 i = 0; i < sizeof(gDialogCarryoverColor) * 2; i++) { if (hex_char_to_value(str[strPos + i]) == -1) { - return FALSE; + if (i < (sizeof(u8) * 3) * 2) return FALSE; + // allow alpha ignore + if (str[strPos + i] != CHAR_VALUE_IGNORE[0]) return FALSE; } } return TRUE; } +#endif + +/** + * Set text color for string to print, needed for color reset commands to function properly. + * This should always be called instead of gDPSetEnvColor prior to any print_generic_string call or variant. + */ +void set_text_color(u32 r, u32 g, u32 b) { + gDPSetEnvColor(gDisplayListHead++, r, g, b, gDialogTextAlpha); +#ifdef CONTROL_COMMAND_FORMAT + sActiveTextColor[0] = r; + sActiveTextColor[1] = g; + sActiveTextColor[2] = b; + sActiveTextColor[3] = gDialogTextAlpha; +#endif +} /** * Get the exact width of the line of a string of any font in pixels, using the given ASCII and UTF-8 tables. */ s32 get_string_width(char *str, struct AsciiCharLUTEntry *asciiLut, struct Utf8LUT *utf8LUT) { + char c; s32 width = 0; s32 maxWidth = 0; - s32 strPos = 0; - char c; + s32 strPos = -1; s32 isGenericFont = (asciiLut == main_font_lut); asciiLut = segmented_to_virtual(asciiLut); - while ((c = str[strPos]) != '\0' && c != '\n') { + while ((c = str[++strPos]) != '\0' && c != '\n') { // Handle color codes and tabs if using generic font if (isGenericFont) { - if (c == CHAR_COLOR_CODE) { - if (is_color_code_valid(str, strPos + 1)) { - strPos += 7; + switch (c) { + case '\t': + width += 4 * SPACE_KERNING(asciiLut); continue; - } - } else if (c == '\t') { - width += 4 * SPACE_KERNING(asciiLut); - strPos++; - continue; +#ifdef CONTROL_COMMAND_FORMAT + case HEX(CONTROL_CHAR_COL): + if (is_color_code_valid(str, strPos + 1)) { + strPos += sizeof(gDialogCarryoverColor) * 2; + } + continue; + case HEX(CONTROL_CHAR_RESET): + continue; +#endif } } + if (c & 0x80) { width += utf8_lookup(utf8LUT, str, &strPos)->kerning; } else { width += asciiLut[ASCII_LUT_INDEX(c)].kerning; } - strPos++; } return MAX(width, maxWidth); @@ -661,13 +700,17 @@ static u32 render_generic_unicode_char(char *str, s32 *strPos) { * to control printing. */ static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { - s32 strPos = 0; char c; - s32 lineNum = 1; s8 kerning = 0; u8 queuedSpaces = 0; // Optimization to only have one translation matrix if there are multiple spaces in a row. - u8 color[3]; + u8 validColor; + s32 strPos = 0; + s32 lineNum = 1; s32 alignmentXOffset = get_alignment_x_offset(str, sGenericFontLineAlignment, main_font_lut, &main_font_utf8_lut); +#ifdef CONTROL_COMMAND_FORMAT + u8 color[4]; + bcopy(gDialogCarryoverColor, color, sizeof(color)); +#endif create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0.0f); @@ -682,8 +725,14 @@ static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { case '\n': gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); if (lineNum == maxLines) { +#ifdef CONTROL_COMMAND_FORMAT + if (gMenuState == MENU_STATE_DIALOG_OPEN) { + bcopy(color, gDialogColorByEnd, sizeof(gDialogColorByEnd)); + } +#endif return strPos + 1; } + create_dl_translation_matrix(MENU_MTX_PUSH, x, y - (lineNum * sGenericFontLineHeight), 0.0f); lineNum++; // Can skip any queued spaces @@ -702,14 +751,7 @@ static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { queuedSpaces += 4; break; - // Backslash / escape character: Force the following character to print normally. - // Note that you will have to type '\\' to use this so that the compiler doesn't - // interpret it as a real escape character. To render one backslash, use '\\\\'. - case '\\': - strPos++; - goto render_character; - - // %d or %s: Display value of dialog variable, + // %d or %s: Display value of dialog variable case '%': // Resolve queued spaces if (queuedSpaces != 0) { @@ -741,26 +783,42 @@ static s32 render_main_font_text(s16 x, s16 y, char *str, s32 maxLines) { // If the character following the % is not 'd' or 's', print the % as a normal character. goto render_character; - // @XXXXXX: Set color of text to an RGB value. - // E.g. @FF0000 will set the color to red. - // Will use gDialogTextAlpha as the alpha value. - - // Note: multiple color codes may be needed in dialog as - // earlier color codes will not function if they scroll offscreen. - case CHAR_COLOR_CODE: // '@' - for (u32 i = 0; i < 3; i++) { - s32 firstDigit = hex_char_to_value(str[strPos + i * 2 + 1]); - s32 secondDigit = hex_char_to_value(str[strPos + i * 2 + 2]); - // If the sequence following the @ is not a valid RGBA32 color, interpret it as normal text. - if (firstDigit == -1 || secondDigit == -1) { - goto render_character; +#ifdef CONTROL_COMMAND_FORMAT + // Color set control character + case HEX(CONTROL_CHAR_COL): // '\033' + validColor = TRUE; + + for (u32 i = 0; i < sizeof(color); i++) { + if (i == sizeof((sizeof(u8) * 3))) { // check if alpha should be ignored (if alpha is "--") + if (str[strPos + i * 2 + 1] == CHAR_VALUE_IGNORE[0] && str[strPos + i * 2 + 2] == CHAR_VALUE_IGNORE[0]) { + color[i] = (u8) gDialogTextAlpha; + continue; + } } - color[i] = (firstDigit << 4) | secondDigit; + + // If the sequence following the control char is not a valid RGBA32 color, interpret it as normal text. + // NOTE: Invalid color combinations can also cause color rendering issues, but those are considered user error. + s32 val = hex_pair_to_value(str, strPos + i * 2 + 1); + if (val == -1) { + validColor = FALSE; + break; + } + + color[i] = val; + } + + if (validColor) { + gDPSetEnvColor(gDisplayListHead++, color[0], color[1], color[2], color[3]); + strPos += sizeof(color) * 2; } - strPos += 6; - gDPSetEnvColor(gDisplayListHead++, color[0], color[1], color[2], gDialogTextAlpha); break; + // Color reset control character + case HEX(CONTROL_CHAR_RESET): // '\034' + bcopy(sActiveTextColor, color, sizeof(color)); + gDPSetEnvColor(gDisplayListHead++, color[0], color[1], color[2], color[3]); + break; +#endif // Normal character rendering default: render_character: @@ -1178,20 +1236,20 @@ static void handle_dialog_text_and_pages(struct DialogEntry *dialog) { gDialogTextAlpha = 255; if (gDialogBoxType == DIALOG_TYPE_ZOOM) { - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + set_text_color(0, 0, 0); } else { - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); } -/* - if (gMenuState == MENU_STATE_DIALOG_OPEN) { +#ifdef CONTROL_COMMAND_FORMAT + if (gMenuState == MENU_STATE_DIALOG_OPENING) { bcopy(sActiveTextColor, gDialogCarryoverColor, sizeof(gDialogCarryoverColor)); } else { // Deliberately not using set_text_color here, as gDialogCarryoverColor isn't // representative of the text color at the start of the dialog prompt gDPSetEnvColor(gDisplayListHead++, gDialogCarryoverColor[0], gDialogCarryoverColor[1], gDialogCarryoverColor[2], gDialogCarryoverColor[3]); } -*/ +#endif sGenericFontLineHeight = DIALOG_LINE_HEIGHT; sGenericFontLineAlignment = TEXT_ALIGN_LEFT; @@ -1413,6 +1471,9 @@ void render_dialog_entries(void) { gDialogTextPos = gLastDialogPageStrPos; gMenuState = MENU_STATE_DIALOG_OPEN; gDialogScrollOffsetY = 0; +#ifdef CONTROL_COMMAND_FORMAT + bcopy(gDialogColorByEnd, gDialogCarryoverColor, sizeof(gDialogCarryoverColor)); +#endif } break; @@ -1503,7 +1564,7 @@ void do_cutscene_handler(void) { gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDialogTextAlpha = gCutsceneMsgFade; - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string_aligned(SCREEN_CENTER_X, 13, LANG_ARRAY(*gEndCutsceneStringsEn[gCutsceneMsgIndex]), TEXT_ALIGN_CENTER); @@ -1552,7 +1613,7 @@ void print_peach_letter_message(void) { gSPDisplayList(gDisplayListHead++, castle_grounds_seg7_dl_0700EA58); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 20, 20, 20, gDialogTextAlpha); + set_text_color(20, 20, 20); print_generic_string(38, 142, str); @@ -1718,7 +1779,7 @@ void render_pause_my_score_coins(void) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); u8 *courseName = segmented_to_virtual(courseNameTbl[courseIndex]); @@ -1776,8 +1837,8 @@ void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) { handle_menu_scrolling(MENU_SCROLL_HORIZONTAL, index, 1, 2); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string_aligned(x + 54, y, LANG_ARRAY(textLakituMario), TEXT_ALIGN_CENTER); print_generic_string_aligned(x + 54, y - 15, LANG_ARRAY(textNormalUpClose), TEXT_ALIGN_CENTER); print_generic_string_aligned(x + 160, y, LANG_ARRAY(textLakituStop), TEXT_ALIGN_CENTER); @@ -1821,8 +1882,8 @@ void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 3); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string(x, y, LANG_ARRAY(textContinue)); print_generic_string(x, y - 15, LANG_ARRAY(textExitCourse)); @@ -1983,8 +2044,8 @@ void render_pause_castle_main_strings(s16 x, s16 y) { } gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); if (gMenuLineNum <= COURSE_NUM_TO_INDEX(COURSE_STAGES_MAX)) { // Main courses courseName = segmented_to_virtual(courseNameTbl[gMenuLineNum]); print_generic_string(x - 50, y + 35, check_number_string_in_course_name(courseName)); @@ -2256,10 +2317,10 @@ void render_course_complete_lvl_info_and_hud_str(void) { format_int_to_string(courseNumText, gLastCompletedCourseNum); sprintf(str, LANG_ARRAY(textCourseX), courseNumText); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + set_text_color(0, 0, 0); print_generic_string(COURSE_COMPLETE_COURSE_X + 2, COURSE_COMPLETE_COURSE_Y - 2, str); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string(COURSE_COMPLETE_COURSE_X, COURSE_COMPLETE_COURSE_Y, str); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); @@ -2270,10 +2331,10 @@ void render_course_complete_lvl_info_and_hud_str(void) { // Print course name and clear text gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + set_text_color(0, 0, 0); print_generic_string(CONGRATULATIONS_COURSE_X + 2, CONGRATULATIONS_COURSE_Y - 2, name); print_generic_string(clearX + 2, CONGRATULATIONS_COURSE_Y - 2, LANG_ARRAY(textClear)); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string(CONGRATULATIONS_COURSE_X, CONGRATULATIONS_COURSE_Y, name); print_generic_string(clearX, CONGRATULATIONS_COURSE_Y, LANG_ARRAY(textClear)); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); @@ -2300,10 +2361,10 @@ void render_course_complete_lvl_info_and_hud_str(void) { // Print act name and catch text gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + set_text_color(0, 0, 0); print_generic_string(COURSE_COMPLETE_ACT_X + 2, COURSE_COMPLETE_ACT_Y - 2, name); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string(COURSE_COMPLETE_ACT_X, COURSE_COMPLETE_ACT_Y, name); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); @@ -2331,8 +2392,8 @@ void render_save_confirmation(s16 x, s16 y, s8 *index, s16 yPos) { handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 3); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string(x + 12, y, LANG_ARRAY(textSaveAndContinue)); print_generic_string(x + 12, y - 20, LANG_ARRAY(textSaveAndQuit)); print_generic_string(x + 12, y - 40, LANG_ARRAY(textContinueWithoutSave)); diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index 266c7e7b2..421add22f 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -3,6 +3,54 @@ #include #include "types.h" +#include "dialog_ids.h" +#include "course_table.h" + +// General string macros +#define HEX(s) GLUE2(0x, s) +#define HEX_STR(s) STRING2(GLUE2(\x, s)) + +// Control characters (Must be hexadecimal without the +// '0x' prefix, possible values range from 00-1F) +#define CONTROL_CHAR_TERMINATOR 00 // '\0' (RESERVED!) +#define CONTROL_CHAR_TAB 09 // '\t' (RESERVED!) +#define CONTROL_CHAR_NEWLINE 0A // '\n' (RESERVED!) +#define CONTROL_CHAR_COL 1B // '\033' +#define CONTROL_CHAR_RESET 1C // '\034' + +// Additional control macros +#define CHAR_VALUE_IGNORE "-" + + +/********************************** BEGIN USER DIALOG CONTROL **********************************/ + + +/** + * COL_RGB("XXXXXX"), COL_RGBA("XXXXXXXX") + * + * Set color of text to an RGB value. + * e.g. COL_RGB("00FF00") will set the color to green. + * Will use gDialogTextAlpha as the alpha value if alpha is not specified. + * + * Example: "normal text " COL_RGBA("FF00007F") "transparent red text" + */ +#define COL_RGB(color) \ + HEX_STR(CONTROL_CHAR_COL) color CHAR_VALUE_IGNORE CHAR_VALUE_IGNORE +#define COL_RGBA(color) \ + HEX_STR(CONTROL_CHAR_COL) color + +/** + * COL_RESET + * + * Reset the text color back to its default text color. + * + * Example: "colored text " COL_RESET "normal text" + */ +#define COL_RESET \ + HEX_STR(CONTROL_CHAR_RESET) + + +/*********************************** END USER DIALOG CONTROL ***********************************/ enum MenuMtxPushOp { MENU_MTX_NONE, @@ -51,10 +99,6 @@ struct AsciiCharLUTEntry { // Macro to quickly get the kerning of the space character from an ASCII LUT. #define SPACE_KERNING(lut) (((struct AsciiCharLUTEntry *)(lut))[ASCII_LUT_INDEX(' ')].kerning) -// The character used to indicate a color code in a generic string. -// As of now, must be an ASCII character. -#define CHAR_COLOR_CODE '@' - struct Utf8CharLUTEntry { u32 codepoint; s8 kerning; @@ -185,6 +229,7 @@ void create_dl_translation_matrix(s8 pushOp, f32 x, f32 y, f32 z); void create_dl_ortho_matrix(void); void create_dl_scale_matrix(s8 pushOp, f32 x, f32 y, f32 z); +void set_text_color(u32 r, u32 g, u32 b); s32 get_string_width(char *str, struct AsciiCharLUTEntry *asciiLut, struct Utf8LUT *utf8LUT); s32 get_string_width_preset(char *str, u16 preset); void format_int_to_string(char *buf, s32 value); diff --git a/src/menu/file_select.c b/src/menu/file_select.c index cf01c8263..f64618bc0 100644 --- a/src/menu/file_select.c +++ b/src/menu/file_select.c @@ -1244,7 +1244,7 @@ void string_format_file_letter(char *buf, char *str, s32 fileIndex) { void print_hud_lut_string_fade(s16 x, s16 y, char *text, u32 alignment) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); gDialogTextAlpha -= sTextFadeAlpha; - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_hud_lut_string_aligned(x, y, text, alignment); gDialogTextAlpha += sTextFadeAlpha; gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); @@ -1256,7 +1256,7 @@ void print_hud_lut_string_fade(s16 x, s16 y, char *text, u32 alignment) { void print_generic_string_fade(s16 x, s16 y, char *text, u32 alignment) { gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDialogTextAlpha -= sTextFadeAlpha; - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string_aligned(x, y, text, alignment); gDialogTextAlpha += sTextFadeAlpha; gSPDisplayList(gDisplayListHead++, dl_ia_text_end); @@ -1400,7 +1400,7 @@ LangArray textOption = DEFINE_LANGUAGE_ARRAY( void print_main_menu_strings(void) { // Print "SELECT FILE" text gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_hud_lut_string_aligned(SCREEN_CENTER_X, 35, LANG_ARRAY(textSelectFile), TEXT_ALIGN_CENTER); // Print file star counts print_save_file_star_count(SAVE_FILE_A, 92, 78); @@ -1410,7 +1410,7 @@ void print_main_menu_strings(void) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string_aligned(67, 39, LANG_ARRAY(textScore), TEXT_ALIGN_CENTER); print_generic_string_aligned(130, 39, LANG_ARRAY(textCopy), TEXT_ALIGN_CENTER); print_generic_string_aligned(191, 39, LANG_ARRAY(textErase), TEXT_ALIGN_CENTER); @@ -1422,7 +1422,7 @@ void print_main_menu_strings(void) { gSPDisplayList(gDisplayListHead++, dl_ia_text_end); // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_menu_generic_string(92, 65, LANG_ARRAY(textMarioA)); print_menu_generic_string(207, 65, LANG_ARRAY(textMarioB)); print_menu_generic_string(92, 105, LANG_ARRAY(textMarioC)); @@ -1502,7 +1502,7 @@ void print_score_menu_strings(void) { // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_save_file_star_count(SAVE_FILE_A, 90, 76); print_save_file_star_count(SAVE_FILE_B, 211, 76); print_save_file_star_count(SAVE_FILE_C, 90, 119); @@ -1511,7 +1511,7 @@ void print_score_menu_strings(void) { // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string_aligned(SUBMENU_LEFT_BUTTON_X, 35, LANG_ARRAY(textReturn), TEXT_ALIGN_CENTER); print_generic_string_aligned(SUBMENU_MIDDLE_BUTTON_X, 35, LANG_ARRAY(textCopyFileButton), TEXT_ALIGN_CENTER); print_generic_string_aligned(SUBMENU_RIGHT_BUTTON_X, 35, LANG_ARRAY(textEraseFileButton), TEXT_ALIGN_CENTER); @@ -1519,7 +1519,7 @@ void print_score_menu_strings(void) { // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_menu_generic_string(89, 62, LANG_ARRAY(textMarioA)); print_menu_generic_string(211, 62, LANG_ARRAY(textMarioB)); print_menu_generic_string(89, 105, LANG_ARRAY(textMarioC)); @@ -1647,7 +1647,7 @@ void print_copy_menu_strings(void) { copy_menu_display_message(sStatusMessageID); // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_save_file_star_count(SAVE_FILE_A, 90, 76); print_save_file_star_count(SAVE_FILE_B, 211, 76); print_save_file_star_count(SAVE_FILE_C, 90, 119); @@ -1655,14 +1655,14 @@ void print_copy_menu_strings(void) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string_aligned(SUBMENU_LEFT_BUTTON_X, 35, LANG_ARRAY(textReturn), TEXT_ALIGN_CENTER); print_generic_string_aligned(SUBMENU_MIDDLE_BUTTON_X, 35, LANG_ARRAY(textViewScore), TEXT_ALIGN_CENTER); print_generic_string_aligned(SUBMENU_RIGHT_BUTTON_X, 35, LANG_ARRAY(textEraseFileButton), TEXT_ALIGN_CENTER); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_menu_generic_string(89, 62, LANG_ARRAY(textMarioA)); print_menu_generic_string(211, 62, LANG_ARRAY(textMarioB)); print_menu_generic_string(89, 105, LANG_ARRAY(textMarioC)); @@ -1849,7 +1849,7 @@ void print_erase_menu_strings(void) { // Print file star counts gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_save_file_star_count(SAVE_FILE_A, 90, 76); print_save_file_star_count(SAVE_FILE_B, 211, 76); print_save_file_star_count(SAVE_FILE_C, 90, 119); @@ -1858,7 +1858,7 @@ void print_erase_menu_strings(void) { // Print menu names gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_generic_string_aligned(SUBMENU_LEFT_BUTTON_X, 35, LANG_ARRAY(textReturn), TEXT_ALIGN_CENTER); print_generic_string_aligned(SUBMENU_MIDDLE_BUTTON_X, 35, LANG_ARRAY(textViewScore), TEXT_ALIGN_CENTER); print_generic_string_aligned(SUBMENU_RIGHT_BUTTON_X, 35, LANG_ARRAY(textCopyFileButton), TEXT_ALIGN_CENTER); @@ -1866,7 +1866,7 @@ void print_erase_menu_strings(void) { // Print file names gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_menu_generic_string(89, 62, LANG_ARRAY(textMarioA)); print_menu_generic_string(211, 62, LANG_ARRAY(textMarioB)); print_menu_generic_string(89, 105, LANG_ARRAY(textMarioC)); @@ -1913,7 +1913,7 @@ void print_sound_mode_menu_strings(void) { // Print "SOUND SELECT" text gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); print_hud_lut_string(47, 32, LANG_ARRAY(textSoundSelect)); #ifdef MULTILANG @@ -1927,9 +1927,9 @@ void print_sound_mode_menu_strings(void) { // Print sound mode names for (mode = 0, textX = SCREEN_CENTER_X - OPTION_LABEL_SPACING; mode < 3; textX += OPTION_LABEL_SPACING, mode++) { if (mode == sSoundMode) { - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); } else { - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + set_text_color(0, 0, 0); } print_generic_string_aligned(textX, SOUND_LABEL_Y, LANG_ARRAY(*textSoundModes[mode]), TEXT_ALIGN_CENTER); } @@ -1957,7 +1957,7 @@ void print_sound_mode_menu_strings(void) { } } - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); // Print current language print_generic_string_aligned(SCREEN_CENTER_X, LANGUAGE_SELECT_Y, textLanguage[gInGameLanguage], TEXT_ALIGN_CENTER); print_generic_string_aligned(SCREEN_CENTER_X - 50, LANGUAGE_SELECT_Y, "◀", TEXT_ALIGN_CENTER); @@ -2099,7 +2099,7 @@ void print_save_file_scores(s8 fileIndex) { // Print file name at top gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); fileLetter = 'A' + fileIndex; sprintf(str, LANG_ARRAY(textScoreMenuMarioX), fileLetter); print_hud_lut_string(25, 15, str); @@ -2109,7 +2109,7 @@ void print_save_file_scores(s8 fileIndex) { gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); // Print course scores gSPDisplayList(gDisplayListHead++, dl_menu_ia8_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); + set_text_color(255, 255, 255); for ((i = 0); (i < COURSE_STAGES_MAX); (i++)) { s32 lineY = 35 + (12 * i); diff --git a/src/menu/star_select.c b/src/menu/star_select.c index 958d2841b..19f993070 100644 --- a/src/menu/star_select.c +++ b/src/menu/star_select.c @@ -267,12 +267,11 @@ void print_act_selector_strings(void) { // Print the coin highscore. gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin); - gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); print_hud_my_score_coins(1, gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum), 155, 106); gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, gDialogTextAlpha); + set_text_color(0, 0, 0); // Print the "MY SCORE" text if the coin score is more than 0 if (save_file_get_course_coin_score(gCurrSaveFileNum - 1, COURSE_NUM_TO_INDEX(gCurrCourseNum)) != 0) { print_generic_string_aligned(145, 118, LANG_ARRAY(textActMyScore), TEXT_ALIGN_RIGHT);