Add 'data/' from commit '583b780994269da9be95e3494fb1445801a896ed'

git-subtree-dir: data
git-subtree-mainline: 30393ad424
git-subtree-split: 583b780994
This commit is contained in:
Luke Hubmayer-Werner 2024-06-26 20:36:48 +09:30
commit be222ce1da
20 changed files with 2787 additions and 0 deletions

5
data/1/NES_addresses.tsv Normal file
View File

@ -0,0 +1,5 @@
Label Address Format Comment
character_battle_sprite_tiles 0x25000 12 of 32 of TileNES2bpp
weapon_battle_sprite_tiles 0x26800 128 of TileNES2bpp
title_logo_tiles 0x27400 96 of TileNES2bpp "6x8 logo, gothic text - 8x2 ""FINAL"", 12x2 ""FANTASY"", 8x1 ""ソタチツテトナニ"""
character_battle_sprite_palettes 12 of Palette FINDME
Can't render this file because it has a wrong number of fields in line 2.

3
data/2/NES_addresses.tsv Normal file
View File

@ -0,0 +1,3 @@
Label Address Format Comment
character_battle_sprite_tiles 0x25E00 9 of 32 of TileNES2bpp
character_battle_sprite_palettes 9 of Palette FINDME
1 Label Address Format Comment
2 character_battle_sprite_tiles 0x25E00 9 of 32 of TileNES2bpp
3 character_battle_sprite_palettes 9 of Palette FINDME

3
data/3/NES_addresses.tsv Normal file
View File

@ -0,0 +1,3 @@
Label Address Format Comment
character_battle_sprite_tiles 0x50000 22 of 42 of TileNES2bpp
character_battle_sprite_palettes 22 of Palette FINDME
1 Label Address Format Comment
2 character_battle_sprite_tiles 0x50000 22 of 42 of TileNES2bpp
3 character_battle_sprite_palettes 22 of Palette FINDME

View File

@ -0,0 +1,6 @@
Label SNES PSX_file PSX_offset format Comment
character_battle_sprite_tiles 0xD0000 /mnu/men_bin.eng 14 of 64 of TileSNES4bpp FIXME - PSX
character_battle_sprite_piggy_tiles 0xD7000 48 of TileSNES4bpp FIXME - PSX
character_battle_sprite_golbez_tiles 0xD7600 27 of TileSNES4bpp FIXME - PSX
character_battle_sprite_anna_tiles 0xD7960 14 of TileSNES4bpp FIXME - PSX
character_battle_sprite_palettes 0xE7D00 /btl/ff5_btl.bin 16 of Palette16Of555 FIXME - PSX
1 Label SNES PSX_file PSX_offset format Comment
2 character_battle_sprite_tiles 0xD0000 /mnu/men_bin.eng 14 of 64 of TileSNES4bpp FIXME - PSX
3 character_battle_sprite_piggy_tiles 0xD7000 48 of TileSNES4bpp FIXME - PSX
4 character_battle_sprite_golbez_tiles 0xD7600 27 of TileSNES4bpp FIXME - PSX
5 character_battle_sprite_anna_tiles 0xD7960 14 of TileSNES4bpp FIXME - PSX
6 character_battle_sprite_palettes 0xE7D00 /btl/ff5_btl.bin 16 of Palette16Of555 FIXME - PSX

View File

