From 226d227440e6b47437651356e0b17b3944bf2ae9 Mon Sep 17 00:00:00 2001 From: Miepee Date: Sat, 3 Jan 2026 20:27:45 +0100 Subject: [PATCH 1/3] Rework ReservedPointers to not need to manually include address --- .../mf/constants/reserved_space.py | 61 ++++++++++++------- src/mars_patcher/mf/item_patcher.py | 14 ++--- src/mars_patcher/mf/misc_patches.py | 12 ++-- src/mars_patcher/mf/navigation_text.py | 4 +- src/mars_patcher/mf/room_names.py | 4 +- src/mars_patcher/mf/starting.py | 4 +- src/mars_patcher/titlescreen_text.py | 6 +- 7 files changed, 62 insertions(+), 43 deletions(-) diff --git a/src/mars_patcher/mf/constants/reserved_space.py b/src/mars_patcher/mf/constants/reserved_space.py index 731e408..ce10866 100644 --- a/src/mars_patcher/mf/constants/reserved_space.py +++ b/src/mars_patcher/mf/constants/reserved_space.py @@ -1,11 +1,18 @@ +from enum import IntEnum, auto + +from typing_extensions import Self + + class ReservedConstantsMF: """ - These are constants that are in the patches 'Reserved Space'; + These are constants that are in the ROM's 'Reserved Space'; things that are intended to be modified by this patcher. """ # These need to be kept in sync with the base patch - # found somewhere around https://github.com/MetroidAdvRandomizerSystem/MARS-Fusion/blob/main/src/main.s#L45 + # found somewhere around https://github.com/MetroidAdvRandomizerSystem/MARS-Fusion/blob/main/src/main.s#L48 + + RANDO_POINTERS_ADDR = 0x7FF000 # Pointers, offset by language value, that store the message table location MESSAGE_TABLE_LOOKUP_ADDR = 0x79CDF4 @@ -13,22 +20,34 @@ class ReservedConstantsMF: PATCHER_FREE_SPACE_ADDR = 0x7D0000 PATCHER_FREE_SPACE_END = PATCHER_FREE_SPACE_ADDR + 0x20000 - # TODO: refactor these to be like in ZM. Instead of hardcoding the addresses. - MINOR_LOCS_TABLE_ADDR = 0x7FF000 - MINOR_LOCS_ARRAY_ADDR = 0x7FF004 - MAJOR_LOCS_POINTER_ADDR = 0x7FF008 - TANK_INC_ADDR = 0x7FF00C - TOTAL_METROID_COUNT_ADDR = 0x7FF010 - REQUIRED_METROID_COUNT_ADDR = 0x7FF010 - STARTING_LOCATION_ADDR = 0x7FF014 - CREDITS_END_DELAY_ADDR = 0x7FF018 # TODO: Is this meant to be changed? - CREDITS_SCROLL_SPEED_ADDR = 0x7FF018 # + 2 TODO: Ditto - HINT_SECURITY_LEVELS_ADDR = 0x7FF01C - ENVIRONMENTAL_HARZARD_DAMAGE_ADDR = 0x7FF020 # TODO: Implement this - MISSILE_LIMIT_ADDR = 0x7FF024 - ROOM_NAMES_TABLE_ADDR = 0x7FF028 - REVEAL_HIDDEN_TILES_ADDR = 0x7FF02C - TITLESCREEN_TEXT_POINTERS_POINTER_ADDR = 0x7FF030 - DEFAULT_STEREO_FLAG_POINTER_ADDR = 0x7FF034 - INSTANT_MORPH_FLAG_POINTER_ADDR = 0x7FF038 - USE_ALTERNATIVE_HUD_DISPLAY = 0x7FF03C + + +class ReservedPointersMF(IntEnum): + """ + These are pointers that are in the ROM's 'Reserved Space'; + things that are intended to be modified by this patcher. + """ + + MINOR_LOCS_TABLE_ADDR = 0 + MINOR_LOCS_ARRAY_ADDR = auto() + MAJOR_LOCS_POINTER_ADDR = auto() + TANK_INC_ADDR = auto() + TOTAL_METROID_COUNT_ADDR = auto() + REQUIRED_METROID_COUNT_ADDR = TOTAL_METROID_COUNT_ADDR + STARTING_LOCATION_ADDR = auto() + CREDITS_END_DELAY_ADDR = auto() # TODO: Is this meant to be changed? + CREDITS_SCROLL_SPEED_ADDR = CREDITS_END_DELAY_ADDR # + 2 TODO: Ditto + HINT_SECURITY_LEVELS_ADDR = auto() + ENVIRONMENTAL_HARZARD_DAMAGE_ADDR = auto() # TODO: Implement this + MISSILE_LIMIT_ADDR = auto() + ROOM_NAMES_TABLE_ADDR = auto() + REVEAL_HIDDEN_TILES_ADDR = auto() + TITLESCREEN_TEXT_POINTERS_POINTER_ADDR = auto() + DEFAULT_STEREO_FLAG_POINTER_ADDR = auto() + INSTANT_MORPH_FLAG_POINTER_ADDR = auto() + USE_ALTERNATIVE_HUD_DISPLAY = auto() + + def __new__(cls, offset: int) -> Self: + obj = int.__new__(cls) + obj._value_ = ReservedConstantsMF.RANDO_POINTERS_ADDR + (offset * 4) + return obj diff --git a/src/mars_patcher/mf/item_patcher.py b/src/mars_patcher/mf/item_patcher.py index e9d7bd9..2185d74 100644 --- a/src/mars_patcher/mf/item_patcher.py +++ b/src/mars_patcher/mf/item_patcher.py @@ -1,6 +1,6 @@ from mars_patcher.item_messages import ItemMessages, ItemMessagesKind from mars_patcher.mf.auto_generated_types import MarsschemamfTankincrements -from mars_patcher.mf.constants.reserved_space import ReservedConstantsMF +from mars_patcher.mf.constants.reserved_space import ReservedConstantsMF, ReservedPointersMF from mars_patcher.mf.locations import ( ItemSprite, ItemType, @@ -11,14 +11,14 @@ from mars_patcher.text import Language, MessageType, encode_text from mars_patcher.tileset import Tileset -MINOR_LOCS_TABLE_ADDR = ReservedConstantsMF.MINOR_LOCS_TABLE_ADDR -MINOR_LOCS_ARRAY_ADDR = ReservedConstantsMF.MINOR_LOCS_ARRAY_ADDR +MINOR_LOCS_TABLE_ADDR = ReservedPointersMF.MINOR_LOCS_TABLE_ADDR +MINOR_LOCS_ARRAY_ADDR = ReservedPointersMF.MINOR_LOCS_ARRAY_ADDR MINOR_LOC_SIZE = 0x10 -MAJOR_LOCS_POINTER_ADDR = ReservedConstantsMF.MAJOR_LOCS_POINTER_ADDR +MAJOR_LOCS_POINTER_ADDR = ReservedPointersMF.MAJOR_LOCS_POINTER_ADDR MAJOR_LOC_SIZE = 0x4 -TANK_INC_ADDR = ReservedConstantsMF.TANK_INC_ADDR -REQUIRED_METROID_COUNT_ADDR = ReservedConstantsMF.REQUIRED_METROID_COUNT_ADDR -TOTAL_METROID_COUNT_ADDR = ReservedConstantsMF.TOTAL_METROID_COUNT_ADDR +TANK_INC_ADDR = ReservedPointersMF.TANK_INC_ADDR +REQUIRED_METROID_COUNT_ADDR = ReservedPointersMF.REQUIRED_METROID_COUNT_ADDR +TOTAL_METROID_COUNT_ADDR = ReservedPointersMF.TOTAL_METROID_COUNT_ADDR MESSAGE_TABLE_LOOKUP_ADDR = ReservedConstantsMF.MESSAGE_TABLE_LOOKUP_ADDR FIRST_CUSTOM_MESSAGE_ID = ReservedConstantsMF.FIRST_CUSTOM_MESSAGE_ID AUTO_MESSAGE_ID = 0xFF diff --git a/src/mars_patcher/mf/misc_patches.py b/src/mars_patcher/mf/misc_patches.py index 12ad9b1..385cf8d 100644 --- a/src/mars_patcher/mf/misc_patches.py +++ b/src/mars_patcher/mf/misc_patches.py @@ -1,5 +1,5 @@ import mars_patcher.constants.game_data as gd -from mars_patcher.mf.constants.reserved_space import ReservedConstantsMF +from mars_patcher.mf.constants.reserved_space import ReservedPointersMF from mars_patcher.mf.data import get_data_path from mars_patcher.patching import BpsDecoder, IpsDecoder from mars_patcher.rom import Rom @@ -43,7 +43,7 @@ def skip_door_transitions(rom: Rom) -> None: def stereo_default(rom: Rom) -> None: - rom.write_8(rom.read_ptr(ReservedConstantsMF.DEFAULT_STEREO_FLAG_POINTER_ADDR), 1) + rom.write_8(rom.read_ptr(ReservedPointersMF.DEFAULT_STEREO_FLAG_POINTER_ADDR), 1) def disable_sounds(rom: Rom, start: int, end: int, exclude: set[int] = set()) -> None: @@ -70,7 +70,7 @@ def disable_sound_effects(rom: Rom) -> None: def change_missile_limit(rom: Rom, limit: int) -> None: - rom.write_8(rom.read_ptr(ReservedConstantsMF.MISSILE_LIMIT_ADDR), limit) + rom.write_8(rom.read_ptr(ReservedPointersMF.MISSILE_LIMIT_ADDR), limit) def apply_unexplored_map(rom: Rom) -> None: @@ -86,11 +86,11 @@ def apply_nerf_gerons(rom: Rom) -> None: def apply_alternative_health_layout(rom: Rom) -> None: - rom.write_8(rom.read_ptr(ReservedConstantsMF.USE_ALTERNATIVE_HUD_DISPLAY), 1) + rom.write_8(rom.read_ptr(ReservedPointersMF.USE_ALTERNATIVE_HUD_DISPLAY), 1) def apply_reveal_hidden_tiles(rom: Rom) -> None: - rom.write_8(rom.read_ptr(ReservedConstantsMF.REVEAL_HIDDEN_TILES_ADDR), 1) + rom.write_8(rom.read_ptr(ReservedPointersMF.REVEAL_HIDDEN_TILES_ADDR), 1) def apply_reveal_unexplored_doors(rom: Rom) -> None: @@ -102,4 +102,4 @@ def apply_accessibility_patch(rom: Rom) -> None: def apply_instant_unmorph_patch(rom: Rom) -> None: - rom.write_8(rom.read_ptr(ReservedConstantsMF.INSTANT_MORPH_FLAG_POINTER_ADDR), 1) + rom.write_8(rom.read_ptr(ReservedPointersMF.INSTANT_MORPH_FLAG_POINTER_ADDR), 1) diff --git a/src/mars_patcher/mf/navigation_text.py b/src/mars_patcher/mf/navigation_text.py index 60d928f..c616335 100644 --- a/src/mars_patcher/mf/navigation_text.py +++ b/src/mars_patcher/mf/navigation_text.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING from mars_patcher.mf.constants.game_data import navigation_text_ptrs -from mars_patcher.mf.constants.reserved_space import ReservedConstantsMF +from mars_patcher.mf.constants.reserved_space import ReservedPointersMF from mars_patcher.rom import Rom from mars_patcher.text import Language, MessageType, encode_text @@ -128,6 +128,6 @@ def apply_hint_security( default_lock_name = "OPEN" for location, offset in NavigationText.NAV_ROOM_ENUMS.items(): rom.write_8( - rom.read_ptr(ReservedConstantsMF.HINT_SECURITY_LEVELS_ADDR) + offset.value, + rom.read_ptr(ReservedPointersMF.HINT_SECURITY_LEVELS_ADDR) + offset.value, NavStationLockType[locks.get(location, default_lock_name)].value, ) diff --git a/src/mars_patcher/mf/room_names.py b/src/mars_patcher/mf/room_names.py index 0b4d7d9..2afe7de 100644 --- a/src/mars_patcher/mf/room_names.py +++ b/src/mars_patcher/mf/room_names.py @@ -1,9 +1,9 @@ from mars_patcher.mf.auto_generated_types import Areaid, MarsschemamfRoomnamesItem, Typeu8 -from mars_patcher.mf.constants.reserved_space import ReservedConstantsMF +from mars_patcher.mf.constants.reserved_space import ReservedPointersMF from mars_patcher.rom import Rom from mars_patcher.text import MessageType, encode_text -ROOM_NAMES_TABLE_ADDR = ReservedConstantsMF.ROOM_NAMES_TABLE_ADDR +ROOM_NAMES_TABLE_ADDR = ReservedPointersMF.ROOM_NAMES_TABLE_ADDR # Write Room Names to ROM diff --git a/src/mars_patcher/mf/starting.py b/src/mars_patcher/mf/starting.py index 17d025b..f139eff 100644 --- a/src/mars_patcher/mf/starting.py +++ b/src/mars_patcher/mf/starting.py @@ -5,12 +5,12 @@ ) from mars_patcher.mf.constants.game_data import starting_equipment from mars_patcher.mf.constants.items import BEAM_FLAGS, MISSILE_BOMB_FLAGS, SUIT_MISC_FLAGS -from mars_patcher.mf.constants.reserved_space import ReservedConstantsMF +from mars_patcher.mf.constants.reserved_space import ReservedPointersMF from mars_patcher.rom import Rom from mars_patcher.room_entry import RoomEntry # Keep in sync with base patch -STARTING_LOC_ADDR = ReservedConstantsMF.STARTING_LOCATION_ADDR +STARTING_LOC_ADDR = ReservedPointersMF.STARTING_LOCATION_ADDR def set_starting_location(rom: Rom, data: MarsschemamfStartinglocation) -> None: diff --git a/src/mars_patcher/titlescreen_text.py b/src/mars_patcher/titlescreen_text.py index dfbfdc7..48208c8 100644 --- a/src/mars_patcher/titlescreen_text.py +++ b/src/mars_patcher/titlescreen_text.py @@ -1,8 +1,8 @@ from mars_patcher.mf.auto_generated_types import MarsschemamfTitletextItem -from mars_patcher.mf.constants.reserved_space import ReservedConstantsMF +from mars_patcher.mf.constants.reserved_space import ReservedPointersMF from mars_patcher.rom import Rom -TITLE_TEXT_POINTER_ADDR = ReservedConstantsMF.TITLESCREEN_TEXT_POINTERS_POINTER_ADDR +TITLE_TEXT_POINTER_ADDR = ReservedPointersMF.TITLESCREEN_TEXT_POINTERS_POINTER_ADDR MAX_LENGTH = 30 MAX_LINES = 14 @@ -30,6 +30,6 @@ def write_title_text(rom: Rom, lines: list[MarsschemamfTitletextItem]) -> None: def write_title_text_line(rom: Rom, line: MarsschemamfTitletextItem) -> None: if len(line["Text"]) > 30: raise ValueError(f'String for title-screen text exceeds 30 characters.\n"{line["Text"]}"') - text_pointers = rom.read_ptr(ReservedConstantsMF.TITLESCREEN_TEXT_POINTERS_POINTER_ADDR) + text_pointers = rom.read_ptr(ReservedPointersMF.TITLESCREEN_TEXT_POINTERS_POINTER_ADDR) addr = rom.read_ptr(text_pointers + (line["LineNum"] * 4)) rom.write_bytes(addr, line["Text"].encode("ascii")) From 1ae9982df9d7e266333981d6c8b08cd061ea35fd Mon Sep 17 00:00:00 2001 From: Miepee Date: Sat, 3 Jan 2026 21:08:44 +0100 Subject: [PATCH 2/3] remove unneded variables --- src/mars_patcher/mf/constants/reserved_space.py | 6 ++---- src/mars_patcher/mf/item_patcher.py | 7 +++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/mars_patcher/mf/constants/reserved_space.py b/src/mars_patcher/mf/constants/reserved_space.py index ce10866..918e112 100644 --- a/src/mars_patcher/mf/constants/reserved_space.py +++ b/src/mars_patcher/mf/constants/reserved_space.py @@ -32,11 +32,9 @@ class ReservedPointersMF(IntEnum): MINOR_LOCS_ARRAY_ADDR = auto() MAJOR_LOCS_POINTER_ADDR = auto() TANK_INC_ADDR = auto() - TOTAL_METROID_COUNT_ADDR = auto() - REQUIRED_METROID_COUNT_ADDR = TOTAL_METROID_COUNT_ADDR + METROID_PARAMETERS_ADDR = auto() STARTING_LOCATION_ADDR = auto() - CREDITS_END_DELAY_ADDR = auto() # TODO: Is this meant to be changed? - CREDITS_SCROLL_SPEED_ADDR = CREDITS_END_DELAY_ADDR # + 2 TODO: Ditto + CREDITS_END_DELAY_ADDR = auto() # Unused. Remnant of when we didn't have looping credits music. HINT_SECURITY_LEVELS_ADDR = auto() ENVIRONMENTAL_HARZARD_DAMAGE_ADDR = auto() # TODO: Implement this MISSILE_LIMIT_ADDR = auto() diff --git a/src/mars_patcher/mf/item_patcher.py b/src/mars_patcher/mf/item_patcher.py index 2185d74..a1fd268 100644 --- a/src/mars_patcher/mf/item_patcher.py +++ b/src/mars_patcher/mf/item_patcher.py @@ -17,8 +17,7 @@ MAJOR_LOCS_POINTER_ADDR = ReservedPointersMF.MAJOR_LOCS_POINTER_ADDR MAJOR_LOC_SIZE = 0x4 TANK_INC_ADDR = ReservedPointersMF.TANK_INC_ADDR -REQUIRED_METROID_COUNT_ADDR = ReservedPointersMF.REQUIRED_METROID_COUNT_ADDR -TOTAL_METROID_COUNT_ADDR = ReservedPointersMF.TOTAL_METROID_COUNT_ADDR +METROID_PARAMETERS_ADDR = ReservedPointersMF.METROID_PARAMETERS_ADDR MESSAGE_TABLE_LOOKUP_ADDR = ReservedConstantsMF.MESSAGE_TABLE_LOOKUP_ADDR FIRST_CUSTOM_MESSAGE_ID = ReservedConstantsMF.FIRST_CUSTOM_MESSAGE_ID AUTO_MESSAGE_ID = 0xFF @@ -195,7 +194,7 @@ def write_items(self) -> None: # Write item jingle rom.write_8(addr + 2, maj_loc.item_jingle.value) # Write total metroid count - rom.write_8(rom.read_ptr(TOTAL_METROID_COUNT_ADDR), total_metroids) + rom.write_8(rom.read_ptr(METROID_PARAMETERS_ADDR), total_metroids) def write_custom_message( self, @@ -230,7 +229,7 @@ def write_custom_message( # TODO: Move these? def set_required_metroid_count(rom: Rom, count: int) -> None: - rom.write_8(rom.read_ptr(REQUIRED_METROID_COUNT_ADDR) + 1, count) + rom.write_8(rom.read_ptr(METROID_PARAMETERS_ADDR) + 1, count) def set_tank_increments(rom: Rom, data: MarsschemamfTankincrements) -> None: From 89ebf70699ba777ce8d47f87b6081e8934b3513d Mon Sep 17 00:00:00 2001 From: Miepee Date: Fri, 16 Jan 2026 16:34:13 +0100 Subject: [PATCH 3/3] rename credits pointer --- src/mars_patcher/mf/constants/reserved_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mars_patcher/mf/constants/reserved_space.py b/src/mars_patcher/mf/constants/reserved_space.py index 918e112..7fe926d 100644 --- a/src/mars_patcher/mf/constants/reserved_space.py +++ b/src/mars_patcher/mf/constants/reserved_space.py @@ -34,7 +34,7 @@ class ReservedPointersMF(IntEnum): TANK_INC_ADDR = auto() METROID_PARAMETERS_ADDR = auto() STARTING_LOCATION_ADDR = auto() - CREDITS_END_DELAY_ADDR = auto() # Unused. Remnant of when we didn't have looping credits music. + CREDITS_PARAMETERS_ADDR = auto() # Unused. Remnant of when we didn't have looping credits music HINT_SECURITY_LEVELS_ADDR = auto() ENVIRONMENTAL_HARZARD_DAMAGE_ADDR = auto() # TODO: Implement this MISSILE_LIMIT_ADDR = auto()