Refactor struct handling a bit

This commit is contained in:
Luke Hubmayer-Werner 2023-07-22 19:08:46 +09:30
parent b4544e5fb8
commit 2ed6ee5f50
3 changed files with 98 additions and 64 deletions

View File

@ -38,6 +38,7 @@ from includes.snes import *
import includes.ff5.const as const import includes.ff5.const as const
from includes.ff5.strings import StringBlock, RPGe_Dialogue_Width from includes.ff5.strings import StringBlock, RPGe_Dialogue_Width
from includes.ff5.strings import Strings as FFVStrings from includes.ff5.strings import Strings as FFVStrings
import includes.ff5.structs as FFVStructs
import includes.ff4 as ff4 import includes.ff4 as ff4
import includes.ff5 as ff5 import includes.ff5 as ff5
import includes.ff6 as ff6 import includes.ff6 as ff6
@ -87,16 +88,6 @@ class FF5Reader(QMainWindow):
string_images[k0] += string_images.pop(k) string_images[k0] += string_images.pop(k)
perfcount() perfcount()
battle_bg_structure = [('Tileset', 1, None),
('Palette 1', 1, None),
('Palette 2', 1, None),
('Tilemap', 1, None),
('TilemapFlip', 1, None),
(hex(5, 1), 1, None),
('Animation', 1, None),
('PaletteCycle',1, None),]
battle_bg_headers = ['Address'] + [z[0] for z in battle_bg_structure]
battle_bg_data = [parse_struct(ROM_jp, 0x14BA21 + (i*8), battle_bg_structure) for i in range(34)]
tileset_headers = ("ID", "Offset", "Pointer", "Expected Length") tileset_headers = ("ID", "Offset", "Pointer", "Expected Length")
tileset_data = [] tileset_data = []
@ -117,16 +108,6 @@ class FF5Reader(QMainWindow):
address = start + (npc*7) address = start + (npc*7)
npc_layers.append([hex(i, 6), hex(layer, 3)] + parse_struct(ROM_en, address, const.npc_layer_structure)) npc_layers.append([hex(i, 6), hex(layer, 3)] + parse_struct(ROM_en, address, const.npc_layer_structure))
enemy_sprite_data = []
enemy_sprite_structure = [
('Sprite data offset', 2, None),
('Multiple things', 2, None),
('Tile Layout ID', 1, None),
]
enemy_sprite_headers = ['Address']+[i[0] for i in enemy_sprite_structure]+['EN Name','EN Name']
address = 0x14B180
for i in range(0x180):
enemy_sprite_data.append(parse_struct(ROM_en, address + (i*5), enemy_sprite_structure) + string_images['enemy_names'][i][3:5])
perfcount() perfcount()
print('Generating map tiles') print('Generating map tiles')
@ -187,6 +168,7 @@ class FF5Reader(QMainWindow):
self.battle_strips = make_character_battle_sprites(ROM_en) self.battle_strips = make_character_battle_sprites(ROM_en)
status_strips = make_character_status_sprites(ROM_en) status_strips = make_character_status_sprites(ROM_en)
enemy_sprites = make_enemy_sprites(ROM_en) enemy_sprites = make_enemy_sprites(ROM_en)
enemy_sprite_data = FFVStructs.EnemySprite.get_data(ROM_en)
enemy_sprites_named = [stack_labels(s, d[-2]) for s, d in zip(enemy_sprites, enemy_sprite_data)] enemy_sprites_named = [stack_labels(s, d[-2]) for s, d in zip(enemy_sprites, enemy_sprite_data)]
perfcount() perfcount()
@ -242,12 +224,13 @@ class FF5Reader(QMainWindow):
self.ff6widget.addTab(make_px_table(self.portraits_ff6, cols=19, scale=2), 'Character Portraits') self.ff6widget.addTab(make_px_table(self.portraits_ff6, cols=19, scale=2), 'Character Portraits')
structs_tab.addTab(make_table(ff5.ZoneData.zone_headers, ff5.ZoneData.get_data(), True), 'Zones') structs_tab.addTab(make_table(FFVStructs.ZoneData.get_headers(), FFVStructs.ZoneData.get_data(ROM_en), True), 'Zones')
structs_tab.addTab(make_table(FFVStructs.BattleBackground.get_headers(), FFVStructs.BattleBackground.get_data(ROM_jp), True), 'BattleBGs')
structs_tab.addTab(make_table(FFVStructs.EnemySprite.get_headers(), enemy_sprite_data, True), 'Enemy Sprites')
structs_tab.addTab(make_table(tileset_headers, tileset_data, True), 'Tilesets') structs_tab.addTab(make_table(tileset_headers, tileset_data, True), 'Tilesets')
structs_tab.addTab(make_table(battle_bg_headers, battle_bg_data, True), 'BattleBGs')
structs_tab.addTab(make_table(const.npc_layer_headers, npc_layers, True), 'NPC Layers') structs_tab.addTab(make_table(const.npc_layer_headers, npc_layers, True), 'NPC Layers')
structs_tab.addTab(make_table(enemy_sprite_headers, enemy_sprite_data, True), 'Enemy Sprites')
# Strings tabs
for k, images in string_images.items(): for k, images in string_images.items():
scale = 1 if FFVStrings.config[k].get('dialog') else 2 scale = 1 if FFVStrings.config[k].get('dialog') else 2
caption = ' '.join(f'{w[0].upper()}{w[1:]}' for w in k.split('_')) caption = ' '.join(f'{w[0].upper()}{w[1:]}' for w in k.split('_'))