@ -0,0 +1,89 @@
Label SNES PSX_file PSX_offset format Comment
character_battle_sprite_stone_palette 0x00F807 N/A N/A Palette16Of555 Also 0x199835
character_battle_sprite_disabled_palette 0x00F867 /mnu/memsave.bin 0x000034 Palette16Of555
locations_bg_palettes 0x03BB00 /nar/ff5_binx.bin 0x03BF80 43 of Palette128Of555
font_glyphs_dialogue 0x03E800 256 of SNESTritile length 0x1800
sfx_brr_data 0x041E3F Use the below SPC pointers
sfx_brr_pointers 0x041F4F 8 of 2 of u16 SPC memory addresses not ROM. Start address followed by loop address.
sfx_adsrs 0x041F71 8 of u16
sfx_samplerates 0x041F83 8 of u16
sfx_data 0x041F95 Contains SPC pointers and tracks
bgm_song_pointers 0x043B97 72 of u24
bgm_instrument_brr_pointers 0x043C6F 35 of u24
bgm_instrument_loop_starts 0x043CD8 35 of u16
bgm_instrument_samplerates 0x043D1E 35 of u16
bgm_instrument_adsrs 0x043D64 35 of u16
bgm_instrument_indices 0x043DAA 72 of 16 of u16 length 0x900
enemy_battle_sprite_palettes 0x0ED000 See enemy_battle_sprite_data for pointers. Some are 8 colours instead of 16.
worldmap_blocks 0x0FF0C0 /nar/ff5_binx.bin 0x040300 3 of 4 of 192 of u8 # Top-left corners, top-right corners, bottom-left corners, bottom-right corners
worldmap_tiles.bias 0x0FF9C0 /nar/ff5_bin3.bin 0x03FB00 3 of 256 of u8 Add to each pixel of the mode7c tiles
worldmap_palettes 0x0FFCC0 /nar/ff5_binx.bin 0x040000 3 of Palette128Of555
enemy_stats 0x100000 384 of EnemyStats
enemy_battle_sprite_layouts_small 0x10D004 102 of 8 of u8 length 0x330
enemy_battle_sprite_layouts_large 0x10D334 72 of 16 of u16 length 0x900
enemy_battle_sprite_mini 0x10E003 4 of TileSNES4bpp length 0x80
enemy_battle_sprite_frog 0x10E083 4 of TileSNES4bpp length 0x80
enemy_battle_sprite_shadow 0x10E103 3 of TileSNES4bpp length 0x60
tbl_weapons 0x110000 128 of WeaponData length 0x600
tbl_armors 0x110600 96 of ArmorData length 0x480
tbl_items 0x110A80 32 of ItemData length 0x100
tbl_magic 0x110B80 256 of MagicData length 0x800
tbl_equip_types 0x112480 64 of 4 of u8 length 0x100 - Item Equipment type definitions (64x4 bytes, 2B weapon, 2B armor)
tbl_armors_elem_def 0x112580 64 of ElemDef length 0x140 - Item Armor Element defense 64x(5B - absorb, evade, immunity, half, weakness)
tbl_armors_status 0x1126C0 64 of StatusEffect length 0x1C0 - Item Armor Status defense 64x(7B - 4B Initial, 3B Immune)
tbl_prices_items 0x112A00 256 of ItemCost length 0x200
tbl_prices_magic 0x112C00 128 of ItemCost length 0x100
tbl_charlevels_exp 0x115000 99 of u24
tbl_charlevels_hp_base 0x115129 99 of u16
tbl_charlevels_mp_base 0x1151EF 99 of u16
ptrs_job_ability_lists 0x1152C0 21 of u16
job_ability_counts 0x1152EA 22 of u8
job_ability_lists 0x115300 length 0x12C - u16 ABP required, u8 ID. Pointers are from bank 0x110000 and start at $5300
tbl_char_stat_bonuses 0x11551E 5 of 4 of u8
tbl_job_base_stats 0x1156B0 22 of 4 of u8
tbl_job_default_equipment 0x115708 22 of 4 of u8
tbl_job_default_commands 0x115760 22 of 4 of u8
tbl_job_innates 0x1157B8 22 of u16
tbl_ability_stats_commands 0x115E00 256 of 4 of u8 length 0x400
tbl_ability_stats_passives 0x116308 33 of 4 of u8 length 0x84
character_initial_data 0x117000 4 of Character length 0x140
attack_layouts 0x117FA0 5 of 2048 of u8 length 0x2400
weapon_palettes 0x11A3A0
enemy_battle_status_sprite_palette 0x11A400 Palette16Of555
tiles_fist 0x11D710 /btl/ff5_btl.bin 0x021D10 TileSNES3bpp Also /mnu/men_bin.eng:0x00D910
font_glyphs_small 0x11F000 256 of TileSNES2bpp length 0x1000
character_battle_sprite_tiles 0x120000 /mnu/men_bin.eng 0x010200 5 of 22 of 48 of TileSNES4bpp
character_battle_sprite_palettes 0x14A3C0 /btl/ff5_btl.bin 0x0273C0 5 of 22 of Palette16Of555 Also /mnu/men_bin.eng:0x03A5C0
enemy_battle_sprite_data 0x14B180 384 of EnemySpriteData length 0x780
character_battle_sprite_layouts 0x14B997 /btl/ff5_btl.bin 0x028997 11 of 6 of u8
tbl_battle_backgrounds 0x14BA21 34 of BattleBackgroundData
battle_background_palettes 0x14BB31 84 of Palette16Of555
ptrs_battle_background_tile_animations 0x14C5B1 8 of u16 bank 0x140000 (0xD40000)
battle_background_tile_animations_data 0x14C5C1 see above
ptrs_battle_background_palette_animations 0x14C6CD 3 of u16 bank 0x140000 (0xD40000)
battle_background_palette_animations_data 0x14C6D3 see above
ptrs_battle_background_tilemap_flips 0x14C736 9 of u16 bank 0x140000 (0xD40000)
battle_background_tilemap_flips_data 0x14C75C see above
ptrs_battle_background_tilemaps 0x14C86D 28 of u16 bank 0x140000 (0xD40000)
? 0x14C8A5
battle_background_tilemaps_data 0x14E09B see above
enemy_battle_sprite_tiles 0x150000 See enemy_battle_sprite_data for pointers
ptrs_battle_background_tileset_skips 0x184157 21 of u24 RAM addresses, subtract 0x7FC000 from results to get offset from tileset
ptrs_battle_background_tilesets 0x184196 21 of u24 ROM addresses, subtract 0xC00000
lzss_battle_background_tilesets 0x1841D5 see pointers above, 4bpp
? 0x18DE36
ptrs_event_data 0x18E080 687 of u16
event_data 0x18E5E0 see above, links to extended event data
tiles_attack_anims 0x190000
ptrs_anim_unk1 0x19A486 405 of u16 bank offsets to below
0x19A7B0 padding
anim_unk1 0x19A7C0 see above
ptrs_anim_unk2 0x19B35E 1669 of u16 bank offsets to below, animation frame data??? also to anim_unk1
anim_unk2 0x19C068 see above
tiles_npcs 0x1A0000
worldmap_tiles.0 0x1B8000 /nar/ff5_bin3.bin 0x039B00 256 of TileSNESMode7c Add the biases
worldmap_tiles.1 0x1BA000 /nar/ff5_bin3.bin 0x039B00 256 of TileSNESMode7c Add the biases
worldmap_tiles.2 0x1BC000 /nar/ff5_bin3.bin 0x039B00 128 of TileSNESMode7c Add the biases
font_glyphs_kanji 0x1BD000 426 of SNESTritile length of 0x27F0
? 0x1BF800
RPGe_font_character_widths 0x203225 512 of u8 RPGe only, Includes the 1px spacing
1 Label SNES PSX_file PSX_offset format Comment
2 character_battle_sprite_stone_palette 0x00F807 N/A N/A Palette16Of555 Also 0x199835
3 character_battle_sprite_disabled_palette 0x00F867 /mnu/memsave.bin 0x000034 Palette16Of555
4 locations_bg_palettes 0x03BB00 /nar/ff5_binx.bin 0x03BF80 43 of Palette128Of555
5 font_glyphs_dialogue 0x03E800 256 of SNESTritile length 0x1800
6 sfx_brr_data 0x041E3F Use the below SPC pointers
7 sfx_brr_pointers 0x041F4F 8 of 2 of u16 SPC memory addresses not ROM. Start address followed by loop address.
8 sfx_adsrs 0x041F71 8 of u16
9 sfx_samplerates 0x041F83 8 of u16
10 sfx_data 0x041F95 Contains SPC pointers and tracks
11 bgm_song_pointers 0x043B97 72 of u24
12 bgm_instrument_brr_pointers 0x043C6F 35 of u24
13 bgm_instrument_loop_starts 0x043CD8 35 of u16
14 bgm_instrument_samplerates 0x043D1E 35 of u16
15 bgm_instrument_adsrs 0x043D64 35 of u16
16 bgm_instrument_indices 0x043DAA 72 of 16 of u16 length 0x900
17 enemy_battle_sprite_palettes 0x0ED000 See enemy_battle_sprite_data for pointers. Some are 8 colours instead of 16.
18 worldmap_blocks 0x0FF0C0 /nar/ff5_binx.bin 0x040300 3 of 4 of 192 of u8 # Top-left corners, top-right corners, bottom-left corners, bottom-right corners
19 worldmap_tiles.bias 0x0FF9C0 /nar/ff5_bin3.bin 0x03FB00 3 of 256 of u8 Add to each pixel of the mode7c tiles
20 worldmap_palettes 0x0FFCC0 /nar/ff5_binx.bin 0x040000 3 of Palette128Of555
21 enemy_stats 0x100000 384 of EnemyStats
22 enemy_battle_sprite_layouts_small 0x10D004 102 of 8 of u8 length 0x330
23 enemy_battle_sprite_layouts_large 0x10D334 72 of 16 of u16 length 0x900
24 enemy_battle_sprite_mini 0x10E003 4 of TileSNES4bpp length 0x80
25 enemy_battle_sprite_frog 0x10E083 4 of TileSNES4bpp length 0x80
26 enemy_battle_sprite_shadow 0x10E103 3 of TileSNES4bpp length 0x60
27 tbl_weapons 0x110000 128 of WeaponData length 0x600
28 tbl_armors 0x110600 96 of ArmorData length 0x480
29 tbl_items 0x110A80 32 of ItemData length 0x100
30 tbl_magic 0x110B80 256 of MagicData length 0x800
31 tbl_equip_types 0x112480 64 of 4 of u8 length 0x100 - Item Equipment type definitions (64x4 bytes, 2B weapon, 2B armor)
32 tbl_armors_elem_def 0x112580 64 of ElemDef length 0x140 - Item Armor Element defense 64x(5B - absorb, evade, immunity, half, weakness)
33 tbl_armors_status 0x1126C0 64 of StatusEffect length 0x1C0 - Item Armor Status defense 64x(7B - 4B Initial, 3B Immune)
34 tbl_prices_items 0x112A00 256 of ItemCost length 0x200
35 tbl_prices_magic 0x112C00 128 of ItemCost length 0x100
36 tbl_charlevels_exp 0x115000 99 of u24
37 tbl_charlevels_hp_base 0x115129 99 of u16
38 tbl_charlevels_mp_base 0x1151EF 99 of u16
39 ptrs_job_ability_lists 0x1152C0 21 of u16
40 job_ability_counts 0x1152EA 22 of u8
41 job_ability_lists 0x115300 length 0x12C - u16 ABP required, u8 ID. Pointers are from bank 0x110000 and start at $5300
42 tbl_char_stat_bonuses 0x11551E 5 of 4 of u8
43 tbl_job_base_stats 0x1156B0 22 of 4 of u8
44 tbl_job_default_equipment 0x115708 22 of 4 of u8
45 tbl_job_default_commands 0x115760 22 of 4 of u8
46 tbl_job_innates 0x1157B8 22 of u16
47 tbl_ability_stats_commands 0x115E00 256 of 4 of u8 length 0x400
48 tbl_ability_stats_passives 0x116308 33 of 4 of u8 length 0x84
49 character_initial_data 0x117000 4 of Character length 0x140
50 attack_layouts 0x117FA0 5 of 2048 of u8 length 0x2400
51 weapon_palettes 0x11A3A0
52 enemy_battle_status_sprite_palette 0x11A400 Palette16Of555
53 tiles_fist 0x11D710 /btl/ff5_btl.bin 0x021D10 TileSNES3bpp Also /mnu/men_bin.eng:0x00D910
54 font_glyphs_small 0x11F000 256 of TileSNES2bpp length 0x1000
55 character_battle_sprite_tiles 0x120000 /mnu/men_bin.eng 0x010200 5 of 22 of 48 of TileSNES4bpp
56 character_battle_sprite_palettes 0x14A3C0 /btl/ff5_btl.bin 0x0273C0 5 of 22 of Palette16Of555 Also /mnu/men_bin.eng:0x03A5C0
57 enemy_battle_sprite_data 0x14B180 384 of EnemySpriteData length 0x780
58 character_battle_sprite_layouts 0x14B997 /btl/ff5_btl.bin 0x028997 11 of 6 of u8
59 tbl_battle_backgrounds 0x14BA21 34 of BattleBackgroundData
60 battle_background_palettes 0x14BB31 84 of Palette16Of555
61 ptrs_battle_background_tile_animations 0x14C5B1 8 of u16 bank 0x140000 (0xD40000)
62 battle_background_tile_animations_data 0x14C5C1 see above
63 ptrs_battle_background_palette_animations 0x14C6CD 3 of u16 bank 0x140000 (0xD40000)
64 battle_background_palette_animations_data 0x14C6D3 see above
65 ptrs_battle_background_tilemap_flips 0x14C736 9 of u16 bank 0x140000 (0xD40000)
66 battle_background_tilemap_flips_data 0x14C75C see above
67 ptrs_battle_background_tilemaps 0x14C86D 28 of u16 bank 0x140000 (0xD40000)
68 ? 0x14C8A5
69 battle_background_tilemaps_data 0x14E09B see above
70 enemy_battle_sprite_tiles 0x150000 See enemy_battle_sprite_data for pointers
71 ptrs_battle_background_tileset_skips 0x184157 21 of u24 RAM addresses, subtract 0x7FC000 from results to get offset from tileset
72 ptrs_battle_background_tilesets 0x184196 21 of u24 ROM addresses, subtract 0xC00000
73 lzss_battle_background_tilesets 0x1841D5 see pointers above, 4bpp
74 ? 0x18DE36
75 ptrs_event_data 0x18E080 687 of u16
76 event_data 0x18E5E0 see above, links to extended event data
77 tiles_attack_anims 0x190000
78 ptrs_anim_unk1 0x19A486 405 of u16 bank offsets to below
79 0x19A7B0 padding
80 anim_unk1 0x19A7C0 see above
81 ptrs_anim_unk2 0x19B35E 1669 of u16 bank offsets to below, animation frame data??? also to anim_unk1
82 anim_unk2 0x19C068 see above
83 tiles_npcs 0x1A0000
84 worldmap_tiles.0 0x1B8000 /nar/ff5_bin3.bin 0x039B00 256 of TileSNESMode7c Add the biases
85 worldmap_tiles.1 0x1BA000 /nar/ff5_bin3.bin 0x039B00 256 of TileSNESMode7c Add the biases
86 worldmap_tiles.2 0x1BC000 /nar/ff5_bin3.bin 0x039B00 128 of TileSNESMode7c Add the biases
87 font_glyphs_kanji 0x1BD000 426 of SNESTritile length of 0x27F0
88 ? 0x1BF800
89 RPGe_font_character_widths 0x203225 512 of u8 RPGe only, Includes the 1px spacing

