SM: smoother co-op, basepatch internal improvements (#793)

* SM: remote touch instantly, pull ips refactor and symbols

* SM: remove hard-coded ROM address writes

* SM: Full length player table, incl. receive-only player ids

+ apply PR feedback (correct graphic offset, readable data file paths)
This commit is contained in:
strotlog 2022-07-26 00:43:39 -07:00 committed by GitHub
parent a0482cf27e
commit 1e366ff66f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1027 additions and 81 deletions

3
.gitignore vendored
View File

@ -116,6 +116,9 @@ target/
profile_default/
ipython_config.py
# vim editor
*.swp
# SageMath parsed files
*.sage.py

View File

@ -1,11 +1,12 @@
import hashlib
import os
import json
import Utils
from Patch import read_rom, APDeltaPatch
SMJUHASH = '21f3e98df4780ee1c667b84e57d88675'
ROM_PLAYER_LIMIT = 65535
ROM_PLAYER_LIMIT = 65535 # max archipelago player ID. note, SM ROM itself will only store 201 names+ids max
class SMDeltaPatch(APDeltaPatch):
@ -17,7 +18,6 @@ class SMDeltaPatch(APDeltaPatch):
def get_source_data(cls) -> bytes:
return get_base_rom_bytes()
def get_base_rom_bytes(file_name: str = "") -> bytes:
base_rom_bytes = getattr(get_base_rom_bytes, "base_rom_bytes", None)
if not base_rom_bytes:
@ -40,3 +40,48 @@ def get_base_rom_path(file_name: str = "") -> str:
if not os.path.exists(file_name):
file_name = Utils.user_path(file_name)
return file_name
def get_sm_symbols(sym_json_path) -> dict:
with open(sym_json_path, "r") as stream:
symbols = json.load(stream)
symboltable = {}
for name, sixdigitaddr in symbols.items():
(bank, addr_within_bank) = sixdigitaddr.split(":")
bank = int(bank, 16)
addr_within_bank = int(addr_within_bank, 16)
# categorize addresses using snes lorom mapping:
# (reference: https://en.wikibooks.org/wiki/Super_NES_Programming/SNES_memory_map)
if (bank >= 0x70 and bank <= 0x7d):
offset_within_rom_file = None
# SRAM is not continuous, but callers may want it in continuous terms
# SRAM @ data bank $70-$7D, addr_within_bank $0000-$7FFF
#
# symbol aka snes offestwithincontinuousSRAM
# --------------- --------------------------
# $70:0000-7FFF -> 0x0000- 7FFF
# $71:0000-7FFF -> 0x8000- FFFF
# $72:0000-7FFF -> 0x10000-17FFF
# etc...
offset_within_continuous_sram = (bank - 0x70) * 0x8000 + addr_within_bank
offset_within_wram = None
elif bank == 0x7e or bank == 0x7f or (bank == 0x00 and addr_within_bank <= 0x1fff):
offset_within_rom_file = None
offset_within_continuous_sram = None
offset_within_wram = addr_within_bank
if bank == 0x7f:
offset_within_wram += 0x10000
elif bank >= 0x80:
offset_within_rom_file = ((bank - 0x80) * 0x8000) + (addr_within_bank % 0x8000)
offset_within_continuous_sram = None
offset_within_wram = None
else:
offset_within_rom_file = None
offset_within_continuous_sram = None
offset_within_wram = None
symboltable[name] = {"bank": bank,
"addr_within_bank": addr_within_bank,
"offset_within_rom_file": offset_within_rom_file,
"offset_within_continuous_sram": offset_within_continuous_sram,
"offset_within_wram": offset_within_wram
}
return symboltable

View File

@ -16,7 +16,7 @@ from .Items import lookup_name_to_id as items_lookup_name_to_id
from .Regions import create_regions
from .Rules import set_rules, add_entrance_rule
from .Options import sm_options
from .Rom import get_base_rom_path, ROM_PLAYER_LIMIT, SMDeltaPatch
from .Rom import get_base_rom_path, ROM_PLAYER_LIMIT, SMDeltaPatch, get_sm_symbols
import Utils
from BaseClasses import Region, Entrance, Location, MultiWorld, Item, ItemClassification, RegionType, CollectionState, Tutorial
@ -201,10 +201,7 @@ class SMWorld(World):
create_locations(self, self.player)
create_regions(self, self.world, self.player)
def getWord(self, w):
return (w & 0x00FF, (w & 0xFF00) >> 8)
def getWordArray(self, w):
def getWordArray(self, w): # little-endian convert a 16-bit number to an array of numbers <= 255 each
return [w & 0x00FF, (w & 0xFF00) >> 8]
# used for remote location Credits Spoiler of local items
@ -269,109 +266,175 @@ class SMWorld(World):
itemName = "___" + itemName + "___"
for char in itemName:
(w0, w1) = self.getWord(charMap.get(char, 0x3C4E))
[w0, w1] = self.getWordArray(charMap.get(char, 0x3C4E))
data.append(w0)
data.append(w1)
return data
def APPatchRom(self, romPatcher):
multiWorldLocations = {}
multiWorldItems = {}
# first apply the sm multiworld code patch named 'basepatch' (also has empty tables that we'll overwrite),
# + apply some patches from varia that we want to be always-on.
# basepatch and variapatches are both generated from https://github.com/lordlou/SMBasepatch
romPatcher.applyIPSPatch(os.path.join(os.path.dirname(__file__),
"data", "SMBasepatch_prebuilt", "multiworld-basepatch.ips"))
romPatcher.applyIPSPatch(os.path.join(os.path.dirname(__file__),
"data", "SMBasepatch_prebuilt", "variapatches.ips"))
symbols = get_sm_symbols(os.path.join(os.path.dirname(__file__),
"data", "SMBasepatch_prebuilt", "sm-basepatch-symbols.json"))
multiWorldLocations = []
multiWorldItems = []
idx = 0
self.playerIDMap = {}
playerIDCount = 0 # 0 is for "Archipelago" server
playerIDCount = 0 # 0 is for "Archipelago" server; highest possible = 200 (201 entries)
vanillaItemTypesCount = 21
for itemLoc in self.world.get_locations():
romPlayerID = itemLoc.item.player if itemLoc.item.player <= ROM_PLAYER_LIMIT else 0
if itemLoc.player == self.player and locationsDict[itemLoc.name].Id != None:
# this SM world can find this item: write full item data to tables and assign player data for writing
romPlayerID = itemLoc.item.player if itemLoc.item.player <= ROM_PLAYER_LIMIT else 0
if itemLoc.item.type in ItemManager.Items:
itemId = ItemManager.Items[itemLoc.item.type].Id
else:
itemId = ItemManager.Items['ArchipelagoItem'].Id + idx
multiWorldItems[0x029EA3 + idx*64] = self.convertToROMItemName(itemLoc.item.name)
multiWorldItems.append({"sym": symbols["message_item_names"],
"offset": (vanillaItemTypesCount + idx)*64,
"values": self.convertToROMItemName(itemLoc.item.name)})
idx += 1
if (romPlayerID > 0 and romPlayerID not in self.playerIDMap.keys()):
playerIDCount += 1
self.playerIDMap[romPlayerID] = playerIDCount
(w0, w1) = self.getWord(0 if itemLoc.item.player == self.player else 1)
(w2, w3) = self.getWord(itemId)
(w4, w5) = self.getWord(romPlayerID)
(w6, w7) = self.getWord(0 if itemLoc.item.advancement else 1)
multiWorldLocations[0x1C6000 + locationsDict[itemLoc.name].Id*8] = [w0, w1, w2, w3, w4, w5, w6, w7]
[w0, w1] = self.getWordArray(0 if itemLoc.item.player == self.player else 1)
[w2, w3] = self.getWordArray(itemId)
[w4, w5] = self.getWordArray(romPlayerID)
[w6, w7] = self.getWordArray(0 if itemLoc.item.advancement else 1)
multiWorldLocations.append({"sym": symbols["rando_item_table"],
"offset": locationsDict[itemLoc.name].Id*8,
"values": [w0, w1, w2, w3, w4, w5, w6, w7]})
if itemLoc.item.player == self.player:
elif itemLoc.item.player == self.player:
# this SM world owns the item: so in case the sending player might not have anything placed in this
# world to receive from it, assign them space in playerIDMap so that the ROM can display their name
# (SM item name not needed, as SM item type id will be in the message they send to this world live)
romPlayerID = itemLoc.player if itemLoc.player <= ROM_PLAYER_LIMIT else 0
if (romPlayerID > 0 and romPlayerID not in self.playerIDMap.keys()):
playerIDCount += 1
self.playerIDMap[romPlayerID] = playerIDCount
itemSprites = ["off_world_prog_item.bin", "off_world_item.bin"]
itemSprites = [{"fileName": "off_world_prog_item.bin",
"paletteSymbolName": "prog_item_eight_palette_indices",
"dataSymbolName": "offworld_graphics_data_progression_item"},
{"fileName": "off_world_item.bin",
"paletteSymbolName": "nonprog_item_eight_palette_indices",
"dataSymbolName": "offworld_graphics_data_item"}]
idx = 0
offworldSprites = {}
for fileName in itemSprites:
with open(Utils.local_path("lib", "worlds", "sm", "data", "custom_sprite", fileName) if Utils.is_frozen() else Utils.local_path("worlds", "sm", "data", "custom_sprite", fileName), 'rb') as stream:
offworldSprites = []
for itemSprite in itemSprites:
with open(os.path.join(os.path.dirname(__file__), "data", "custom_sprite", itemSprite["fileName"]), 'rb') as stream:
buffer = bytearray(stream.read())
offworldSprites[0x027882 + 10*(21 + idx) + 2] = buffer[0:8]
offworldSprites[0x049100 + idx*256] = buffer[8:264]
offworldSprites.append({"sym": symbols[itemSprite["paletteSymbolName"]],
"offset": 0,
"values": buffer[0:8]})
offworldSprites.append({"sym": symbols[itemSprite["dataSymbolName"]],
"offset": 0,
"values": buffer[8:264]})
idx += 1
openTourianGreyDoors = {0x07C823 + 5: [0x0C], 0x07C831 + 5: [0x0C]}
deathLink = {0x277f04: [self.world.death_link[self.player].value]}
remoteItem = {0x277f06: self.getWordArray(0b001 + (0b010 if self.remote_items else 0b000))}
deathLink = [{"sym": symbols["config_deathlink"],
"offset": 0,
"values": [self.world.death_link[self.player].value]}]
remoteItem = [{"sym": symbols["config_remote_items"],
"offset": 0,
"values": self.getWordArray(0b001 + (0b010 if self.remote_items else 0b000))}]
ownPlayerId = [{"sym": symbols["config_player_id"],
"offset": 0,
"values": self.getWordArray(self.player)}]
playerNames = {}
playerNameIDMap = {}
playerNames[0x1C5000] = "Archipelago".upper().center(16).encode()
playerNameIDMap[0x1C5800] = self.getWordArray(0)
playerNames = []
playerNameIDMap = []
playerNames.append({"sym": symbols["rando_player_table"],
"offset": 0,
"values": "Archipelago".upper().center(16).encode()})
playerNameIDMap.append({"sym": symbols["rando_player_id_table"],
"offset": 0,
"values": self.getWordArray(0)})
for key,value in self.playerIDMap.items():
playerNames[0x1C5000 + value * 16] = self.world.player_name[key][:16].upper().center(16).encode()
playerNameIDMap[0x1C5800 + value * 2] = self.getWordArray(key)
playerNames.append({"sym": symbols["rando_player_table"],
"offset": value * 16,
"values": self.world.player_name[key][:16].upper().center(16).encode()})
playerNameIDMap.append({"sym": symbols["rando_player_id_table"],
"offset": value * 2,
"values": self.getWordArray(key)})
patchDict = { 'MultiWorldLocations': multiWorldLocations,
'MultiWorldItems': multiWorldItems,
'offworldSprites': offworldSprites,
'openTourianGreyDoors': openTourianGreyDoors,
'deathLink': deathLink,
'remoteItem': remoteItem,
'ownPlayerId': ownPlayerId,
'PlayerName': playerNames,
'PlayerNameIDMap': playerNameIDMap}
# convert an array of symbolic byte_edit dicts like {"sym": symobj, "offset": 0, "values": [1, 0]}
# to a single rom patch dict like {0x438c: [1, 0], 0xa4a5: [0, 0, 0]} which varia will understand and apply
def resolve_symbols_to_file_offset_based_dict(byte_edits_arr) -> dict:
this_patch_as_dict = {}
for byte_edit in byte_edits_arr:
offset_within_rom_file = byte_edit["sym"]["offset_within_rom_file"] + byte_edit["offset"]
this_patch_as_dict[offset_within_rom_file] = byte_edit["values"]
return this_patch_as_dict
for patchname, byte_edits_arr in patchDict.items():
patchDict[patchname] = resolve_symbols_to_file_offset_based_dict(byte_edits_arr)
romPatcher.applyIPSPatchDict(patchDict)
openTourianGreyDoors = {0x07C823 + 5: [0x0C], 0x07C831 + 5: [0x0C]}
romPatcher.applyIPSPatchDict({'openTourianGreyDoors': openTourianGreyDoors})
# set rom name
# 21 bytes
from Main import __version__
self.romName = bytearray(f'SM{__version__.replace(".", "")[0:3]}_{self.player}_{self.world.seed:11}\0', 'utf8')[:21]
self.romName = bytearray(f'SM{__version__.replace(".", "")[0:3]}_{self.player}_{self.world.seed:11}', 'utf8')[:21]
self.romName.extend([0] * (21 - len(self.romName)))
# clients should read from 0x7FC0, the location of the rom title in the SNES header.
# duplicative ROM name at 0x1C4F00 is still written here for now, since people with archipelago pre-0.3.0 client installed will still be depending on this location for connecting to SM
romPatcher.applyIPSPatch('ROMName', { 'ROMName': {0x1C4F00 : self.romName, 0x007FC0 : self.romName} })
startItemROMAddressBase = 0x2FD8B9
startItemROMAddressBase = symbols["start_item_data_major"]["offset_within_rom_file"]
# current, base value or bitmask, max, base value or bitmask
startItemROMDict = {'ETank': [0x8, 0x64, 0xA, 0x64],
'Missile': [0xC, 0x5, 0xE, 0x5],
'Super': [0x10, 0x5, 0x12, 0x5],
'PowerBomb': [0x14, 0x5, 0x16, 0x5],
'Reserve': [0x1A, 0x64, 0x18, 0x64],
'Morph': [0x2, 0x4, 0x0, 0x4],
'Bomb': [0x3, 0x10, 0x1, 0x10],
'SpringBall': [0x2, 0x2, 0x0, 0x2],
'HiJump': [0x3, 0x1, 0x1, 0x1],
'Varia': [0x2, 0x1, 0x0, 0x1],
'Gravity': [0x2, 0x20, 0x0, 0x20],
'SpeedBooster': [0x3, 0x20, 0x1, 0x20],
'SpaceJump': [0x3, 0x2, 0x1, 0x2],
'ScrewAttack': [0x2, 0x8, 0x0, 0x8],
'Charge': [0x7, 0x10, 0x5, 0x10],
'Ice': [0x6, 0x2, 0x4, 0x2],
'Wave': [0x6, 0x1, 0x4, 0x1],
'Spazer': [0x6, 0x4, 0x4, 0x4],
'Plasma': [0x6, 0x8, 0x4, 0x8],
'Grapple': [0x3, 0x40, 0x1, 0x40],
'XRayScope': [0x3, 0x80, 0x1, 0x80]
# array for each item:
# offset within ROM table "start_item_data_major" of this item"s info (starting status)
# item bitmask or amount per pickup (BVOB = base value or bitmask),
# offset within ROM table "start_item_data_major" of this item"s info (starting maximum/starting collected items)
# current BVOB max
# ------- ---- ---
startItemROMDict = {"ETank": [ 0x8, 0x64, 0xA],
"Missile": [ 0xC, 0x5, 0xE],
"Super": [0x10, 0x5, 0x12],
"PowerBomb": [0x14, 0x5, 0x16],
"Reserve": [0x1A, 0x64, 0x18],
"Morph": [ 0x2, 0x4, 0x0],
"Bomb": [ 0x3, 0x10, 0x1],
"SpringBall": [ 0x2, 0x2, 0x0],
"HiJump": [ 0x3, 0x1, 0x1],
"Varia": [ 0x2, 0x1, 0x0],
"Gravity": [ 0x2, 0x20, 0x0],
"SpeedBooster": [ 0x3, 0x20, 0x1],
"SpaceJump": [ 0x3, 0x2, 0x1],
"ScrewAttack": [ 0x2, 0x8, 0x0],
"Charge": [ 0x7, 0x10, 0x5],
"Ice": [ 0x6, 0x2, 0x4],
"Wave": [ 0x6, 0x1, 0x4],
"Spazer": [ 0x6, 0x4, 0x4],
"Plasma": [ 0x6, 0x8, 0x4],
"Grapple": [ 0x3, 0x40, 0x1],
"XRayScope": [ 0x3, 0x80, 0x1]
# BVOB = base value or bitmask
}
mergedData = {}
hasETank = False
@ -379,48 +442,52 @@ class SMWorld(World):
hasPlasma = False
for startItem in self.startItems:
item = startItem.Type
if item == 'ETank': hasETank = True
if item == 'Spazer': hasSpazer = True
if item == 'Plasma': hasPlasma = True
if (item in ['ETank', 'Missile', 'Super', 'PowerBomb', 'Reserve']):
(currentValue, currentBase, maxValue, maxBase) = startItemROMDict[item]
if item == "ETank": hasETank = True
if item == "Spazer": hasSpazer = True
if item == "Plasma": hasPlasma = True
if (item in ["ETank", "Missile", "Super", "PowerBomb", "Reserve"]):
(currentValue, amountPerItem, maxValue) = startItemROMDict[item]
if (startItemROMAddressBase + currentValue) in mergedData:
mergedData[startItemROMAddressBase + currentValue] += currentBase
mergedData[startItemROMAddressBase + maxValue] += maxBase
mergedData[startItemROMAddressBase + currentValue] += amountPerItem
mergedData[startItemROMAddressBase + maxValue] += amountPerItem
else:
mergedData[startItemROMAddressBase + currentValue] = currentBase
mergedData[startItemROMAddressBase + maxValue] = maxBase
mergedData[startItemROMAddressBase + currentValue] = amountPerItem
mergedData[startItemROMAddressBase + maxValue] = amountPerItem
else:
(collected, currentBitmask, equipped, maxBitmask) = startItemROMDict[item]
(collected, bitmask, equipped) = startItemROMDict[item]
if (startItemROMAddressBase + collected) in mergedData:
mergedData[startItemROMAddressBase + collected] |= currentBitmask
mergedData[startItemROMAddressBase + equipped] |= maxBitmask
mergedData[startItemROMAddressBase + collected] |= bitmask
mergedData[startItemROMAddressBase + equipped] |= bitmask
else:
mergedData[startItemROMAddressBase + collected] = currentBitmask
mergedData[startItemROMAddressBase + equipped] = maxBitmask
mergedData[startItemROMAddressBase + collected] = bitmask
mergedData[startItemROMAddressBase + equipped] = bitmask
if hasETank:
# we are overwriting the starting energy, so add up the E from 99 (normal starting energy) rather than from 0
mergedData[startItemROMAddressBase + 0x8] += 99
mergedData[startItemROMAddressBase + 0xA] += 99
if hasSpazer and hasPlasma:
# de-equip spazer.
# otherwise, firing the unintended spazer+plasma combo would cause massive game glitches and crashes
mergedData[startItemROMAddressBase + 0x4] &= ~0x4
for key, value in mergedData.items():
if (key - startItemROMAddressBase > 7):
(w0, w1) = self.getWord(value)
[w0, w1] = self.getWordArray(value)
mergedData[key] = [w0, w1]
else:
mergedData[key] = [value]
startItemPatch = { 'startItemPatch': mergedData }
romPatcher.applyIPSPatch('startItemPatch', startItemPatch)
startItemPatch = { "startItemPatch": mergedData }
romPatcher.applyIPSPatch("startItemPatch", startItemPatch)
# commit all the changes we've made here to the ROM
romPatcher.commitIPS()
itemLocs = [ItemLocation(ItemManager.Items[itemLoc.item.type if itemLoc.item.type in ItemManager.Items else 'ArchipelagoItem'], locationsDict[itemLoc.name], True) for itemLoc in self.world.get_locations() if itemLoc.player == self.player]
romPatcher.writeItemsLocs(itemLocs)
romPatcher.writeItemsLocs(itemLocs)
itemLocs = [ItemLocation(ItemManager.Items[itemLoc.item.type], locationsDict[itemLoc.name] if itemLoc.name in locationsDict and itemLoc.player == self.player else self.DummyLocation(self.world.get_player_name(itemLoc.player) + " " + itemLoc.name), True) for itemLoc in self.world.get_locations() if itemLoc.item.player == self.player]
progItemLocs = [ItemLocation(ItemManager.Items[itemLoc.item.type], locationsDict[itemLoc.name] if itemLoc.name in locationsDict and itemLoc.player == self.player else self.DummyLocation(self.world.get_player_name(itemLoc.player) + " " + itemLoc.name), True) for itemLoc in self.world.get_locations() if itemLoc.item.player == self.player and itemLoc.item.advancement == True]

View File

@ -0,0 +1,689 @@
; wla symbolic information file
; generated by asar
[labels]
B8:8026 :neg_1_1
85:B9B4 :neg_1_2
85:B9E6 :neg_1_3
B8:C81F :neg_1_4
B8:C831 :neg_1_5
B8:C843 :neg_1_6
B8:800C :pos_1_0
B8:81DE :pos_1_1
84:FA6B :pos_1_2
84:FA75 :pos_1_3
B8:C862 :pos_1_4
B8:C86F :pos_1_5
B8:C87C :pos_1_6
85:FF00 CLIPCHECK
85:9900 CLIPLEN
85:990F CLIPLEN_end
85:990C CLIPLEN_no_multi
85:FF1D CLIPSET
B8:80EF COLLECTTANK
85:FF45 MISCFX
84:8BF2 NORMAL
85:FF4E SETFX
85:FF30 SOUNDFX
84:F9E0 SOUNDFX_84
85:FF3C SPECIALFX
84:F896 ammo_loop_table
84:F874 archipelago_chozo_item_plm
84:F878 archipelago_hidden_item_plm
84:F870 archipelago_visible_item_plm
84:F892 c_item
CE:FF04 config_deathlink
CE:FF00 config_flags
CE:FF00 config_multiworld
CE:FF08 config_player_id
CE:FF06 config_remote_items
CE:FF02 config_sprite
84:F894 h_item
84:F8AD i_chozo_item
84:F8B4 i_hidden_item
84:FA5A i_hidden_item_setup
B8:885C i_item_setup_shared
B8:8878 i_item_setup_shared_all_items
B8:8883 i_item_setup_shared_alwaysloaded
84:FA79 i_live_pickup
B8:817F i_live_pickup_multiworld
B8:81C4 i_live_pickup_multiworld_end
B8:819B i_live_pickup_multiworld_local_item_or_offworld
B8:81B0 i_live_pickup_multiworld_own_item
B8:81BC i_live_pickup_multiworld_own_item1
84:FA1E i_load_custom_graphics
84:FA39 i_load_custom_graphics_all_items
84:FA49 i_load_custom_graphics_alwaysloaded
84:FA61 i_load_rando_item
84:FA78 i_load_rando_item_end
84:F9F1 i_start_draw_loop
84:FA0A i_start_draw_loop_all_items
84:F9EC i_start_draw_loop_hidden
84:FA1C i_start_draw_loop_non_ammo_item
84:F9E5 i_start_draw_loop_visible_or_chozo
84:F8A6 i_visible_item
84:FA53 i_visible_item_setup
85:BA8A message_PlaceholderBig
85:BA0A message_char_table
85:BABC message_hook_tilemap_calc
85:BADC message_hook_tilemap_calc_msgbox_mwrecv
85:BACE message_hook_tilemap_calc_msgbox_mwsend
85:824C message_hook_tilemap_calc_normal
85:BAC9 message_hook_tilemap_calc_vanilla
85:9963 message_item_names
85:B8A3 message_item_received
85:B9A3 message_item_received_end
85:B7A3 message_item_sent
85:B8A3 message_item_sent_end
85:BA95 message_multiworld_init_new_messagebox_if_needed
85:BAB1 message_multiworld_init_new_messagebox_if_needed_msgbox_mwrecv
85:BAB1 message_multiworld_init_new_messagebox_if_needed_msgbox_mwsend
85:BAA9 message_multiworld_init_new_messagebox_if_needed_vanilla
85:B9A3 message_write_placeholders
85:B9A5 message_write_placeholders_adjust
85:BA04 message_write_placeholders_end
85:B9CA message_write_placeholders_loop
85:B9DC message_write_placeholders_notfound
85:B9DF message_write_placeholders_value_ok
B8:8092 mw_display_item_sent
B8:80FF mw_handle_queue
B8:8178 mw_handle_queue_end
B8:8101 mw_handle_queue_loop
B8:8151 mw_handle_queue_new_remote_item
B8:816D mw_handle_queue_next
B8:8163 mw_handle_queue_perform_receive
B8:81C8 mw_hook_main_game
B8:8011 mw_init
B8:8044 mw_init_end
B8:8000 mw_init_memory
B8:8083 mw_load_sram
B8:80B0 mw_receive_item
B8:80E8 mw_receive_item_end
B8:8070 mw_save_sram
B8:8049 mw_write_message
84:F888 nonprog_item_eight_palette_indices
89:9200 offworld_graphics_data_item
89:9100 offworld_graphics_data_progression_item
84:F972 p_chozo_item
84:F9A0 p_chozo_item_end
84:F98D p_chozo_item_loop
84:F999 p_chozo_item_trigger
84:F8FB p_etank_hloop
84:F8BB p_etank_loop
84:F9A6 p_hidden_item
84:F9D8 p_hidden_item_end
84:F9BD p_hidden_item_loop
84:F9A8 p_hidden_item_loop2
84:F9D1 p_hidden_item_trigger
84:F90F p_missile_hloop
84:F8CB p_missile_loop
84:F937 p_pb_hloop
84:F8EB p_pb_loop
84:F923 p_super_hloop
84:F8DB p_super_loop
84:F94B p_visible_item
84:F96E p_visible_item_end
84:F95B p_visible_item_loop
84:F967 p_visible_item_trigger
B8:81DF patch_load_multiworld
84:FA7E perform_item_pickup
84:F886 plm_graphics_entry_offworld_item
84:F87C plm_graphics_entry_offworld_progression_item
84:FA90 plm_sequence_generic_item_0_bitmask
84:F87E prog_item_eight_palette_indices
B8:E000 rando_item_table
B8:DC90 rando_player_id_table
B8:DE22 rando_player_id_table_end
B8:D000 rando_player_table
B8:CF00 rando_seed_data
B8:8800 sm_item_graphics
B8:882E sm_item_plm_pickup_sequence_pointers
B8:C81C start_item
B8:C800 start_item_data_major
B8:C808 start_item_data_minor
B8:C818 start_item_data_reserve
B8:C856 update_graphic
84:F890 v_item
[source files]
0000 e25029c5 main.asm
0001 06780555 ../common/nofanfare.asm
0002 e76d1f83 ../common/multiworld.asm
0003 613d24e1 ../common/itemextras.asm
0004 d6616c0c ../common/items.asm
0005 440b54fe ../common/startitem.asm
[rom checksum]
09b134c5
[addr-to-line mapping]
ff:ffff 0000:00000001
85:ff00 0001:0000010b
85:ff03 0001:0000010c
85:ff06 0001:0000010d
85:ff08 0001:0000010e
85:ff0b 0001:0000010f
85:ff0f 0001:00000110
85:ff12 0001:00000111
85:ff16 0001:00000112
85:ff19 0001:00000113
85:ff1c 0001:00000114
85:ff1d 0001:00000117
85:ff20 0001:00000118
85:ff24 0001:00000119
85:ff28 0001:0000011a
85:ff2b 0001:0000011c
85:ff2f 0001:0000011d
85:ff30 0001:00000120
85:ff34 0001:00000121
85:ff37 0001:00000122
85:ff3b 0001:00000123
85:ff3c 0001:00000126
85:ff40 0001:00000127
85:ff44 0001:00000128
85:ff45 0001:0000012b
85:ff49 0001:0000012c
85:ff4d 0001:0000012d
85:ff4e 0001:00000131
85:ff51 0001:00000132
85:ff54 0001:00000134
85:ff57 0001:00000135
85:ff58 0001:00000136
85:8490 0001:0000013a
85:9900 0001:0000013e
85:9901 0001:0000013f
85:9905 0001:00000140
85:9907 0001:00000141
85:990a 0001:00000142
85:990c 0001:00000144
85:990f 0001:00000146
85:9910 0001:00000147
82:e126 0001:0000014a
82:e12a 0001:0000014b
85:8089 0001:0000014e
84:8bf2 0001:00000152
84:8bf6 0001:00000153
84:8bf7 0001:00000153
b8:8000 0002:00000019
b8:8002 0002:0000001a
b8:8006 0002:0000001b
b8:8008 0002:0000001c
b8:800c 0002:00000020
b8:800e 0002:00000021
b8:8010 0002:00000022
b8:8011 0002:00000025
b8:8012 0002:00000025
b8:8013 0002:00000025
b8:8014 0002:00000025
b8:8015 0000:00000013
b8:8017 0002:00000029
b8:801b 0002:0000002a
b8:801e 0002:0000002b
b8:8020 0002:0000002d
b8:8023 0002:0000002e
b8:8026 0002:00000031
b8:802a 0002:00000032
b8:802e 0002:00000033
b8:8032 0002:00000034
b8:8036 0002:00000035
b8:8037 0002:00000035
b8:8038 0002:00000036
b8:803b 0002:00000037
b8:803d 0002:00000039
b8:8040 0002:0000003a
b8:8044 0002:0000003d
b8:8045 0002:0000003d
b8:8046 0002:0000003d
b8:8047 0002:0000003d
b8:8048 0002:0000003e
b8:8049 0002:00000043
b8:804a 0002:00000043
b8:804b 0002:00000044
b8:804c 0002:00000044
b8:804d 0002:00000045
b8:8051 0002:00000046
b8:8054 0002:00000046
b8:8055 0002:00000047
b8:8056 0002:00000048
b8:805a 0002:00000049
b8:805b 0002:0000004a
b8:805f 0002:0000004b
b8:8060 0002:0000004c
b8:8064 0002:0000004e
b8:8068 0002:0000004f
b8:8069 0002:00000050
b8:806d 0002:00000051
b8:806e 0002:00000051
b8:806f 0002:00000052
b8:8070 0002:00000055
b8:8071 0002:00000055
b8:8072 0000:00000013
b8:8074 0002:00000057
b8:8078 0002:00000058
b8:807c 0002:00000059
b8:807d 0002:00000059
b8:807e 0002:0000005b
b8:807f 0002:0000005c
b8:8082 0002:0000005d
b8:8083 0002:00000060
b8:8084 0002:00000060
b8:8085 0000:00000013
b8:8087 0002:00000062
b8:808b 0002:00000063
b8:808f 0002:00000064
b8:8090 0002:00000064
b8:8091 0002:00000065
b8:8092 0002:0000006a
b8:8094 0002:0000006b
b8:8096 0002:0000006e
b8:8099 0002:0000006f
b8:809b 0002:00000070
b8:809e 0002:00000071
b8:80a0 0002:00000072
b8:80a3 0002:00000073
b8:80a7 0002:00000074
b8:80a9 0002:00000075
b8:80ab 0002:00000076
b8:80ad 0002:00000077
b8:80af 0002:00000078
b8:80b0 0002:0000007c
b8:80b1 0002:0000007c
b8:80b2 0002:0000007d
b8:80b5 0002:0000007e
b8:80b7 0002:0000007f
b8:80ba 0002:00000080
b8:80bc 0002:00000081
b8:80bd 0002:00000082
b8:80be 0002:00000084
b8:80c1 0002:00000085
b8:80c3 0002:00000086
b8:80c6 0002:00000087
b8:80c7 0002:00000088
b8:80ca 0002:00000089
b8:80cb 0002:00000089
b8:80cc 0002:0000008a
b8:80d0 0002:0000008b
b8:80d1 0002:0000008c
b8:80d4 0002:0000008d
b8:80d8 0002:0000008e
b8:80da 0002:00000090
b8:80dd 0002:00000091
b8:80df 0002:00000092
b8:80e2 0002:00000093
b8:80e4 0002:00000095
b8:80e8 0002:00000097
b8:80ea 0002:00000098
b8:80ec 0002:00000099
b8:80ed 0002:00000099
b8:80ee 0002:0000009a
b8:80ef 0002:000000a5
b8:80f0 0002:000000a6
b8:80f4 0002:000000a7
b8:80f5 0002:000000a8
b8:80f9 0002:000000a9
b8:80fa 0002:000000ab
b8:80fe 0002:000000ac
b8:80ff 0002:000000de
b8:8100 0002:000000de
b8:8101 0002:000000e1
b8:8105 0002:000000e2
b8:8109 0002:000000e3
b8:810b 0002:000000e5
b8:810d 0002:000000e5
b8:810e 0002:000000e8
b8:8112 0002:000000e9
b8:8114 0002:000000ea
b8:8118 0002:000000eb
b8:811a 0002:000000ec
b8:811e 0002:000000ed
b8:8121 0002:000000ee
b8:8123 0002:000000ef
b8:8125 0002:000000f0
b8:8129 0002:000000f1
b8:812b 0002:000000f2
b8:812d 0002:000000f3
b8:8130 0002:000000f4
b8:8133 0002:000000f5
b8:8135 0002:000000f6
b8:813d 0002:000000fa
b8:813e 0002:000000fb
b8:813f 0002:000000fc
b8:8143 0002:000000ff
b8:8147 0002:00000100
b8:814b 0002:00000101
b8:814d 0002:00000103
b8:814e 0002:00000104
b8:814f 0002:00000105
b8:8151 0002:0000010a
b8:8152 0002:0000010b
b8:8156 0002:0000010e
b8:815a 0002:0000010f
b8:815e 0002:00000110
b8:8162 0002:00000111
b8:8163 0002:00000115
b8:8165 0002:00000116
b8:8168 0002:00000117
b8:816a 0002:00000118
b8:816d 0002:0000011b
b8:8171 0002:0000011c
b8:8172 0002:0000011d
b8:8176 0002:0000011f
b8:8178 0002:00000122
b8:817a 0002:00000123
b8:817c 0002:00000124
b8:817d 0002:00000124
b8:817e 0002:00000125
b8:817f 0002:00000129
b8:8180 0002:00000129
b8:8181 0002:00000129
b8:8182 0002:0000012a
b8:8186 0002:0000012b
b8:8189 0002:0000012b
b8:818a 0002:0000012d
b8:818e 0002:0000012e
b8:818f 0002:0000012f
b8:8193 0002:00000130
b8:8196 0002:00000131
b8:8198 0002:00000133
b8:819b 0002:00000136
b8:819f 0002:00000137
b8:81a3 0002:00000138
b8:81a5 0002:0000013a
b8:81a9 0002:0000013b
b8:81aa 0002:0000013d
b8:81ae 0002:0000013e
b8:81b0 0002:00000141
b8:81b4 0002:00000142
b8:81b7 0002:00000143
b8:81b9 0002:00000144
b8:81bc 0002:00000147
b8:81bd 0002:00000148
b8:81be 0002:00000149
b8:81c2 0002:0000014a
b8:81c4 0002:0000014d
b8:81c5 0002:0000014d
b8:81c6 0002:0000014d
b8:81c7 0002:0000014e
b8:81c8 0002:00000152
b8:81cc 0002:00000153
b8:81d0 0002:00000154
b8:81d2 0002:00000155
b8:81d6 0002:00000156
b8:81d9 0002:00000157
b8:81db 0002:00000158
b8:81de 0002:0000015a
b8:81df 0002:0000015d
b8:81e3 0002:0000015e
b8:81e4 0002:0000015f
b8:81e7 0002:00000160
b8:81eb 0002:00000162
b8:81ec 0002:00000163
b8:81ed 0002:00000164
b8:81ee 0002:00000165
b8:81ef 0002:00000166
8b:914a 0002:0000016b
81:80f7 0002:0000016e
81:8027 0002:00000171
82:8bb3 0002:00000174
85:b9a3 0002:0000020e
85:b9a4 0002:0000020e
85:b9a5 0002:00000211
85:b9a7 0002:00000212
85:b9ad 0002:00000212
85:b9ae 0002:00000213
85:b9b1 0002:00000214
85:b9b2 0002:00000215
85:b9b3 0002:00000215
85:b9b4 0002:00000219
85:b9b7 0002:0000021a
85:b9bb 0002:0000021b
85:b9bd 0002:0000021b
85:b9bf 0002:0000021c
85:b9c2 0002:0000021d
85:b9c4 0002:0000021f
85:b9c5 0002:00000220
85:b9c7 0002:00000224
85:b9ca 0002:00000226
85:b9cd 0002:00000227
85:b9cf 0002:00000228
85:b9d1 0002:00000229
85:b9d5 0002:0000022a
85:b9d7 0002:0000022b
85:b9d9 0002:0000022c
85:b9da 0002:0000022d
85:b9dc 0002:0000022f
85:b9df 0002:00000231
85:b9e2 0002:00000231
85:b9e3 0002:00000232
85:b9e6 0002:00000234
85:b9ea 0002:00000235
85:b9ed 0002:00000236
85:b9ee 0002:00000237
85:b9ef 0002:00000237
85:b9f0 0002:00000238
85:b9f4 0002:00000239
85:b9f5 0002:0000023a
85:b9f9 0002:0000023b
85:b9fb 0002:0000023c
85:b9fc 0002:0000023d
85:b9fd 0002:0000023e
85:ba00 0002:0000023f
85:ba02 0002:00000240
85:ba04 0002:00000243
85:ba05 0002:00000243
85:ba06 0002:00000244
85:ba09 0002:00000245
85:ba8a 0002:00000253
85:ba8c 0002:00000254
85:ba8f 0002:00000255
85:ba92 0002:00000256
85:ba95 0002:0000025e
85:ba96 0002:0000025f
85:ba98 0002:00000260
85:ba9b 0002:00000261
85:ba9d 0002:00000262
85:ba9f 0002:00000263
85:baa2 0002:00000264
85:baa4 0002:00000265
85:baa7 0002:00000266
85:baa9 0002:00000269
85:baaa 0002:0000026a
85:baab 0002:0000026b
85:baac 0002:0000026c
85:baae 0002:0000026d
85:baaf 0002:0000026e
85:bab0 0002:0000026f
85:bab1 0002:00000274
85:bab4 0002:00000275
85:bab5 0002:00000276
85:bab8 0002:00000277
85:bab9 0002:00000278
85:baba 0002:00000279
85:babb 0002:0000027a
85:babc 0002:00000285
85:babd 0002:00000286
85:babf 0002:00000287
85:bac2 0002:00000288
85:bac4 0002:00000289
85:bac7 0002:0000028a
85:bac9 0002:0000028d
85:baca 0002:0000028e
85:bacb 0002:0000028f
85:bacd 0002:00000290
85:bace 0002:00000292
85:bacf 0002:00000293
85:bad1 0002:00000294
85:bad4 0002:00000295
85:bad6 0002:00000296
85:bad9 0002:00000297
85:badb 0002:00000298
85:badc 0002:0000029a
85:badd 0002:0000029b
85:badf 0002:0000029c
85:bae2 0002:0000029d
85:bae4 0002:0000029e
85:bae7 0002:0000029f
85:bae9 0002:000002a0
85:8246 0002:000002a5
85:8249 0002:000002a6
85:824b 0002:000002a7
85:82f9 0002:000002ab
b8:885c 0003:00000045
b8:885d 0003:00000045
b8:885e 0003:00000046
b8:885f 0003:00000047
b8:8863 0003:00000048
b8:8866 0003:00000049
b8:8867 0003:0000004a
b8:886b 0003:0000004b
b8:886e 0003:0000004c
b8:8870 0003:0000004e
b8:8873 0003:0000004f
b8:8874 0003:0000004f
b8:8878 0003:00000051
b8:8879 0003:00000052
b8:887a 0003:00000053
b8:887e 0003:00000054
b8:8880 0003:00000056
b8:8881 0003:00000056
b8:8882 0003:00000057
b8:8883 0003:0000005a
b8:8884 0003:0000005a
b8:8885 0003:0000005b
b8:8886 0003:0000005c
b8:888a 0003:0000005d
84:f8a6 0004:00000051
84:f8a9 0004:00000052
84:f8ac 0004:00000053
84:f8ad 0004:00000056
84:f8b0 0004:00000057
84:f8b3 0004:00000058
84:f8b4 0004:0000005b
84:f8b7 0004:0000005c
84:f8ba 0004:0000005d
84:f9e0 0004:000000d4
84:f9e4 0004:000000d5
84:f9e5 0004:000000d8
84:f9e8 0004:000000d9
84:f9ea 0004:000000da
84:f9ec 0004:000000dd
84:f9ef 0004:000000de
84:f9f1 0004:000000e5
84:f9f2 0004:000000e6
84:f9f5 0004:000000e7
84:f9f8 0004:000000e7
84:f9f9 0004:000000e8
84:f9fd 0004:000000e9
84:fa00 0004:000000ea
84:fa02 0004:000000ec
84:fa05 0004:000000ed
84:fa06 0004:000000ee
84:fa0a 0004:000000f1
84:fa0d 0004:000000f2
84:fa0f 0004:000000f4
84:fa11 0004:000000f5
84:fa12 0004:000000f6
84:fa14 0004:000000f7
84:fa15 0004:000000f8
84:fa19 0004:000000f9
84:fa1a 0004:000000fa
84:fa1b 0004:000000fb
84:fa1c 0004:000000fe
84:fa1d 0004:000000ff
84:fa1e 0004:00000103
84:fa1f 0004:00000103
84:fa20 0004:00000103
84:fa21 0004:00000104
84:fa24 0004:00000105
84:fa27 0004:00000106
84:fa28 0004:00000107
84:fa2c 0004:00000108
84:fa2f 0004:00000109
84:fa31 0004:0000010b
84:fa34 0004:0000010c
84:fa35 0004:0000010c
84:fa39 0004:0000010e
84:fa3a 0004:00000110
84:fa3b 0004:00000111
84:fa3c 0004:00000112
84:fa40 0004:00000113
84:fa42 0004:00000114
84:fa43 0004:00000115
84:fa44 0004:00000116
84:fa47 0004:00000117
84:fa48 0004:00000118
84:fa49 0004:0000011b
84:fa4a 0004:0000011c
84:fa4c 0004:0000011d
84:fa4d 0004:0000011e
84:fa51 0004:0000011f
84:fa52 0004:00000120
84:fa53 0004:00000123
84:fa57 0004:00000124
84:fa5a 0004:00000127
84:fa5e 0004:00000128
84:fa61 0004:0000012c
84:fa64 0004:0000012c
84:fa66 0004:0000012d
84:fa69 0004:0000012e
84:fa6b 0004:0000012f
84:fa6e 0004:0000012f
84:fa70 0004:00000130
84:fa73 0004:00000131
84:fa75 0004:00000132
84:fa78 0004:00000135
84:fa79 0004:00000139
84:fa7d 0004:0000013a
84:fa7e 0004:0000013f
84:fa7f 0004:00000140
84:fa80 0004:00000141
84:fa81 0004:00000141
84:fa82 0004:00000145
84:fa86 0004:00000146
84:fa87 0004:00000147
84:fa88 0004:00000148
84:fa89 0004:00000148
84:fa8a 0004:00000149
84:fa8d 0004:0000014a
84:fa8e 0004:0000014b
84:fa8f 0004:0000014c
81:b303 0005:00000003
81:b307 0005:00000004
81:b308 0005:00000005
b8:c81c 0005:00000016
b8:c81f 0005:00000018
b8:c823 0005:00000019
b8:c827 0005:0000001a
b8:c828 0005:0000001b
b8:c829 0005:0000001c
b8:c82c 0005:0000001d
b8:c82e 0005:0000001e
b8:c831 0005:00000020
b8:c835 0005:00000021
b8:c839 0005:00000022
b8:c83a 0005:00000023
b8:c83b 0005:00000024
b8:c83e 0005:00000025
b8:c840 0005:00000026
b8:c843 0005:00000028
b8:c847 0005:00000029
b8:c84b 0005:0000002a
b8:c84c 0005:0000002b
b8:c84d 0005:0000002c
b8:c850 0005:0000002d
b8:c852 0005:0000002e
b8:c855 0005:00000031
b8:c856 0005:00000034
b8:c859 0005:00000035
b8:c85b 0005:00000036
b8:c85e 0005:00000037
b8:c862 0005:00000039
b8:c866 0005:0000003a
b8:c869 0005:0000003b
b8:c86b 0005:0000003c
b8:c86f 0005:0000003e
b8:c873 0005:0000003f
b8:c876 0005:00000040
b8:c878 0005:00000041
b8:c87c 0005:00000043
b8:c880 0005:00000044

View File

@ -0,0 +1,141 @@
{
"CLIPCHECK": "85:FF00",
"CLIPLEN": "85:9900",
"CLIPLEN_end": "85:990F",
"CLIPLEN_no_multi": "85:990C",
"CLIPSET": "85:FF1D",
"COLLECTTANK": "B8:80EF",
"MISCFX": "85:FF45",
"NORMAL": "84:8BF2",
"SETFX": "85:FF4E",
"SOUNDFX": "85:FF30",
"SOUNDFX_84": "84:F9E0",
"SPECIALFX": "85:FF3C",
"ammo_loop_table": "84:F896",
"archipelago_chozo_item_plm": "84:F874",
"archipelago_hidden_item_plm": "84:F878",
"archipelago_visible_item_plm": "84:F870",
"c_item": "84:F892",
"config_deathlink": "CE:FF04",
"config_flags": "CE:FF00",
"config_multiworld": "CE:FF00",
"config_player_id": "CE:FF08",
"config_remote_items": "CE:FF06",
"config_sprite": "CE:FF02",
"h_item": "84:F894",
"i_chozo_item": "84:F8AD",
"i_hidden_item": "84:F8B4",
"i_hidden_item_setup": "84:FA5A",
"i_item_setup_shared": "B8:885C",
"i_item_setup_shared_all_items": "B8:8878",
"i_item_setup_shared_alwaysloaded": "B8:8883",
"i_live_pickup": "84:FA79",
"i_live_pickup_multiworld": "B8:817F",
"i_live_pickup_multiworld_end": "B8:81C4",
"i_live_pickup_multiworld_local_item_or_offworld": "B8:819B",
"i_live_pickup_multiworld_own_item": "B8:81B0",
"i_live_pickup_multiworld_own_item1": "B8:81BC",
"i_load_custom_graphics": "84:FA1E",
"i_load_custom_graphics_all_items": "84:FA39",
"i_load_custom_graphics_alwaysloaded": "84:FA49",
"i_load_rando_item": "84:FA61",
"i_load_rando_item_end": "84:FA78",
"i_start_draw_loop": "84:F9F1",
"i_start_draw_loop_all_items": "84:FA0A",
"i_start_draw_loop_hidden": "84:F9EC",
"i_start_draw_loop_non_ammo_item": "84:FA1C",
"i_start_draw_loop_visible_or_chozo": "84:F9E5",
"i_visible_item": "84:F8A6",
"i_visible_item_setup": "84:FA53",
"message_PlaceholderBig": "85:BA8A",
"message_char_table": "85:BA0A",
"message_hook_tilemap_calc": "85:BABC",
"message_hook_tilemap_calc_msgbox_mwrecv": "85:BADC",
"message_hook_tilemap_calc_msgbox_mwsend": "85:BACE",
"message_hook_tilemap_calc_normal": "85:824C",
"message_hook_tilemap_calc_vanilla": "85:BAC9",
"message_item_names": "85:9963",
"message_item_received": "85:B8A3",
"message_item_received_end": "85:B9A3",
"message_item_sent": "85:B7A3",
"message_item_sent_end": "85:B8A3",
"message_multiworld_init_new_messagebox_if_needed": "85:BA95",
"message_multiworld_init_new_messagebox_if_needed_msgbox_mwrecv": "85:BAB1",
"message_multiworld_init_new_messagebox_if_needed_msgbox_mwsend": "85:BAB1",
"message_multiworld_init_new_messagebox_if_needed_vanilla": "85:BAA9",
"message_write_placeholders": "85:B9A3",
"message_write_placeholders_adjust": "85:B9A5",
"message_write_placeholders_end": "85:BA04",
"message_write_placeholders_loop": "85:B9CA",
"message_write_placeholders_notfound": "85:B9DC",
"message_write_placeholders_value_ok": "85:B9DF",
"mw_display_item_sent": "B8:8092",
"mw_handle_queue": "B8:80FF",
"mw_handle_queue_end": "B8:8178",
"mw_handle_queue_loop": "B8:8101",
"mw_handle_queue_new_remote_item": "B8:8151",
"mw_handle_queue_next": "B8:816D",
"mw_handle_queue_perform_receive": "B8:8163",
"mw_hook_main_game": "B8:81C8",
"mw_init": "B8:8011",
"mw_init_end": "B8:8044",
"mw_init_memory": "B8:8000",
"mw_load_sram": "B8:8083",
"mw_receive_item": "B8:80B0",
"mw_receive_item_end": "B8:80E8",
"mw_save_sram": "B8:8070",
"mw_write_message": "B8:8049",
"nonprog_item_eight_palette_indices": "84:F888",
"offworld_graphics_data_item": "89:9200",
"offworld_graphics_data_progression_item": "89:9100",
"p_chozo_item": "84:F972",
"p_chozo_item_end": "84:F9A0",
"p_chozo_item_loop": "84:F98D",
"p_chozo_item_trigger": "84:F999",
"p_etank_hloop": "84:F8FB",
"p_etank_loop": "84:F8BB",
"p_hidden_item": "84:F9A6",
"p_hidden_item_end": "84:F9D8",
"p_hidden_item_loop": "84:F9BD",
"p_hidden_item_loop2": "84:F9A8",
"p_hidden_item_trigger": "84:F9D1",
"p_missile_hloop": "84:F90F",
"p_missile_loop": "84:F8CB",
"p_pb_hloop": "84:F937",
"p_pb_loop": "84:F8EB",
"p_super_hloop": "84:F923",
"p_super_loop": "84:F8DB",
"p_visible_item": "84:F94B",
"p_visible_item_end": "84:F96E",
"p_visible_item_loop": "84:F95B",
"p_visible_item_trigger": "84:F967",
"patch_load_multiworld": "B8:81DF",
"perform_item_pickup": "84:FA7E",
"plm_graphics_entry_offworld_item": "84:F886",
"plm_graphics_entry_offworld_progression_item": "84:F87C",
"plm_sequence_generic_item_0_bitmask": "84:FA90",
"prog_item_eight_palette_indices": "84:F87E",
"rando_item_table": "B8:E000",
"rando_player_id_table": "B8:DC90",
"rando_player_id_table_end": "B8:DE22",
"rando_player_table": "B8:D000",
"rando_seed_data": "B8:CF00",
"sm_item_graphics": "B8:8800",
"sm_item_plm_pickup_sequence_pointers": "B8:882E",
"start_item": "B8:C81C",
"start_item_data_major": "B8:C800",
"start_item_data_minor": "B8:C808",
"start_item_data_reserve": "B8:C818",
"update_graphic": "B8:C856",
"v_item": "84:F890",
"ITEM_RAM": "7E:09A2",
"SRAM_MW_ITEMS_RECV": "70:2000",
"SRAM_MW_ITEMS_RECV_RPTR": "70:2600",
"SRAM_MW_ITEMS_RECV_WPTR": "70:2602",
"SRAM_MW_ITEMS_RECV_SPTR": "70:2604",
"SRAM_MW_ITEMS_SENT_RPTR": "70:2680",
"SRAM_MW_ITEMS_SENT_WPTR": "70:2682",
"SRAM_MW_ITEMS_SENT": "70:2700",
"SRAM_MW_INITIALIZED": "70:26fe",
"CollectedItems": "7E:D86E"
}

View File

@ -0,0 +1,3 @@
SMBasepatch_prebuilt:
- comes exactly from build/vanilla/ directory of https://github.com/lordlou/SMBasepatch
- keep it in sync with the basepatch repo; do not modify the contents in this repo alone!

View File

@ -24,8 +24,6 @@ class RomPatcher:
'Removes_Gravity_Suit_heat_protection',
# door ASM to skip G4 cutscene when all 4 bosses are dead
'g4_skip.ips',
# basepatch is generated from https://github.com/lordlou/SMBasepatch
'basepatch.ips'
],
# VARIA tweaks
'VariaTweaks' : ['WS_Etank', 'LN_Chozo_SpaceJump_Check_Disable', 'ln_chozo_platform.ips', 'bomb_torizo.ips'],