Ejemplo n.º 1
0
    tilesets.get_tileset("MainDialog2", override_offset=0x80),
    tilesets.get_tileset("Special", override_offset=0xE0)
])

kanji = tilesets.get_tileset("Kanji", override_offset=0x0)

with open("./game/src/version/ptrlist_data.asm", "w") as datafile:
    datafile.write(
        f'INCLUDE "build/ptrlists/ptrlist_data_constants_{{GAMEVERSION}}.asm"\n\n'
    )
    for l in list_map:
        addr, spp, term, fix_len, print_hex, null_indicator, data_prefix = list_map[
            l]
        if isinstance(addr, tuple):
            bank = addr[0]
            addr = utils.rom2realaddr(addr)
        else:
            bank = utils.real2romaddr(addr)[0]

        datafile.write(
            f'SECTION "Pointer List - {l}", ROMX[${utils.real2romaddr(addr)[1]:04x}], BANK[${bank:02x}]\n'
        )
        datafile.write(f'PtrList{l}::\n')
        datafile.write(f'  INCBIN c{l}\n\n')

        entries = OrderedDict()
        with open(f"./text/ptrlists/{l}.txt", "w", encoding="utf-8") as output:
            output.write(str(list_map[l][1:]) + "\n")
            count_written = False
            for version_suffix in roms:
                with open(
Ejemplo n.º 2
0
	ptrs = [utils.read_short(rom) for i in range(0, count)]
	data = {}
	for ptr in ptrs:
		rom.seek(ptr) # Bank 0, no need to convert addresses
		# (Bank, Pointer, VRAM Offset, Name)
		if namefile: # We assume the table file not existing is fine
			nametable[ptr] = "{:04X}".format(ptr)
			namefile.write("{:04X}={}\n".format(ptr, nametable[ptr]))
		data[ptr] = (utils.read_byte(rom), utils.read_short(rom), utils.read_short(rom), nametable[ptr])
	output.write('INCLUDE "game/src/common/macros.asm"\n\n')
	output.write('SECTION "Tileset Table", ROM0[${:04X}]\n'.format(tiletable))
	output.write('TilesetTable::\n')
	for i in ptrs:
		output.write("  dw TilesetInfo{}\n".format(data[i][3]))
	output.write("TilesetTableEnd::\n");
	with open("game/src/gfx/tileset_files.asm", "w") as outputf:
		for ptr in sorted(data):
			with open("game/tilesets/{}.malias".format(data[ptr][3]),"wb") as compressed, open("text/tilesets/{}.2bpp".format(data[ptr][3]),"wb") as uncompressed:
				f = tilesets.decompress_tileset(rom, utils.rom2realaddr((data[ptr][0],data[ptr][1])))
				uncompressed.write(bytearray(f[0]))
				compressed.write(bytearray(f[1]))
				output.write('SECTION "TilesetInfo {0}", ROM0[${1:04X}]\n'.format(data[ptr][3], ptr))
				output.write("TilesetInfo{}::\n".format(data[ptr][3]))
				output.write('  dbww BANK(Tileset{0}), Tileset{0}, ${1:04X}\n'.format(data[ptr][3], data[ptr][2]))
				outputf.write('SECTION "Tileset Data {0}", ROMX[${1:04X}], BANK[${2:02X}]\n'.format(data[ptr][3], data[ptr][1], data[ptr][0]))
				outputf.write("Tileset{}::\n".format(data[ptr][3]))
				outputf.write("TilesetStart{}::\n".format(data[ptr][3]))
				outputf.write('  INCBIN "build/tilesets/{}.malias"\n'.format(data[ptr][3]))
				outputf.write("TilesetEnd{}::\n\n".format(data[ptr][3]))
		output.write("TilesetInfoEnd::\n");
Ejemplo n.º 3
0
sys.path.append(os.path.join(os.path.dirname(__file__), 'common'))
from common import utils, tilesets

rom_info = ("baserom_parts_collection.gb", "parts_collection", (0x16, 0x539b),
            63)  # [ROM File, Version Suffix, Credits Ptr, Entry Count]
table = utils.merge_dicts([
    tilesets.get_tileset("MainSpecial"),
    tilesets.get_tileset("MainDialog"),
    tilesets.get_tileset("dakuten", override_offset=0x0)
])

filename = rom_info[0]
suffix = rom_info[1]
text_ptr_table = rom_info[2] if isinstance(
    rom_info[2], int) else utils.rom2realaddr(rom_info[2])
bank = utils.real2romaddr(text_ptr_table)[0]
entry_count = rom_info[3]

with open(filename, 'rb') as rom, open(f"./text/credits/Credits.csv",
                                       "w",
                                       encoding="utf-8") as fp:
    writer = csv.writer(fp,
                        lineterminator='\n',
                        delimiter=',',
                        quotechar='"',
                        quoting=csv.QUOTE_MINIMAL)
    writer.writerow(["Pointer", "VRAMOffset", "Original", "Translated"])

    rom.seek(text_ptr_table)
    pointers = [(rom.tell(), utils.read_short(rom))
Ejemplo n.º 4
0
default_version = roms[0][1]
nametable = OrderedDict()
namefile = None
realptr_key_map = {}

# Map real address to a defined name
if os.path.exists("scripts/res/meta_tileset_names.tbl"):
    nametable = utils.read_table("scripts/res/meta_tileset_names.tbl")
else:
    namefile = open("scripts/res/meta_tileset_names.tbl", "w")

# M3 keeps source addresses in a table in bank 0 and banks + destination info in a separate table
# This is pretty much a single table that's been split over 2 banks, and there may be duplicate tileset entries
count = ((terminator - tiletable) // 2)
terminator_key = utils.rom2realaddr((0, terminator))
nametable[terminator] = "TilesetSourceAddressTableEnd"

tileset_data = OrderedDict()
tileset_metadata = {}

common_tilesets = []
unique_pointer_and_tilesets = []
unique_tilesets = []
unique_pointers = []
missing_pointers = []
tileset_alias = {}
for version in roms:
    ver = version[1]
    realptr_key_map[ver] = OrderedDict()
    realptr_key_map[ver][terminator_key] = terminator
Ejemplo n.º 5
0
        table[0xce] = SpecialCharacter('S') # Text Speed
        table[0xcf] = SpecialCharacter("CF", bts=0, always_print=True) # Create new text box
        table[0xd0] = SpecialCharacter("&", bts=2, names=name_table) # Pull text from RAM
        table[0xd1] = SpecialCharacter("D1", bts=0, always_print=True) # New page (keeps portrait)
        # Portrait, [Orientation:{00, 01, 10, 11, FF}][Character:1][Expression:1]
        table[0xd2] = SpecialCharacter('@', bts=3, parser=lambda x: "{},{:02X},{:02X}".format({0x00: 'LL', 0x01: 'LR', 0x10: 'RL', 0x11: 'RR', 0xFF: 'CC' }[utils.read_byte(x)], utils.read_byte(x), utils.read_byte(x)) )
        table[0xd3] = SpecialCharacter('K', print_control_code=False, parser=lambda x: kanji[utils.read_byte(x)]) # Kanji

        terminator_pointers = []

        for i, entry in enumerate([t for t in text_ptrs if t[0] != 0]):
            csv_filename = f"./text/dialog/TextSection{i:02}.csv"
            text_version_specific[csv_filename] = {}
            text_shifted_pointers[csv_filename] = {}
            text_unused[csv_filename] = {}
            realaddr = utils.rom2realaddr(entry)
            rom.seek(realaddr)
            end = utils.rom2realaddr((entry[0], utils.read_short(rom)))
            rom.seek(end - 2)
            terminator_pointers.append(utils.rom2realaddr((entry[0], utils.read_short(rom))))
            rom.seek(realaddr + 2)
            pointers = OrderedDict()
            pointer_lengths = OrderedDict()
            pointer_lengths_key = realaddr
            pointer_lengths[pointer_lengths_key] = end
            pointers[realaddr] = end # Treat pointers[0] as the end of the list of addresses
            reverse_map = {}
            realaddr = rom.tell()
            last_ptr = 0
            if realaddr >= end: # An empty bank, so clear pointers to avoid any parsing but still create the csv file
                pointer_lengths.clear()
Ejemplo n.º 6
0
    # Medarotters have a 3-byte prefix before the names
    'Medarotters': ((0x17, 0x63e2), 0x50, 80, 3),
})

tileset = utils.merge_dicts([
    tilesets.get_tileset("MainSpecial"),
    tilesets.get_tileset("MainDialog"),
    tilesets.get_tileset("dakuten", override_offset=0x0)
])

with open("baserom_parts_collection.gb", "rb") as rom:
    for l in list_map:
        addr, term, n, prefixlen = list_map[l]
        if isinstance(addr, tuple):
            bank = addr[0]
            addr = utils.rom2realaddr(addr)
        else:
            bank = utils.real2romaddr(addr)[0]
        rom.seek(addr)
        with open('text/ptrlists/{}.txt'.format(l), 'w',
                  encoding="utf-8") as output:
            output.write(f"({term},{prefixlen})\n")
            ptrs = [utils.read_short(rom) for i in range(0, n)]
            for ptr in ptrs:
                rom.seek(utils.rom2realaddr((bank, ptr)))
                prefix = [utils.read_byte(rom) for i in range(0, prefixlen)]
                # If the first 2 are 00, there's no data
                if prefixlen > 0 and prefix[0] == 0x0:
                    b = []
                else:
                    b = list(iter(partial(utils.read_byte, rom), term))
Ejemplo n.º 7
0
        if i == terminator:
            output.write(f"  dw TilesetInfoEnd ; {x:02X}\n")
        else:
            output.write(f"  dw TilesetInfo{data[i][3]} ; {x:02X}\n")
            offsetfile.write(f"{x:02X}={data[i][2]:04X}\n")
            indexfile.write(f"{x:02X}={data[i][3]}\n")
    output.write("TilesetTableEnd::\n")
    with open("game/src/gfx/tileset_files.asm", "w") as outputf:
        for ptr in sorted(data):
            output.write('SECTION "TilesetInfo {0}", ROM0[${1:04X}]\n'.format(
                data[ptr][3], ptr))
            output.write("TilesetInfo{}::\n".format(data[ptr][3]))
            with open("game/tilesets/{}.malias".format(data[ptr][3]),"wb") as compressed, \
                    open("text/tilesets/{}.png".format(data[ptr][3]),"wb") as uncompressed:
                f = tilesets.decompress_tileset(
                    rom, utils.rom2realaddr((data[ptr][0], data[ptr][1])))
                width, height, palette, greyscale, bitdepth, px_map = gfx.convert_2bpp_to_png(
                    f[0])
                w = png.Writer(width,
                               height,
                               palette=palette,
                               compression=9,
                               greyscale=greyscale,
                               bitdepth=bitdepth)
                w.write(uncompressed, px_map)
                compressed.write(bytearray(f[1]))

                output.write(
                    '  dbww BANK(Tileset{0}), Tileset{0}, ${1:04X}\n'.format(
                        data[ptr][3], data[ptr][2]))
                outputf.write(
Ejemplo n.º 8
0
                0xFF: 'CC'
            }[utils.read_byte(x)], utils.read_byte(x), utils.read_byte(x)))
        table[0xd3] = SpecialCharacter(
            'K',
            print_control_code=False,
            parser=lambda x: kanji[utils.read_byte(x)])  # Kanji

        terminator_pointers = []

        for i, entry in enumerate([t for t in text_ptrs if t[0] != 0]):
            csv_filename = os.path.join(text_src_path,
                                        f"TextSection{i:02}.csv")
            text_version_specific[csv_filename] = {}
            text_shifted_pointers[csv_filename] = {}
            text_unused[csv_filename] = {}
            realaddr = utils.rom2realaddr(entry)
            rom.seek(realaddr)
            end = utils.rom2realaddr((entry[0], utils.read_short(rom)))
            rom.seek(end - 2)
            terminator_pointers.append(
                utils.rom2realaddr((entry[0], utils.read_short(rom))))
            rom.seek(realaddr + 2)
            pointers = OrderedDict()
            pointer_lengths = OrderedDict()
            pointer_lengths_key = realaddr
            pointer_lengths[pointer_lengths_key] = end
            pointers[
                realaddr] = end  # Treat pointers[0] as the end of the list of addresses
            reverse_map = {}
            realaddr = rom.tell()
            last_ptr = 0