View File

@ -0,0 +1,256 @@
 
\n
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
%
/
:
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
°C
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

View File

@ -0,0 +1,256 @@
\n
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
il
it
li
ll
:
;
,
(
)
/
!
?
.
ti
fi
p
el
if
lt
tl
ir
tt
%
:
+
°C

View File

@ -0,0 +1,426 @@
使
殿
姿
西
宿
 

View File

@ -0,0 +1,256 @@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[stone]
[toad]
[mini]
[float]
[poison]
[KO]
[blind]
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
%
/
:
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
[洋剣]
[wh.mag]
[blk.mag]
🕒
[刂]
[槍]
[鉞]
[刀]
[棒]
[杖]
[弓]
[鞭]
[bell]
[shield]
[helmet]
[armor]
[ring]

View File

@ -0,0 +1,256 @@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[stone]
[toad]
[mini]
[float]
[poison]
[KO]
[blind]
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
il
it
li
ll
'
"
:
;
,
(
)
/
!
?
.
ti
fi
Bl
a
pe
l
'
"
if
lt
tl
ir
tt
[key]
[shoe]
[hammer]
[ribbon]
[potion]
[shirt]
-
[shuriken]
[scroll]
!
[claw]
?
[glove]
%
/
:
.
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
[sword]
[wh.mag]
[blk.mag]
🕒
[knife]
[spear]
[axe]
[katana]
[rod]
[staff]
[bow]
[harp]
[whip]
[bell]
[shield]
[helmet]
[armor]
[ring]

View File

@ -0,0 +1,256 @@
0
1
2
3
4
5
6
7
8
9
_m
_H
_P
%
/
:
A
B
X
Y
L
R
E
H
M
P
S
C
T
+
[洋剣]
[wh.mag]
[blk.mag]
🕒
[刂]
[槍]
[鉞]
[刀]
[棒]
[杖]
[弓]
[鞭]
[bell]
[shield]
[helmet]
[armor]
[ring]

189
data/5/sprite_blocks.json Normal file
View File

