126 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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)) |