Migrate worldmap and battle strip generation to struct system
This commit is contained in:
parent
3a35eb73f0
commit
11059735ee
|
@ -1,9 +1,11 @@
|
||||||
Label SNES PSX_file PSX_offset format Comment
|
Label SNES PSX_file PSX_offset format Comment
|
||||||
locations_bg_palettes 0x03BB00 /nar/ff5_binx.bin 0x03BF80 43 of Palette128Of555
|
locations_bg_palettes 0x03BB00 /nar/ff5_binx.bin 0x03BF80 43 of Palette128Of555
|
||||||
worldmap_blocks 0x0FF0C0 /nar/ff5_binx.bin 0x040300 3 of 192 of 4 of u8
|
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_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
|
worldmap_palettes 0x0FFCC0 /nar/ff5_binx.bin 0x040000 3 of Palette128Of555
|
||||||
worldmap_tiles 0x1B8000 /nar/ff5_bin3.bin 0x039B00 3 of 256 of TileSNESMode7c Add the biases
|
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
|
||||||
character_battle_sprite_tiles 0x120000 /mnu/men_bin.eng 0x010200 5 of 22 of 48 of TileSNES4bpp
|
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
|
character_battle_sprite_palettes 0x14A3C0 /btl/ff5_btl.bin 0x0273C0 5 of 22 of Palette16Of555 Also /mnu/men_bin.eng:0x03A5C0
|
||||||
character_battle_sprite_layouts 0x14B997 /btl/ff5_btl.bin 0x028997 11 of 6 of u8
|
character_battle_sprite_layouts 0x14B997 /btl/ff5_btl.bin 0x028997 11 of 6 of u8
|
||||||
|
|
|
|
@ -27,8 +27,8 @@ func load_snes_rom(filename: String):
|
||||||
var bytes := rom_snes.get_buffer(rom_snes.get_len())
|
var bytes := rom_snes.get_buffer(rom_snes.get_len())
|
||||||
var buffer = StreamPeerBuffer.new()
|
var buffer = StreamPeerBuffer.new()
|
||||||
buffer.data_array = bytes
|
buffer.data_array = bytes
|
||||||
SpriteLoader.load_snes_rom(rom_snes)
|
# SpriteLoader.load_snes_rom(rom_snes)
|
||||||
MapLoader.load_snes_rom(rom_snes)
|
# MapLoader.load_snes_rom(rom_snes)
|
||||||
StringLoader.load_snes_rom(rom_snes, true)
|
StringLoader.load_snes_rom(rom_snes, true)
|
||||||
# Don't do this concurrently, avoid file pointer conflicts
|
# Don't do this concurrently, avoid file pointer conflicts
|
||||||
#var _thread_error = thread.start(SoundLoader, 'parse_rom', rom_snes)
|
#var _thread_error = thread.start(SoundLoader, 'parse_rom', rom_snes)
|
||||||
|
@ -45,7 +45,20 @@ func load_snes_rom(filename: String):
|
||||||
if not s:
|
if not s:
|
||||||
assert(false, 'Invalid StructType: "%s"' % d.format)
|
assert(false, 'Invalid StructType: "%s"' % d.format)
|
||||||
buffer.seek(d.SNES)
|
buffer.seek(d.SNES)
|
||||||
snes_data[key] = s.get_value(buffer, [0, 0])
|
if '.' in key:
|
||||||
|
var keysplit: PoolStringArray = key.split('.', 1)
|
||||||
|
var k0 := keysplit[0]
|
||||||
|
var k1 = keysplit[1]
|
||||||
|
if k1.is_valid_integer():
|
||||||
|
k1 = int(k1)
|
||||||
|
if not (k0 in snes_data):
|
||||||
|
snes_data[k0] = {k1: s.get_value(buffer, [0, 0])}
|
||||||
|
else:
|
||||||
|
snes_data[k0][k1] = s.get_value(buffer, [0, 0])
|
||||||
|
else:
|
||||||
|
snes_data[key] = s.get_value(buffer, [0, 0])
|
||||||
|
SpriteLoader.load_from_structs(snes_data)
|
||||||
|
MapLoader.load_snes_rom(rom_snes)
|
||||||
|
|
||||||
func load_psx_folder(_dirname: String):
|
func load_psx_folder(_dirname: String):
|
||||||
pass
|
pass
|
||||||
|
@ -73,24 +86,6 @@ func _ready():
|
||||||
var _error := psx_productcode_regex.compile('(S[A-Z]{3}_\\d{3}\\.\\d{2});(\\d)')
|
var _error := psx_productcode_regex.compile('(S[A-Z]{3}_\\d{3}\\.\\d{2});(\\d)')
|
||||||
load_snes_rom(ROM_filename)
|
load_snes_rom(ROM_filename)
|
||||||
# Debugging breakpoint
|
# Debugging breakpoint
|
||||||
for i in 128:
|
|
||||||
var weapon = snes_data.tbl_weapons[i]
|
|
||||||
if weapon.byte_2_leftover:
|
|
||||||
print('Weapon %d ($%02X) has byte_2_leftover set' % [i, i])
|
|
||||||
if weapon.byte_8_leftover:
|
|
||||||
print('Weapon %d ($%02X) has byte_8_leftover set' % [i, i])
|
|
||||||
if weapon['is_5.4']:
|
|
||||||
print('Weapon %d ($%02X) has 5.4 set' % [i, i])
|
|
||||||
for i in 96:
|
|
||||||
var armor = snes_data.tbl_armors[i]
|
|
||||||
if armor.byte_0_leftover:
|
|
||||||
print('Armor %d ($%02X) "%s" has byte_0_leftover set' % [i, i, StringLoader.tables.items[i+0x80]])
|
|
||||||
if armor.byte_4_leftovers:
|
|
||||||
print('Armor %d ($%02X) "%s" has byte_4_leftovers set' % [i, i, StringLoader.tables.items[i+0x80]])
|
|
||||||
if armor.byte_2_leftovers:
|
|
||||||
print('Armor %d ($%02X) "%s" has byte_2_leftovers set to %d ($%02X)' % [i, i, StringLoader.tables.items[i+0x80], armor.byte_2_leftovers, armor.byte_2_leftovers])
|
|
||||||
if armor.gear_special:
|
|
||||||
print('Armor %d ($%02X) "%s" has gear_special set to %d ($%02X)' % [i, i, StringLoader.tables.items[i+0x80], armor.gear_special, armor.gear_special])
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
func _exit_tree() -> void:
|
||||||
|
|
|
@ -121,6 +121,19 @@ static func generate_palette(rom: File, offset: int, length: int = 16) -> Image:
|
||||||
length = 16
|
length = 16
|
||||||
return generate_palette_rgb8(rom, offset, length)
|
return generate_palette_rgb8(rom, offset, length)
|
||||||
|
|
||||||
|
static func generate_palette_from_colorarray(colors: PoolColorArray, format:=Image.FORMAT_RGBF) -> Image:
|
||||||
|
var img := Image.new()
|
||||||
|
var rows := len(colors)/16
|
||||||
|
img.create(16, rows, false, format)
|
||||||
|
img.lock()
|
||||||
|
var i := 0
|
||||||
|
for y in rows:
|
||||||
|
for x in 16:
|
||||||
|
img.set_pixel(x, y, colors[i])
|
||||||
|
i += 1
|
||||||
|
img.unlock()
|
||||||
|
return img
|
||||||
|
|
||||||
static func make_tile_atlas(tile_images) -> Image:
|
static func make_tile_atlas(tile_images) -> Image:
|
||||||
var r := Rect2(0, 0, 8, 8)
|
var r := Rect2(0, 0, 8, 8)
|
||||||
var image = Image.new()
|
var image = Image.new()
|
||||||
|
@ -260,12 +273,90 @@ func snes_load_map_sprites(rom: File):
|
||||||
print_debug('Invalid bpp "%s" in sprite blocks json' % bpp)
|
print_debug('Invalid bpp "%s" in sprite blocks json' % bpp)
|
||||||
sprite_blocks[k] = tiles
|
sprite_blocks[k] = tiles
|
||||||
|
|
||||||
|
static func bias_tile(unbiased: PoolByteArray, bias: int) -> Image:
|
||||||
|
var image := Image.new()
|
||||||
|
var biased = ByteArray(64)
|
||||||
|
for i in 64:
|
||||||
|
biased[i] = unbiased[i] + bias
|
||||||
|
image.create_from_data(8, 8, false, INDEX_FORMAT, biased)
|
||||||
|
return image
|
||||||
|
|
||||||
func load_snes_rom(rom: File):
|
func load_snes_rom(rom: File):
|
||||||
snes_load_battle_sprites(rom)
|
snes_load_battle_sprites(rom)
|
||||||
snes_load_worldmap(rom)
|
snes_load_worldmap(rom)
|
||||||
# snes_load_map_sprites(rom)
|
# snes_load_map_sprites(rom)
|
||||||
|
|
||||||
|
func load_from_structs(data: Dictionary):
|
||||||
|
# Load Battle sprites
|
||||||
|
for character_tiles in data.character_battle_sprite_tiles:
|
||||||
|
for job_tiles in character_tiles:
|
||||||
|
var strip_image = Image.new()
|
||||||
|
# Should probably refactor later
|
||||||
|
strip_image.create(16, 24 * num_Character_Battle_Sprite_Layouts, false, INDEX_FORMAT)
|
||||||
|
for sprite in num_Character_Battle_Sprite_Layouts:
|
||||||
|
var sprite_tiles: PoolByteArray = data.character_battle_sprite_layouts[sprite]
|
||||||
|
for i in 6:
|
||||||
|
strip_image.blit_rect(job_tiles[sprite_tiles[i]], Rect2(0, 0, 8, 8), Vector2((i%2) * 8, ((i/2) * 8) + (sprite * 24)))
|
||||||
|
strip_images.append(strip_image)
|
||||||
|
strip_textures.append(texture_from_image(strip_image))
|
||||||
|
# Character Battle Sprite Palettes
|
||||||
|
for character_palettes in data.character_battle_sprite_palettes:
|
||||||
|
for job_palette in character_palettes:
|
||||||
|
character_battle_sprite_palette_textures.append(texture_from_image(generate_palette_from_colorarray(job_palette)))
|
||||||
|
character_battle_sprite_palette_disabled_texture = texture_from_image(generate_palette_from_colorarray(data.character_battle_sprite_disabled_palette))
|
||||||
|
character_battle_sprite_palette_stone_texture = texture_from_image(generate_palette_from_colorarray(data.character_battle_sprite_stone_palette))
|
||||||
|
weapon_textures['Fist'] = texture_from_image(data.tiles_fist)
|
||||||
|
# Load World Map
|
||||||
|
# Load Worldmap Graphics
|
||||||
|
var worldmap_tile_counts = [256, 256, 128] # Only 128 underwater tiles
|
||||||
|
for world_ts in 3: # Bartz/Combined World, Galuf World, Underwater (world tilesets, not to be confused with the 5 world maps)
|
||||||
|
var tile_count: int = worldmap_tile_counts[world_ts]
|
||||||
|
var image := generate_palette_from_colorarray(data.worldmap_palettes[world_ts])
|
||||||
|
worldmap_palette_imgs.append(image)
|
||||||
|
worldmap_palette_textures.append(texture_from_image(image))
|
||||||
|
var tile_biases: PoolByteArray = data.worldmap_tiles.bias[world_ts]
|
||||||
|
var tile_images_unbiased = data.worldmap_tiles[world_ts]
|
||||||
|
var tile_images := []
|
||||||
|
for i in tile_count:
|
||||||
|
tile_images.append(bias_tile(tile_images_unbiased[i].get_data(), tile_biases[i]))
|
||||||
|
if world_ts == 0: # Waterfall hack: lay it out vertically, pushing out dummy tiles
|
||||||
|
tile_images[0x97] = tile_images[0x88]
|
||||||
|
tile_images[0x98] = tile_images[0x87]
|
||||||
|
worldmap_tile_individual_imgs.append(tile_images)
|
||||||
|
worldmap_tile_atlas_textures.append(texture_from_image(make_tile_atlas(tile_images)))
|
||||||
|
# Block definitions
|
||||||
|
var block_images = []
|
||||||
|
var block_textures = []
|
||||||
|
var block_tile_ids := PoolByteArray()
|
||||||
|
for block in 0xC0: # 192 blocks per world tileset
|
||||||
|
image = Image.new()
|
||||||
|
image.create(16, 16, false, INDEX_FORMAT)
|
||||||
|
for i in 4:
|
||||||
|
var src_idx: int = data.worldmap_blocks[world_ts][i][block]
|
||||||
|
block_tile_ids.append(src_idx)
|
||||||
|
if src_idx < tile_count:
|
||||||
|
image.blit_rect(tile_images[src_idx], Rect2(0, 0, 8, 8), Vector2((i%2)*8, (i/2)*8))
|
||||||
|
block_images.append(image)
|
||||||
|
block_textures.append(texture_from_image(image))
|
||||||
|
worldmap_block_individual_imgs.append(block_images)
|
||||||
|
worldmap_block_individual_textures.append(block_textures)
|
||||||
|
worldmap_block_tile_ids.append(block_tile_ids)
|
||||||
|
# Make block atlas
|
||||||
|
# image = Image.new()
|
||||||
|
# image.create(16*16, 16*12, false, INDEX_FORMAT)
|
||||||
|
# for block in 0xC0:
|
||||||
|
# image.blit_rect(block_images[block], Rect2(0, 0, 16, 16), Vector2((block%16)*16, (block/16)*16))
|
||||||
|
# worldmap_block_atlas_imgs.append(image)
|
||||||
|
# worldmap_block_atlas_textures.append(texture_from_image(image))
|
||||||
|
|
||||||
|
# # DEBUG: Make tile atlas
|
||||||
|
# image = Image.new()
|
||||||
|
# image.create(16*8, (tile_count/16)*8, false, INDEX_FORMAT)
|
||||||
|
# for tile in tile_count:
|
||||||
|
# image.blit_rect(tile_images[tile], Rect2(0, 0, 8, 8), Vector2((tile%16)*8, (tile/16)*8))
|
||||||
|
# worldmap_tile_atlas_textures.append(texture_from_image(image))
|
||||||
|
|
||||||
|
MapLoader.update_worldmap_block_tile_ids(worldmap_block_tile_ids)
|
||||||
|
|
||||||
const gba_marker := 'FINAL FANTASY V ADVANCE SYGMAB'
|
const gba_marker := 'FINAL FANTASY V ADVANCE SYGMAB'
|
||||||
const gba_marker_pos_US := 0x12FE10
|
const gba_marker_pos_US := 0x12FE10
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
shader_type canvas_item;
|
shader_type canvas_item;
|
||||||
uniform sampler2D tile_atlas : hint_normal;
|
uniform sampler2D tile_atlas : hint_normal;
|
||||||
uniform sampler2D palette : hint_normal;
|
uniform sampler2D palette : hint_normal;
|
||||||
|
uniform float palette_rows = 8.0; // 128 colours
|
||||||
// uniform float tile_width = 8.0;
|
// uniform float tile_width = 8.0;
|
||||||
uniform float tilemap_width = 512.0; // Require square tilemap for now
|
uniform float tilemap_width = 512.0; // Require square tilemap for now
|
||||||
uniform bool enable_sea_scroll = true; // Disable on underwater maps (tileset 3)
|
uniform bool enable_sea_scroll = true; // Disable on underwater maps (tileset 3)
|
||||||
|
@ -73,7 +74,7 @@ void fragment() {
|
||||||
vec2 lut_uv = get_tile_atlas_uv(s, UV);
|
vec2 lut_uv = get_tile_atlas_uv(s, UV);
|
||||||
float color_id = texture(tile_atlas, lut_uv).r;
|
float color_id = texture(tile_atlas, lut_uv).r;
|
||||||
float color_idx16 = color_id * index_scale;
|
float color_idx16 = color_id * index_scale;
|
||||||
float pal_row = trunc(color_idx16) / 16.0;
|
float pal_row = trunc(color_idx16) / palette_rows;
|
||||||
float pal_col = fract(color_idx16);
|
float pal_col = fract(color_idx16);
|
||||||
vec2 palette_uv = vec2(pal_col, pal_row);
|
vec2 palette_uv = vec2(pal_col, pal_row);
|
||||||
COLOR = texture(palette, palette_uv);
|
COLOR = texture(palette, palette_uv);
|
||||||
|
|
|
@ -25,11 +25,11 @@ func _ready():
|
||||||
$PartyMenu.update_labels(data)
|
$PartyMenu.update_labels(data)
|
||||||
ThemeManager.set_menu_color_555(data.config.menu_color_r, data.config.menu_color_g, data.config.menu_color_b)
|
ThemeManager.set_menu_color_555(data.config.menu_color_r, data.config.menu_color_g, data.config.menu_color_b)
|
||||||
|
|
||||||
var lbl = Label.new()
|
# var lbl = Label.new()
|
||||||
for i in 22:
|
# for i in 22:
|
||||||
lbl.text = lbl.text + '%s - %s\n' % [StringLoader.get_job_name(i), StringLoader.get_job_desc(i)]
|
# lbl.text = lbl.text + '%s - %s\n' % [StringLoader.get_job_name(i), StringLoader.get_job_desc(i)]
|
||||||
for i in 78:
|
# for i in 78:
|
||||||
lbl.text = lbl.text + '\n%s - %s' % [StringLoader.get_ability_name(i), StringLoader.get_ability_desc(i)]
|
# lbl.text = lbl.text + '\n%s - %s' % [StringLoader.get_ability_name(i), StringLoader.get_ability_desc(i)]
|
||||||
for i in range(128, 161):
|
# for i in range(128, 161):
|
||||||
lbl.text = lbl.text + '\n%s - %s' % [StringLoader.get_ability_name(i), StringLoader.get_ability_desc(i)]
|
# lbl.text = lbl.text + '\n%s - %s' % [StringLoader.get_ability_name(i), StringLoader.get_ability_desc(i)]
|
||||||
add_child(lbl)
|
# add_child(lbl)
|
||||||
|
|
|
@ -14,14 +14,12 @@ theme = ExtResource( 6 )
|
||||||
script = ExtResource( 3 )
|
script = ExtResource( 3 )
|
||||||
|
|
||||||
[node name="audio_system" parent="." instance=ExtResource( 5 )]
|
[node name="audio_system" parent="." instance=ExtResource( 5 )]
|
||||||
visible = false
|
|
||||||
position = Vector2( 0, 160 )
|
position = Vector2( 0, 160 )
|
||||||
|
|
||||||
[node name="worldmap_system" parent="." instance=ExtResource( 2 )]
|
[node name="worldmap_system" parent="." instance=ExtResource( 2 )]
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="battle_sprites" parent="." instance=ExtResource( 4 )]
|
[node name="battle_sprites" parent="." instance=ExtResource( 4 )]
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="PartyMenu" parent="." instance=ExtResource( 1 )]
|
[node name="PartyMenu" parent="." instance=ExtResource( 1 )]
|
||||||
|
visible = false
|
||||||
margin_right = 320.0
|
margin_right = 320.0
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
shader = ExtResource( 1 )
|
shader = ExtResource( 1 )
|
||||||
|
shader_param/palette_rows = 8.0
|
||||||
shader_param/tilemap_width = 512.0
|
shader_param/tilemap_width = 512.0
|
||||||
shader_param/enable_sea_scroll = true
|
shader_param/enable_sea_scroll = true
|
||||||
shader_param/enable_waterfall_scroll = true
|
shader_param/enable_waterfall_scroll = true
|
||||||
|
|
Loading…
Reference in New Issue