@ -0,0 +1,189 @@
{
"NPCs sprites": {
"start": "0x1A0000",
"bpp": 4,
"definitions": [
[2, 2, 2, "Crystal shards"],
[2, 2, 2, "sparkle"],
[2, 2, 2, "speech bubble exclamation"],
[2, 2, 2, "speech bubble question"],
[2, 2, 2, "speech bubble heart"],
[2, 2, 2, "binding barrier"],
[2, 2, 2, "wisp flame"],
[2, 2, 20, "lightning"],
[2, 2, 4, "sparkle glow"],
[2, 2, 2, "void demon that Leviathan kills (second palette)"],
[2, 2, 2, "void demon Triton/Nereid/Phobos"],
[2, 2, 2, "void demon Wendigo (second palette)"],
[2, 2, 2, "void demon Azulmagia (third palette)"],
[2, 2, 2, "void demon Catastrophe (third palette)"],
[2, 2, 1, "void demon Calofisteri"],
[2, 2, 1, "fallen soldier"],
[2, 2, 2, "lightning 2"],
[2, 2, 2, "sparkle glow 2"],
[2, 2, 2, "blob shadow"],
[2, 2, 2, "void demon Halicarnassus (second palette)"],
[2, 2, 2, "Faris hair blowing in the wind"],
[2, 4, 1, "rainbow stripes"],
[2, 2, 2, "pirate sleeping standing"],
[2, 2, 2, "Faris hair blowing in the wind 2"],
[2, 2, 2, "WingRaptor (2x2 wing, 2x2 body)"],
[2, 2, 1, "Melusine"],
[2, 2, 1, "jumping in shock"],
[2, 2, 1, "blank"],
[2, 2, 1, "fallen woman"],
[2, 2, 1, "fallen Cid"],
[2, 2, 1, "fallen Mid"],
[2, 2, 4, "Crystal upper"],
[2, 2, 4, "Crystal lower"],
[2, 2, 4, "fireball"],
[2, 2, 4, "sparkle glow 3"],
[2, 2, 4, "kite-shaped crystal"],
[2, 2, 4, "puff of smoke"],
[2, 2, 4, "fire geyser"],
[2, 2, 4, "flame in ball"],
[2, 2, 4, "growing sparkle"],
[2, 2, 4, "Abductor"],
[2, 2, 4, "Galuf glowing"],
[2, 2, 4, "Goblin?"],
[2, 2, 4, "kingly guy"],
[2, 2, 4, "Queen Karnak"],
[2, 2, 4, "bard"],
[2, 2, 4, "kid"],
[2, 2, 4, "old woman"],
[2, 2, 4, "merchant guy"],
[2, 2, 4, "sheep"],
[2, 2, 4, "girl"],
[2, 2, 2, "Garula"],
[2, 2, 2, "Archeoaevis"],
[2, 2, 4, "guy"],
[2, 2, 4, "turban guy"],
[2, 2, 4, "snake"],
[2, 2, 1, "mummy"],
[2, 2, 1, "small kid"],
[2, 2, 2, "blank"],
[2, 2, 4, "Magissa"],
[2, 2, 4, "Gilgamesh"],
[2, 2, 4, "Faris dress"],
[2, 2, 4, "Skeleton"],
[2, 2, 4, "cutscene bird"],
[2, 2, 4, "Omega"],
[2, 2, 8, "King Tycoon strip (some tiles not 2x2)"],
[2, 2, 8, "Pirate strip (some tiles not 2x2)"],
[2, 2, 8, "Boko strip (some tiles not 2x2)"],
[2, 2, 8, "Black Chocobo strip (some tiles not 2x2)"],
[2, 2, 8, "servant lady strip (some tiles not 2x2)"],
[2, 2, 8, "King Walse strip (some tiles not 2x2)"],
[2, 2, 8, "Chancellor strip (some tiles not 2x2)"],
[2, 2, 8, "Werewolf strip (some tiles not 2x2)"],
[2, 2, 8, "Moogle strip (some tiles not 2x2)"],
[2, 2, 8, "Kelger strip (some tiles not 2x2)"],
[2, 2, 8, "Xezat strip (some tiles not 2x2)"],
[2, 2, 8, "Ghido strip (some tiles not 2x2)"],
[2, 2, 8, "Dorgann strip (some tiles not 2x2)"],
[2, 2, 4, "Dwarf"],
[2, 2, 4, "Chicobo"],
[2, 2, 8, "kid strip (some tiles not 2x2)"],
[2, 2, 8, "woman strip (some tiles not 2x2)"],
[2, 2, 8, "old man with pointy hat strip (some tiles not 2x2)"],
[2, 2, 8, "scholar strip (some tiles not 2x2)"],
[2, 2, 8, "soldier strip (some tiles not 2x2)"],
[2, 2, 8, "dancer strip (some tiles not 2x2)"],
[2, 2, 8, "soldier 2 strip (some tiles not 2x2)"],
[2, 2, 8, "Cid strip (some tiles not 2x2)"],
[2, 2, 8, "Mid strip (some tiles not 2x2)"],
[2, 2, 6, "Black Chocobo flying"],
[2, 2, 2, "blank"],
[2, 2, 8, "Exdeath strip (some tiles not 2x2)"],
[2, 2, 16, "mini strip (some tiles not 2x2)"],
[2, 2, 16, "frog strip (some tiles not 2x2)"],
[2, 2, 16, "Bartz strip (some tiles not 2x2)"],
[2, 2, 16, "Lenna strip (some tiles not 2x2)"],
[2, 2, 16, "Galuf strip (some tiles not 2x2)"],
[2, 2, 16, "Faris strip (some tiles not 2x2)"],
[2, 2, 16, "Krile strip (some tiles not 2x2)"],
[2, 2, 1, "fallen King Tycoon"],
[2, 2, 1, "fallen Durgann?"],
[2, 2, 1, "fallen Queen Karnak"],
[2, 2, 19, "Syldra?"],
[2, 2, 1, "Dragongrass?"],
[2, 2, 1, "arrow"],
[2, 2, 2, "book"],
[2, 2, 1, "map"],
[2, 2, 1, "torn page"],
[2, 2, 4, "Dragongrass attack mode"],
[2, 4, 1, "Siren"],
[2, 2, 1, "fallen soldier 2"],
[2, 2, 1, "campfire sticks"],
[2, 2, 2, "dragon head"],
[2, 2, 1, "King Tycoon's Helmet"],
[2, 2, 1, "picture?"],
[2, 2, 1, "music box?"],
[2, 6, 1, "some fire pillar thing"],
[2, 2, 2, "bubbles"],
[2, 2, 1, "void demon Twintania"],
[2, 2, 1, "egg"],
[2, 2, 1, "pendant"],
[2, 2, 1, "elder branch"],
[2, 2, 1, "elder branch tiara"],
[2, 2, 1, "magic mirror?"],
[2, 2, 1, "piece of glass?"],
[2, 2, 1, "piece of adamantine?"],
[2, 2, 1, "bomb"],
[2, 2, 1, "vertical rope"],
[2, 2, 1, "antlion pincer?"],
[2, 2, 1, "elder branch 2???"],
[2, 2, 1, "stone tablet"],
[2, 2, 1, "void demon Apanda"],
[2, 4, 1, "gargoyle statue"],
[2, 2, 6, "Leviathan?"],
[2, 2, 1, "Sealed Weapon - Excalibur"],
[2, 2, 1, "Sealed Weapon - Assassin Dagger"],
[2, 2, 1, "Sealed Weapon - Sasuke's Katana"],
[2, 2, 1, "Sealed Weapon - Holy Lance"],
[2, 2, 1, "Sealed Weapon - Rune Axe"],
[2, 2, 1, "Sealed Weapon - Masamune"],
[2, 2, 1, "Sealed Weapon - Yoichi's Bow"],
[2, 2, 1, "Sealed Weapon - Fire Lash"],
[2, 2, 1, "Sealed Weapon - Sage Staff"],
[2, 2, 1, "Sealed Weapon - Magus Rod"],
[2, 2, 1, "Sealed Weapon - Apollo's Harp"],
[2, 2, 1, "Sealed Weapon - Gaia's Bell"],
[2, 2, 1, "Bartz tied up"],
[2, 2, 1, "Lenna tied up"],
[2, 2, 1, "Galuf tied up"],
[2, 2, 1, "void demon Necrophobe (palette 2)"],
[1, 1, 64, "Hiryuu tiles"]
]
},
"Overworld / World map sprites": {
"start": "0x1B3A00",
"bpp": 3,
"definitions": [
[2, 2, 1, "Tent"],
[2, 2, 1, "Cabin"],
[1, 1, 1, "shadow large"],
[1, 1, 1, "shadow medium"],
[1, 1, 1, "shadow small"],
[1, 1, 1, "question mark"],
[1, 1, 1, "up arrow"],
[1, 1, 1, "plus large"],
[1, 1, 1, "plus small"],
[1, 1, 1, "x small"],
[2, 2, 6, "Ship"],
[2, 2, 6, "Hiryuu"],
[2, 2, 6, "Steamship"],
[2, 2, 6, "Airship"],
[2, 2, 6, "Submarine underwater"],
[2, 2, 6, "Submarine surface"],
[2, 2, 6, "Airship/Submarine transformation"]
]
},
"Overworld sprites": {
"start": "0x1B4D80",
"bpp": 4,
"definitions": [
[2, 1, 202, "TBC"]
]
}
}