Ejemplo n.º 9
0
VERSIONS = [("baserom_kabuto.gb", "kabuto"),
            ("baserom_kuwagata.gb", "kuwagata")]

tileset = utils.merge_dicts([
    utils.read_table("scripts/res/tileset_MainDialog.tbl"),
    utils.read_table("scripts/res/tileset_MainSpecial.tbl"),
    utils.read_table("scripts/res/tileset_BoldLetters.tbl"),
    utils.read_table("scripts/res/dakuten.tbl")
])
for lst in list_map:
    merged_dict = {}
    addr, length, term, pad, n = list_map[lst]
    for version in VERSIONS:
        with open(version[0], "rb") as rom:
            if isinstance(addr, tuple):
                addr = utils.rom2realaddr(addr)
            rom.seek(addr)
            for i in range(0, n):
                c = 0
                for l in length if isinstance(length, tuple) else (length, ):
                    b = list(iter(partial(utils.read_byte, rom), term))
                    rom.seek(l - len(b) - 1, 1)  # Account for the terminator
                    value = "{}\n".format("".join(
                        utils.bin2txt(bytearray(b), tileset)))
                    key = "{:03}_{:02}".format(i, c)
                    c += 1
                    if key in merged_dict and merged_dict[
                            key] != value:  # Just assume 2 versions, so the existence of a previous entry must belong to the 'default' version
                        merged_dict[key + VERSIONS[0][1]] = "[{}]{}".format(
                            VERSIONS[0][1], merged_dict[key])
                        del merged_dict[key]