View File

@ -1,42 +1 @@
from . import const, files, strings
from ..helpers import hex, parse_struct
class ZoneData:
def split_tilesets(data):
tilesets = [(data & 0x00003F),
(data & 0x000FC0) >> 6,
(data & 0x03F000) >> 12,
(data & 0xFC0000) >> 18]
return ' '.join([hex(i,2) for i in tilesets])
def split_blockmaps(data):
blockmaps = [(data & 0x000003FF) - 1,
((data & 0x000FFC00) >> 10) - 1,
((data & 0x3FF00000) >> 20) - 1]
return ' '.join([hex(i,3) for i in blockmaps])
zone_structure = [('NPC Layer', 2, None), # 00 01
('Name', 1, strings.Strings.blocks_RPGe['zone_names'].decoded), # 02
('ShadowFlags', 1, None), # 03
('Graphic maths', 1, None), # 04 - MSb animation-related, 6 LSbs are ID for table in 0x005BB8 which writes to $2131-$2133 (Color Math Designation, Subscreen BG color)
('Tile properties',1, None), # 05
('Flags '+hex(6), 1, None), # 06
(hex(7), 1, None), # 07
('Blockset', 1, None), # 08
('Tilesets', 3, split_tilesets), # 09 0A 0B
('Blockmaps', 4, split_blockmaps), # 0C 0D 0E 0F
(hex(16), 1, None), # 10
(hex(17), 1, None), # 11
(hex(18), 1, None), # 12
(hex(19), 1, None), # 13
(hex(20), 1, None), # 14
(hex(21), 1, None), # 15
('Palette', 1, None), # 16
(hex(23), 1, None), # 17
(hex(24), 1, None), # 18
('Music', 1, const.BGM_Tracks)] # 19
zone_headers = ['Address'] + [z[0] for z in zone_structure]
@classmethod
def get_data(cls):
return [parse_struct(files.ROM_RPGe, 0x0E9C00 + (i*0x1A), cls.zone_structure) for i in range(const.zone_count)]

92
includes/ff5/structs.py Normal file
View File

@ -0,0 +1,92 @@
from . import const, strings
from ..helpers import hex, parse_struct
class StructBlock:
structure = None
block_start = 0
block_length = 0
block_count = 0
@classmethod
def get_data(cls, rom: bytes):
start = cls.block_start
step = cls.block_length
end = start + (step * cls.block_count)
return [parse_struct(rom, address, cls.structure) for address in range(start, end, step)]
@classmethod
def get_headers(cls):
return ['Address'] + [z[0] for z in cls.structure]
class BattleBackground(StructBlock):
structure = (
('Tileset', 1, None),
('Palette 1', 1, None),
('Palette 2', 1, None),
('Tilemap', 1, None),
('TilemapFlip', 1, None),
(hex(5, 1), 1, None),
('Animation', 1, None),
('PaletteCycle',1, None),
)
block_start = 0x14BA21
block_length = 8
block_count = 34
class EnemySprite(StructBlock):
structure = (
('Sprite data offset', 2, None),
('Multiple things', 2, None),
('Tile Layout ID', 1, None),
)
headers = ['Address']+[i[0] for i in structure]
block_start = 0x14B180
block_length = 5
block_count = 0x180
class ZoneData(StructBlock):
def split_tilesets(data):
tilesets = [
(data & 0x00003F), # 0b00000000_00000000_00111111
(data & 0x000FC0) >> 6, # 0b00000000_00001111_11000000
(data & 0x03F000) >> 12, # 0b00000011_11110000_00000000
(data & 0xFC0000) >> 18, # 0b11111100_00000000_00000000
]
return ' '.join([hex(i,2) for i in tilesets])
def split_blockmaps(data):
blockmaps = [
( data & 0x000003FF) - 1, # 0b00000000_00000000_00000011_11111111
((data & 0x000FFC00) >> 10) - 1, # 0b00000000_00001111_11111100_00000000
((data & 0x3FF00000) >> 20) - 1, # 0b00111111_11110000_00000000_00000000
]
return ' '.join([hex(i,3) for i in blockmaps])
structure = (
('NPC Layer', 2, None), # 00 01
('Name', 1, strings.Strings.blocks_RPGe['zone_names'].decoded), # 02
('ShadowFlags', 1, None), # 03
('Graphic maths', 1, None), # 04 - MSb animation-related, 6 LSbs are ID for table in 0x005BB8 which writes to $2131-$2133 (Color Math Designation, Subscreen BG color)
('Tile properties',1, None), # 05
('Flags '+hex(6), 1, None), # 06
(hex(7), 1, None), # 07
('Blockset', 1, None), # 08
('Tilesets', 3, split_tilesets), # 09 0A 0B
('Blockmaps', 4, split_blockmaps), # 0C 0D 0E 0F
(hex(16), 1, None), # 10
(hex(17), 1, None), # 11
(hex(18), 1, None), # 12
(hex(19), 1, None), # 13
(hex(20), 1, None), # 14
(hex(21), 1, None), # 15
('Palette', 1, None), # 16
(hex(23), 1, None), # 17
(hex(24), 1, None), # 18
('Music', 1, const.BGM_Tracks), # 19
)
block_start = 0x0E9C00
block_length = 0x1A
block_count = const.zone_count