15
data/5/string_blocks.tsv Normal file
View File

@ -0,0 +1,15 @@
name num_entries address snes_address bytes snes_bytes rpge_ptr_offset snes_ptr_offset dialog null_terminated
ability_names 33 0x116200 8
battle_commands 96 0x201150 0x115800 7 5
character_names 5 0x115500 6
dialogue 0x900 0x2013F0 0x082220 3 2 0x000000 0x0A0000 True
enemy_names 384 0x200050 0x105C00 10 8
items 0x100 0x111380 9
item_long_names 0x120 0x275860 0x111380 24 9
item_descriptions 128 0x114000 2 0x110000 0x110000 True True
job_names 22 0x115600 8
job_and_ability_descs 133 0x117140 2 0x110000 0x110000 True
magics 87 0x111C80 6
magics2 73 0x111E8A 9
menu_strings 139 0x00F987 2 0x270000 0x000000 True
zone_names 164 0x107000 2 0x270000 0x107200 True
1 name num_entries address snes_address bytes snes_bytes rpge_ptr_offset snes_ptr_offset dialog null_terminated
2 ability_names 33 0x116200 8
3 battle_commands 96 0x201150 0x115800 7 5
4 character_names 5 0x115500 6
5 dialogue 0x900 0x2013F0 0x082220 3 2 0x000000 0x0A0000 True
6 enemy_names 384 0x200050 0x105C00 10 8
7 items 0x100 0x111380 9
8 item_long_names 0x120 0x275860 0x111380 24 9
9 item_descriptions 128 0x114000 2 0x110000 0x110000 True True
10 job_names 22 0x115600 8
11 job_and_ability_descs 133 0x117140 2 0x110000 0x110000 True
12 magics 87 0x111C80 6
13 magics2 73 0x111E8A 9
14 menu_strings 139 0x00F987 2 0x270000 0x000000 True
15 zone_names 164 0x107000 2 0x270000 0x107200 True

165
data/5/structs/SNES.tsv Normal file
View File

@ -0,0 +1,165 @@
struct AttackType
u1 is_blue_magic
u1 is_white_magic
u1 is_black_magic
u1 is_dimension_magic
u1 is_summon
u1 is_sound
u1 is_longrange
u1 is_physical
struct AttackProperties
u2 action_delay
u1 roulette
u1 target_enemy_by_default
u1 can_target_either_side
u1 can_select_target
u1 always_target_all
u1 can_target_all
struct WeaponData
AttackProperties attack_properties
AttackType attack_type
u6 item_type
u1 is_unthrowable
u1 byte_2_leftover
EquipStatBonus bonus
u6 description
u1 can_double_grip
u1 only_double_grip
u1 is_wonder_rod
u1 is_action_on_use
u1 can_magic_sword
u1 is_action_on_hit
u1 is_5.4
u1 is_initiative
u1 is_knife_parry
u1 is_sword_parry
u7 spell_cast
u1 is_break_after_use
u8 attack_power
u7 attack_effect
u1 byte_8_leftover
u8 param0 # accuracy_percent for sub-100 weapons, crit rate on katanas, element on Flametongue/Icebrand/Excalibur/AirKnife/Trident/WindSpear
u8 param1 # on_hit_effect_percent for weapons that cast actions on hit, also Rune weapons bonus attack power
u8 param2 # action_on_hit for weapons that cast actions on hit, Also Rune weapons 5 mana cost on attack, also element of attack for rods
struct ArmorData
u8 slot # b0 - 0x01 acc, 0x02 body, 0x04 head, 0x08 shield, 0xF0 unused
u8 weight # b1
u6 item_type
u1 is_unthrowable
u1 byte_2_leftover
EquipStatBonus bonus # b3
u6 description # b4
u2 byte_4_leftovers
u1 is_improve_catch # b5
u1 is_become_undead
u1 is_improve_dance
u1 is_halve_mp_cost
u1 is_improve_steal
u1 is_improve_brawl
u1 is_elf_cape_dodge
u1 is_block_all_magic # b5
u8 evasion # b6
u8 defense
u8 m_evasion
u8 m_def # b9
u8 elem_effect # b10 - 01 ½ lightning, 02 ½ all, 03 immune poison damage, 04 absorb fire+immune ice+weak water, 05 absorb water+immune fire+weak lightning, 06 Bone Mail (absorb poison, halve ice, weak fire/holy), 07 absorb fire, 08 absorb ice
u8 status_effect # b11 - 01 auto-regen, 02 auto-doom, 03 auto-haste + immune slow/stop/paralyse/sleep, 04 immune petrify, 05 Ribbon, 06 immune confuse, 07 immune silence, 08 immune blind, 09 immune poison, 0A bone mail, 0B auto-reflect, 0C immune mini, 0D immune old/zombie, 0E auto-sap + immune sleep, 0F auto-blink, 10 immune mini/paralyse, 11 immune confuse/mini, 12 immune confuse/toad, 13 immune toad/paralyse
struct ItemData
AttackProperties attack_properties
u8 attack_type
u1 unk0
u1 is_unmixable
u1 unk1
u1 is_magic_lamp
u1 is_undrinkable
u1 is_unusable_in_battle
u1 is_unthrowable
u1 unk2
u6 description # b3
u2 byte_3_leftovers
u7 attack_formula
u1 is_unavoidable
u8 param_0
u8 param_1
u8 param_2
struct MagicData
AttackProperties attack_properties
u8 attack_type
u4 meteo_extra_hits
u2 unk
u1 is_learnable
u1 is_monster_bit
u7 mp_cost
u1 is_unreflectable
u7 attack_formula
u1 is_unavoidable
u8 param_0
u8 param_1
u8 param_2
struct ElemDef
u8 absorb
u8 evade
u8 immune
u8 half
u8 weak
struct StatusEffect
4 of u8 initial
3 of u8 immune
struct EnemySpriteData
u7 tileset_offset_hi # combined with lo, << 3, + 0x150000
u1 is_3bpp
u8 tileset_offset_lo
u2 palette_offset_hi # combined with lo, << 4, + 0x0ED000
u4 unk
u1 is_separate_shadow
u1 is_large_layout
u8 palette_offset_lo
u8 layout_id # Small? <<3, + 0x10D004, take 8 bytes. Large? <<5, + 0x10D334, take 32 bytes.
struct BattleBackgroundData
u8 tileset_id
2 of u8 palette_ids
u8 tilemap_id
u8 tilemap_flips_id
u8 tilemap_v_flips_id # Unused, all 0xFF = no flips
u8 tilecycle_id
u8 palcycle_id
struct EnemyStats
u8 speed
u8 attack_power
u8 attack_multiplier
u8 evasion
u8 defense
u8 magic_power
u8 magic_defense
u8 magic_evasion
u16 max_hp
u16 max_mp
u16 reward_exp
u16 reward_gil
u8 attack_graphics
u8 elements_immune
u24 status_immune
u8 elements_absorb
AttackType attack_type
u8 elements_weak
u8 monster_type
u8 flags_25
u16 status_26
u16 status_28
u8 29
u8 30
u8 level # 31
Can't render this file because it has a wrong number of fields in line 43.

