Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 38 additions & 21 deletions src/mars_patcher/mf/constants/reserved_space.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,51 @@
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
FIRST_CUSTOM_MESSAGE_ID = 0x39 # The first 0x38 messages are reserved for standard messages

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()
METROID_PARAMETERS_ADDR = auto()
STARTING_LOCATION_ADDR = auto()
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()
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
17 changes: 8 additions & 9 deletions src/mars_patcher/mf/item_patcher.py
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -11,14 +11,13 @@
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
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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down
12 changes: 6 additions & 6 deletions src/mars_patcher/mf/misc_patches.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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)
4 changes: 2 additions & 2 deletions src/mars_patcher/mf/navigation_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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,
)
4 changes: 2 additions & 2 deletions src/mars_patcher/mf/room_names.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/mars_patcher/mf/starting.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions src/mars_patcher/titlescreen_text.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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"))