Ejemplo n.º 10
0
#!/bin/python

# Script to initially dump tilemaps, shouldn't really need to be run anymore, and is mainly here as a reference

import os, sys
from functools import partial

sys.path.append(os.path.join(os.path.dirname(__file__), 'common'))
from common import utils, tilemaps, tilesets

# tilemap bank is 1e (0x78000)
BANK_SIZE = 0x4000
BANK = 0x1e
BASE = 0x4000
BASE_ADDR = utils.rom2realaddr((BANK, BASE))
MAX_ADDR = BASE_ADDR + BANK_SIZE - 1

tilemap_ptr = {}
tilemap_bytes = {}
tilemap_files = []
TERMINATOR = 0

with open("baserom_parts_collection.gb", "rb") as rom:
    rom.seek(BASE_ADDR)
    ptr = utils.read_short(rom)
    tilemap_ptr[0] = ptr
    end = utils.rom2realaddr((BANK, ptr))
    i = 1
    while rom.tell() < end:  # The first tilemap is where the table should end
        tilemap_ptr[i] = utils.read_short(rom)
        i += 1
Ejemplo n.º 11
0
    duplicate_map = {}  # [version] -> [identifier] -> identity
    version_specific_ids = set()
    basename_map = OrderedDict()

    version_suffixes = [i[1] for i in roms]
    for versionidx, version in enumerate(roms):
        rom_filename = version[0]
        ver = version[1]
        tilemap_data[versionidx] = OrderedDict()
        duplicate_map[versionidx] = {}
        with open(rom_filename, "rb") as rom:
            pointers = None

            for tableidx, tableptr in enumerate(tilemap_tables):
                current_bank = tableptr[0]
                rom.seek(utils.rom2realaddr(tableptr))

                pointers = [utils.read_short(rom)]
                # Assume the end of the table is the first data pointer
                table_end = utils.rom2realaddr((current_bank, pointers[0]))

                while rom.tell() < table_end:
                    pointers.append(utils.read_short(rom))

                # Empty spaces in the table are the terminator, but we need to verify
                terminator = pointers[-1]
                # A hack to guess if something is a terminator or not
                is_terminator = pointers[-2] == terminator
                duplicate_pointers = []
                for pointeridx, pointer in enumerate(pointers):
                    realaddr = utils.rom2realaddr((current_bank, pointer))