View File

@ -0,0 +1,161 @@
struct Character
u3 character_id # 0=Bartz, 1=Lenna, 2=Galuf, 3=Faris, 4=Krile, 5/6/7 unused
u1 is_female # 0=male, 1=female
u2 unk0 # Two unknown, possibly unused bits
u1 is_absent # 0=present, 1=absent
u1 is_back_row
u8 current_job_id
u8 level
u24 experience
u16 hp_current
u16 hp_max
u16 mp_current
u16 mp_max
u8 equipped_head
u8 equipped_body
u8 equipped_acc
u8 equipped_rh_shield
u8 equipped_lh_shield
u8 equipped_rh_weapon
u8 equipped_lh_weapon
u8 caught_monster
u8 ability_1
u8 ability_2
u8 ability_3
u8 ability_4
u8 status_1
u8 status_2
u8 status_3
u8 status_4
u8 action_flags
u8 damage_mod
u16 innates
u8 magic_element_up
u8 equip_weight
u8 base_strength
u8 base_agility
u8 base_stamina
u8 base_magic
u8 current_strength
u8 current_agility
u8 current_stamina
u8 current_magic
u8 evasion
u8 defense
u8 magic_evasion
u8 magic_defense
u8 elemental_absorb
u8 elemental_evade
u8 elemental_immune
u8 elemental_half
u8 elemental_weakness
u8 resistance_status_1
u8 resistance_status_2
u8 resistance_status_3
u8 specialty_weapon
u8 specialty_equipment
u8 current_job_level
u16 current_job_abp
u8 spell_level_1
u8 spell_level_2
u8 spell_level_3
u32 equipment_category
u16 attack
u8 attack_id_reaction_unused
u8 unk1
u8 unk2
u8 unk3
u8 freelancer_strength
u8 freelancer_agility
u8 freelancer_stamina
u8 freelancer_magic
u16 freelancer_innates
struct Job_progress
u12 abp
u4 level
struct Config
u3 battle_speed # 0=1 in-game, ..., 5=6 in-game
u1 is_wait_mode # 0=active, 1=wait???
u3 message_speed # 0=1 in-game, ..., 5=6 in-game
u1 command_set # 0=window, 1=shortcut
u5 menu_color_r
u5 menu_color_g
u5 menu_color_b
u1 padding
u1 reequip_mode # 0=optimum, 1=empty
u1 is_mono # 0=stereo, 1=mono
u1 is_memory_cursor # 0=reset, 1=memory
u4 unk0
u1 hide_atb_gauge # 0=show, 1=hide
u6 unk1
u1 is_controller_custom # 0=no, 1=yes
u1 is_controller_2p # 0=no, 1=yes
u8 button_A # Bit of action
u8 button_B # Bit of action
u8 button_X # Bit of action
u8 button_Y # Bit of action
u8 button_L # Bit of action
u8 button_R # Bit of action
u8 button_Select # Bit of action
4 of u8 character_player_nums # 0=controller 1, 1=controller 2
4 of 4 of u8 character_shortcut_commands # 0=ability_1, 1=ability_2, 2=ability_3, 3=ability_4
struct Vehicle
u2 mode_switching
u3 movement_type
u3 map_id
u7 unk0
u1 is_hidden # 0=show, 1=hide
u8 x
u8 y
struct Save_slot
4 of Character characters
256 of u8 inventory_item_ids
256 of u8 inventory_item_qtys
u24 unlocked_jobs
4 of 22 of Job_progress character_jobs_progress
4 of u8 character_abilities_learned_count
4 of 20 of u8 character_abilities_learned
u24 current_gil
u32 game_time_frames
u16 num_enemies_defeated
32 of u8 magic_learned
Config config
5 of 6 of u8 character_names # Bartz, Lenna, Galuf, Faris, Krile. Dialog is hardcoded for everyone except Bartz's name anyway...
6 of u8 unk0
u8 magic_lamp_next_summon
u8 num_battles_escaped # Brave Blade vs Chicken Knife
u8 wonder_rod_magic
9 of u8 unk1
u16 num_total_battles
u16 num_times_saved
u8 last_battle_results # 0=victory, 1=game over, 2=escaped
15 of u8 flags_battle_events
32 of u8 flags_treasure_opened
32 of u8 unk_probably_still_flags_treasure_opened
96 of u8 flags_events # RAM map mentions $D8E000. This is likely critical to story progression and scripting.
96 of u8 unk_probably_still_flags_events
u16 map_id_inner
u16 map_id_world
u8 pos_x
u8 pos_y
u8 current_character_sprite
u8 current_character_facing
u8 current_vehicle
Vehicle veh_chocobo
Vehicle veh_black_chocobo
Vehicle veh_hiryuu
Vehicle veh_submarine
Vehicle veh_steamship
Vehicle veh_airship
u16 teleport_map_id
u8 teleport_map_x
u8 teleport_map_y
u8 initial_seed
u8 walking_speed # 0=normal, 1=double (fast), 80=half (slow)
u8 timed_event_active
u16 timed_event_timer
u16 timed_event_end
1 struct Character
2 u3 character_id # 0=Bartz, 1=Lenna, 2=Galuf, 3=Faris, 4=Krile, 5/6/7 unused
3 u1 is_female # 0=male, 1=female
4 u2 unk0 # Two unknown, possibly unused bits
5 u1 is_absent # 0=present, 1=absent
6 u1 is_back_row
7 u8 current_job_id
8 u8 level
9 u24 experience
10 u16 hp_current
11 u16 hp_max
12 u16 mp_current
13 u16 mp_max
14 u8 equipped_head
15 u8 equipped_body
16 u8 equipped_acc
17 u8 equipped_rh_shield
18 u8 equipped_lh_shield
19 u8 equipped_rh_weapon
20 u8 equipped_lh_weapon
21 u8 caught_monster
22 u8 ability_1
23 u8 ability_2
24 u8 ability_3
25 u8 ability_4
26 u8 status_1
27 u8 status_2
28 u8 status_3
29 u8 status_4
30 u8 action_flags
31 u8 damage_mod
32 u16 innates
33 u8 magic_element_up
34 u8 equip_weight
35 u8 base_strength
36 u8 base_agility
37 u8 base_stamina
38 u8 base_magic
39 u8 current_strength
40 u8 current_agility
41 u8 current_stamina
42 u8 current_magic
43 u8 evasion
44 u8 defense
45 u8 magic_evasion
46 u8 magic_defense
47 u8 elemental_absorb
48 u8 elemental_evade
49 u8 elemental_immune
50 u8 elemental_half
51 u8 elemental_weakness
52 u8 resistance_status_1
53 u8 resistance_status_2
54 u8 resistance_status_3
55 u8 specialty_weapon
56 u8 specialty_equipment
57 u8 current_job_level
58 u16 current_job_abp
59 u8 spell_level_1
60 u8 spell_level_2
61 u8 spell_level_3
62 u32 equipment_category
63 u16 attack
64 u8 attack_id_reaction_unused
65 u8 unk1
66 u8 unk2
67 u8 unk3
68 u8 freelancer_strength
69 u8 freelancer_agility
70 u8 freelancer_stamina
71 u8 freelancer_magic
72 u16 freelancer_innates
73
74 struct Job_progress
75 u12 abp
76 u4 level
77
78 struct Config
79 u3 battle_speed # 0=1 in-game, ..., 5=6 in-game
80 u1 is_wait_mode # 0=active, 1=wait???
81 u3 message_speed # 0=1 in-game, ..., 5=6 in-game
82 u1 command_set # 0=window, 1=shortcut
83 u5 menu_color_r
84 u5 menu_color_g
85 u5 menu_color_b
86 u1 padding
87 u1 reequip_mode # 0=optimum, 1=empty
88 u1 is_mono # 0=stereo, 1=mono
89 u1 is_memory_cursor # 0=reset, 1=memory
90 u4 unk0
91 u1 hide_atb_gauge # 0=show, 1=hide
92 u6 unk1
93 u1 is_controller_custom # 0=no, 1=yes
94 u1 is_controller_2p # 0=no, 1=yes
95 u8 button_A # Bit of action
96 u8 button_B # Bit of action
97 u8 button_X # Bit of action
98 u8 button_Y # Bit of action
99 u8 button_L # Bit of action
100 u8 button_R # Bit of action
101 u8 button_Select # Bit of action
102 4 of u8 character_player_nums # 0=controller 1, 1=controller 2
103 4 of 4 of u8 character_shortcut_commands # 0=ability_1, 1=ability_2, 2=ability_3, 3=ability_4
104
105 struct Vehicle
106 u2 mode_switching
107 u3 movement_type
108 u3 map_id
109 u7 unk0
110 u1 is_hidden # 0=show, 1=hide
111 u8 x
112 u8 y
113
114 struct Save_slot
115 4 of Character characters
116 256 of u8 inventory_item_ids
117 256 of u8 inventory_item_qtys
118 u24 unlocked_jobs
119 4 of 22 of Job_progress character_jobs_progress
120 4 of u8 character_abilities_learned_count
121 4 of 20 of u8 character_abilities_learned
122 u24 current_gil
123 u32 game_time_frames
124 u16 num_enemies_defeated
125 32 of u8 magic_learned
126 Config config
127 5 of 6 of u8 character_names # Bartz, Lenna, Galuf, Faris, Krile. Dialog is hardcoded for everyone except Bartz's name anyway...
128 6 of u8 unk0
129 u8 magic_lamp_next_summon
130 u8 num_battles_escaped # Brave Blade vs Chicken Knife
131 u8 wonder_rod_magic
132 9 of u8 unk1
133 u16 num_total_battles
134 u16 num_times_saved
135 u8 last_battle_results # 0=victory, 1=game over, 2=escaped
136 15 of u8 flags_battle_events
137 32 of u8 flags_treasure_opened
138 32 of u8 unk_probably_still_flags_treasure_opened
139 96 of u8 flags_events # RAM map mentions $D8E000. This is likely critical to story progression and scripting.
140 96 of u8 unk_probably_still_flags_events
141 u16 map_id_inner
142 u16 map_id_world
143 u8 pos_x
144 u8 pos_y
145 u8 current_character_sprite
146 u8 current_character_facing
147 u8 current_vehicle
148 Vehicle veh_chocobo
149 Vehicle veh_black_chocobo
150 Vehicle veh_hiryuu
151 Vehicle veh_submarine
152 Vehicle veh_steamship
153 Vehicle veh_airship
154 u16 teleport_map_id
155 u8 teleport_map_x
156 u8 teleport_map_y
157 u8 initial_seed
158 u8 walking_speed # 0=normal, 1=double (fast), 80=half (slow)
159 u8 timed_event_active
160 u16 timed_event_timer
161 u16 timed_event_end

