Archipelago/worlds/ladx/LADXR/patches/bank34.py

126 lines
3.6 KiB
Python

import os
import binascii
import pkgutil
from ..assembler import ASM
from ..utils import formatText
ItemNameLookupTable = 0x0100
ItemNameLookupSize = 2
TotalRoomCount = 0x316
AnItemText = "an item"
ItemNameStringBufferStart = ItemNameLookupTable + \
TotalRoomCount * ItemNameLookupSize
def addBank34(rom, item_list):
rom.patch(0x34, 0x0000, ItemNameLookupTable, ASM("""
; Get the pointer in the lookup table, doubled as it's two bytes
ld hl, $2080
push de
call OffsetPointerByRoomNumber
pop de
add hl, hl
ldi a, [hl] ; hl = *hl
ld h, [hl]
ld l, a
; If there's no data, bail
ld a, l
or h
jp z, SwitchBackTo3E
ld de, wCustomMessage
; Copy "Got " to de
ld a, 71
ld [de], a
inc de
ld a, 111
ld [de], a
inc de
ld a, 116
ld [de], a
inc de
ld a, 32
ld [de], a
inc de
; Copy in our item name
call MessageCopyString
SwitchBackTo3E:
; Bail
ld a, $3e ; Set bank number
jp $080C ; switch bank
; this should be shared but I got link errors
OffsetPointerByRoomNumber:
ldh a, [$F6] ; map room
ld e, a
ld a, [$DBA5] ; is indoor
ld d, a
ldh a, [$F7] ; mapId
cp $FF
jr nz, .notColorDungeon
ld d, $03
jr .notCavesA
.notColorDungeon:
cp $1A
jr nc, .notCavesA
cp $06
jr c, .notCavesA
inc d
.notCavesA:
add hl, de
ret
""" + pkgutil.get_data(__name__, os.path.join("bank3e.asm", "message.asm")).decode().replace("\r", ""), 0x4000), fill_nop=True)
nextItemLookup = ItemNameStringBufferStart
nameLookup = {
}
name = AnItemText
def add_or_get_name(name):
nonlocal nextItemLookup
if name in nameLookup:
return nameLookup[name]
if len(name) + 1 + nextItemLookup >= 0x4000:
return nameLookup[AnItemText]
asm = ASM(f'db "{name}", $ff\n')
rom.patch(0x34, nextItemLookup, None, asm)
patch_len = len(binascii.unhexlify(asm))
nameLookup[name] = nextItemLookup + 0x4000
nextItemLookup += patch_len
return nameLookup[name]
item_text_addr = add_or_get_name(AnItemText)
#error_text_addr = add_or_get_name("Please report this check to #bug-reports in the AP discord")
def swap16(x):
assert x <= 0xFFFF
return (x >> 8) | ((x & 0xFF) << 8)
def to_hex_address(x):
return f"{swap16(x):04x}"
# Set defaults for every room
for i in range(TotalRoomCount):
rom.patch(0x34, ItemNameLookupTable + i *
ItemNameLookupSize, None, to_hex_address(0))
for item in item_list:
if not item.custom_item_name:
continue
assert item.room < TotalRoomCount, item.room
# Item names of exactly 255 characters will cause overwrites to occur in the text box
# assert len(item.custom_item_name) < 0x100
# Custom text is only 95 bytes long, restrict to 50
addr = add_or_get_name(item.custom_item_name[:50])
rom.patch(0x34, ItemNameLookupTable + item.room *
ItemNameLookupSize, None, to_hex_address(addr))
if item.extra:
rom.patch(0x34, ItemNameLookupTable + item.extra *
ItemNameLookupSize, None, to_hex_address(addr))