View File

@ -0,0 +1,9 @@
struct ItemCost # All definitions here are intended to be overriden in code, but provide correctly-sized stubs for programs that don't care
u1 is_sellable
u1 is_sellprice_5gil
u6 exponent
u8 mantissa # buy_price = mantissa * int(pow(10, exponent)); sell_price = -1 if not is_sellable else (5 if is_sellprice_5gil else buy_price/2)
struct EquipStatBonus
u1 is_stat_bonus # 0 -> data is elemental bonus bitfield; 1 -> 4bit toggle fields for affected stats, 3bit selector of bonus enum
u7 data # Meaning changes based on is_stat_bonus
Can't render this file because it has a wrong number of fields in line 2.

121
data/LICENSE Normal file
View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

3
data/README.md Normal file
View File

@ -0,0 +1,3 @@
# ChocolateBirdData
The data definitions that ChocolateBird uses, separated out into its own repository so that other projects can easily use them.

View File

@ -0,0 +1,283 @@
# This is a reference implementation of parsing, serializing, and deserializing ChocolateBird's struct definitions.
# It is ported from the original GDscript to Python.
import logging
from io import TextIOWrapper
from struct import pack_into, unpack_from, calcsize
from collections.abc import Buffer
class LeftoverBits:
number_bits = 0
bit_buffer = 0 # Stored as an integer
class ReadBuffer:
backing_buffer: Buffer
position: int = 0
def __init__(self, backing_buffer, position: int = 0) -> None:
self.backing_buffer = backing_buffer
self.position = position
def get(self, format) -> tuple:
values = unpack_from(format, self.backing_buffer, self.position)
self.position += calcsize(format) # TODO: cache this
return values
class WriteBuffer:
backing_buffer: Buffer
position: int = 0
def __init__(self, backing_buffer, position: int = 0) -> None:
self.backing_buffer = backing_buffer
self.position = position
def put(self, format, *values) -> None:
pack_into(format, self.backing_buffer, self.position, *values)
self.position += calcsize(format) # TODO: cache this
class StructType:
name: str = None
def __repr__(self) -> str:
if self.name:
return self.name
return super().__repr__()
def get_value(self, buffer: ReadBuffer, leftover_bits: LeftoverBits):
raise NotImplementedError('Deserialization not implemented')
def put_value(self, buffer: WriteBuffer, value, leftover_bits: LeftoverBits):
raise NotImplementedError('Serialization not implemented')
class SimpleStruct(StructType):
format: str
def __init__(self, format, name=None) -> None:
self.format = format
self.name = name
def get_value(self, buffer: ReadBuffer, leftover_bits: LeftoverBits):
return buffer.get(self.format)[0]
def put_value(self, buffer: WriteBuffer, value, leftover_bits: LeftoverBits):
buffer.put(self.format, value)
class U24(StructType):
name = 'u24'
def get_value(self, buffer: ReadBuffer, leftover_bits: LeftoverBits):
u16, u8 = buffer.get('<HB')
return u16 | (u8 << 16)
def put_value(self, buffer: WriteBuffer, value, leftover_bits: LeftoverBits):
buffer.put('<HB', value & 0xFFFF, value >> 16)
class S24(StructType):
name = 's24'
def get_value(self, buffer: ReadBuffer, leftover_bits: LeftoverBits):
u16, u8 = buffer.get('<HB')
unsigned = u16 | (u8 << 16)
return unsigned - (2 * (unsigned & 0x800000))
def put_value(self, buffer: WriteBuffer, value, leftover_bits: LeftoverBits):
unsigned = value % 0x1000000
buffer.put('<HB', unsigned & 0xFFFF, unsigned >> 16)
class UBits(StructType):
bits = 8
def __init__(self, bits: int):
self.bits = bits
self.name = f'u{bits:d}'
def get_value(self, buffer: ReadBuffer, leftover_bits: LeftoverBits):
while leftover_bits.number_bits < self.bits:
leftover_bits.bit_buffer |= buffer.get('<B')[0] << leftover_bits.number_bits
leftover_bits.number_bits += 8
value = leftover_bits.bit_buffer & ((1 << self.bits)-1)
leftover_bits.bit_buffer = leftover_bits.bit_buffer >> self.bits
leftover_bits.number_bits -= self.bits
return value
def put_value(self, buffer: WriteBuffer, value, leftover_bits: LeftoverBits):
leftover_bits.bit_buffer |= value << leftover_bits.number_bits
leftover_bits.number_bits += self.bits
while leftover_bits.number_bits >= 8:
buffer.put('<B', leftover_bits.bit_buffer & 0xFF)
leftover_bits.number_bits -= 8
leftover_bits.bit_buffer = leftover_bits.bit_buffer >> 8
class Struct(StructType):
members: list # Array of [name, StructType]
def __init__(self, name=None) -> None:
self.name = name
self.members = []
def get_value(self, buffer: ReadBuffer, leftover_bits: LeftoverBits):
return {key: struct_type.get_value(buffer, leftover_bits) for key, struct_type in self.members}
def put_value(self, buffer: WriteBuffer, value, leftover_bits: LeftoverBits):
for key, struct_type in self.members:
if not (key in value):
logging.error(f'Key "{key}" missing from value supplied')
return
struct_type.put_value(buffer, value[key], leftover_bits)
class StructArrayType(StructType):
count: int
struct_type: StructType
def __init__(self, count, struct_type, name=None) -> None:
self.count = count
self.struct_type = struct_type
self.name = name
def get_value(self, buffer: ReadBuffer, leftover_bits: LeftoverBits) -> list:
return [self.struct_type.get_value(buffer, leftover_bits) for i in range(self.count)]
def put_value(self, buffer: WriteBuffer, value, leftover_bits: LeftoverBits) -> None:
if len(value) < self.count:
logging.error('Not enough values supplied')
return
for i in range(self.count):
self.struct_type.put_value(buffer, value[i], leftover_bits)
def get_base_structarraytypes() -> dict:
return {
'u8': SimpleStruct('<B', 'u8'),
's8': SimpleStruct('<b', 's8'),
'u16': SimpleStruct('<H', 'u16'),
's16': SimpleStruct('<h', 's16'),
'u24': U24(),
's24': S24(),
'u32': SimpleStruct('<I', 'u32'),
's32': SimpleStruct('<i', 's32'),
}
def get_structarraytype(type: str, existing_structs: dict):
tokens = type.split(' ')
t: str = tokens[-1]
inner_type: Struct = None
if t in existing_structs:
inner_type = existing_structs[t]
elif t[0] == 'u':
b: int = int(t[1:])
if b > 0:
inner_type = UBits(b)
existing_structs[f'u{b:d}'] = inner_type # Cache it for future use
if not inner_type:
logging.error(f'typestring "{type}" has no matches for "{t}" in existing structs')
return
l: int = len(tokens)
if l == 1:
return inner_type
# Our parsing goal is to turn 'a of b of c of d' into StructArrayType<StructArrayType<StructArrayType<d, c>, b>, a>
# Our strategy is to parse backwards over the tokens, changing inner_type at each point
# a of b of c of (d)
# a of b of (c of d)
# a of (b of c of d)
# (a of b of c of d)
# done
i: int = l-2
while i > -1:
match tokens[i]:
case 'of':
i -= 1
l1: int = int(tokens[i])
if l1 > 1:
inner_type = StructArrayType(l1, inner_type, name=type) # Might be worth caching these later on if we use them more
i -= 1
case k:
logging.error(f'Invalid keyword used in type designator: "{k}"')
return
return inner_type
def parse_struct_definitions_from_tsv_file(tsv_file: TextIOWrapper, existing_structs: dict) -> None:
current_struct: Struct
lines = tsv_file.read().rstrip().split('\n')
for line in lines:
# logging.debug(line)
tokens = line.split('\t')
size = len(tokens)
if size < 2:
continue
# Size is at least 2
type, label = tokens[:2]
if type == 'struct':
# New struct declaration
current_struct = Struct(name=label)
existing_structs[label] = current_struct
elif type and label:
current_struct.members.append([label, get_structarraytype(type, existing_structs)])
# TODO: Maybe store the trailing comments somewhere?
def parse_struct_definitions_from_tsv_filename(filename: str, existing_structs: dict) -> None:
with open(filename, 'r') as file:
parse_struct_definitions_from_tsv_file(file, existing_structs)
def load_ff5_snes_struct_definitions() -> dict:
existing_structs = get_base_structarraytypes()
parse_struct_definitions_from_tsv_filename('structs_SNES_stubs.tsv', existing_structs)
parse_struct_definitions_from_tsv_filename('5/structs/SNES_stubs.tsv', existing_structs)
parse_struct_definitions_from_tsv_filename('5/structs/SNES.tsv', existing_structs)
parse_struct_definitions_from_tsv_filename('5/structs/SNES_save.tsv', existing_structs)
return existing_structs
# Basic TSV dumper
# This is mostly unrelated, but helpful for debugging.
def flatten_keys(d: dict, prefix: str = '') -> dict:
output = {}
for k, v in d.items():
if isinstance(v, dict):
flat = flatten_keys(v, f'{prefix}{k}.')
for k2, v2 in flat.items():
output[k2] = v2
else:
output[f'{prefix}{k}'] = v
return output
def dump_tsv(filename, table):
table_flat = [flatten_keys(d) for d in table]
hex_digits = len(f'{len(table_flat)-1:X}') # See how long the hex representation of the last number will be, so we can zero-pad the rest to match.
hex_format = f'0{hex_digits}X'
with open(filename, 'w') as file:
headers = list(table_flat[0].keys())
file.write('\t'.join(['ID'] + headers) + '\n')
for i, entry in enumerate(table_flat):
file.write('\t'.join([f'0x{i:{hex_format}}'] + [str(entry[key]) for key in headers]) + '\n')
# Example usage: run this script with a positional filename argument for a FF5 .sfc and it will load EnemyStats from it.
if __name__ == '__main__':
existing_structs = load_ff5_snes_struct_definitions()
leftover_bits = LeftoverBits()
from sys import argv
if len(argv) > 1:
rom_filename = argv[1]
if rom_filename.endswith('.sfc'):
with open(rom_filename, 'rb') as file:
rom_data = file.read()
buffer = ReadBuffer(rom_data, 0x100000)
# enemy_stats = existing_structs['EnemyStats'].get_value(buffer, leftover_bits)
enemy_stats = get_structarraytype('384 of EnemyStats', existing_structs).get_value(buffer, leftover_bits)
print('Loaded EnemyStats table to enemy_stats! If you ran the python interpreter with -i flag, you can now examine it in the REPL.')
# Also add a basic dumper
if len(argv) > 2 and argv[2] == 'dump_tsv':
dump_tsv('enemy_stats.tsv', enemy_stats)
print('Dumped enemy_stats table to enemy_stats.tsv!')
else:
print(f'Argument "{rom_filename}" doesn\'t end in ".sfc", so it was not parsed as a FF5 SNES ROM.')
else:
print('Example usage: run this script with a positional filename argument for a FF5 .sfc and it will load EnemyStats from it.')

View File

@ -0,0 +1,29 @@
struct TileSNESMode7 # All definitions here are intended to be overriden in code, but provide correctly-sized stubs for programs that don't care
64 of u8 data
struct TileSNESMode7c
32 of u8 data
struct TileSNES4bpp
32 of u8 data
struct TileSNES3bpp
24 of u8 data
struct TileSNES2bpp
16 of u8 data
struct TileSNES1bpp
8 of u8 data
struct SNESTritile
24 of u8 data
struct ColorBGR555
u16 data
struct Palette16Of555 # Typed PoolColorArray in GDscript
16 of ColorBGR555 data
struct Palette128Of555 # Typed PoolColorArray in GDscript
128 of ColorBGR555 data
Can't render this file because it has a wrong number of fields in line 2.