Load enemy sprites
This commit is contained in:
parent
d1bb23b0f3
commit
19717c6b01
|
@ -49,7 +49,8 @@ I have mostly solved parsing of SNES menus in a sister project, however there ar
|
|||
- [x] Character sprites
|
||||
- [ ] Weapon sprites (solved problem, soon™)
|
||||
- [ ] Weapon animations (will hardcode these)
|
||||
- [ ] Enemy sprites (solved problem, soon™)
|
||||
- [x] Enemy sprites
|
||||
- [ ] Enemy sprite separate shadows
|
||||
- [ ] Backgrounds (solved problem, soon™)
|
||||
- [ ] Enemy AI (needs research)
|
||||
- [ ] Abilities (will hardcode these, with fixes and extensions where appropriate)
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
Label SNES PSX_file PSX_offset format Comment
|
||||
locations_bg_palettes 0x03BB00 /nar/ff5_binx.bin 0x03BF80 43 of Palette128Of555
|
||||
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_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
|
||||
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_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
|
||||
enemy_battle_sprite_tiles 0x150000 See enemy_battle_sprite_data for pointers
|
||||
character_battle_sprite_disabled_palette 0x00F867 /mnu/memsave.bin 0x000034 Palette16Of555
|
||||
character_battle_sprite_stone_palette 0x00F807 N/A N/A Palette16Of555 Also 0x199835
|
||||
tiles_fist 0x11D710 /btl/ff5_btl.bin 0x021D10 TileSNES3bpp Also /mnu/men_bin.eng:0x00D910
|
||||
|
|
|
|
@ -115,3 +115,15 @@ 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.
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 43.
|
|
@ -70,6 +70,7 @@ func load_snes_rom(filename: String):
|
|||
snes_data.job_levels.append(ability_list)
|
||||
print(snes_data.job_levels)
|
||||
SpriteLoader.load_from_structs(snes_data)
|
||||
SpriteLoader.load_enemy_battle_sprites(snes_data, buffer)
|
||||
MapLoader.load_snes_rom(rom_snes)
|
||||
|
||||
func load_psx_folder(_dirname: String):
|
||||
|
|
|
@ -5,6 +5,7 @@ const INDEX_FORMAT := globals.INDEX_FORMAT
|
|||
const snes_graphics := preload('res://scripts/loaders/snes/graphics.gd')
|
||||
const gba_graphics := preload('res://scripts/loaders/gba/graphics.gd')
|
||||
var shader_material = load('res://palette_mat.tres')
|
||||
const TILE_RECT := Rect2(0, 0, 8, 8)
|
||||
|
||||
# Offsets
|
||||
|
||||
|
@ -135,13 +136,12 @@ static func generate_palette_from_colorarray(colors: PoolColorArray, format:=Ima
|
|||
return img
|
||||
|
||||
static func make_tile_atlas(tile_images) -> Image:
|
||||
var r := Rect2(0, 0, 8, 8)
|
||||
var image = Image.new()
|
||||
image.create(128, 128, false, INDEX_FORMAT)
|
||||
var tile = 0
|
||||
for y in tile_images.size()/16:
|
||||
for x in 16:
|
||||
image.blit_rect(tile_images[tile], r, Vector2(x*8, y*8))
|
||||
image.blit_rect(tile_images[tile], TILE_RECT, Vector2(x*8, y*8))
|
||||
tile += 1
|
||||
return image
|
||||
|
||||
|
@ -273,6 +273,102 @@ static func make_tile_atlas(tile_images) -> Image:
|
|||
# print_debug('Invalid bpp "%s" in sprite blocks json' % bpp)
|
||||
# sprite_blocks[k] = tiles
|
||||
|
||||
# func load_snes_rom(rom: File):
|
||||
# snes_load_battle_sprites(rom)
|
||||
# snes_load_worldmap(rom)
|
||||
# # snes_load_map_sprites(rom)
|
||||
|
||||
# Cache these as they are shared between monsters
|
||||
var monster_battle_sprite_palettes := {} # offset -> 16 colour palette image
|
||||
var monster_battle_sprite_palette_textures := {} # offset -> 16 colour palette texture
|
||||
var monster_battle_sprite_images := {} # "tiles_offset:layout_id:large:bpp" -> tiles laid out in image
|
||||
var monster_battle_sprite_textures := {} # "tiles_offset:layout_id:large:bpp" -> tiles laid out in texture
|
||||
func load_enemy_battle_sprites(data: Dictionary, buffer: StreamPeerBuffer):
|
||||
var PAL: int = Common.SNES_PSX_addresses.enemy_battle_sprite_palettes.SNES
|
||||
var TILES: int = Common.SNES_PSX_addresses.enemy_battle_sprite_tiles.SNES
|
||||
var Palette16Of555 = RomLoader.structdefs.Palette16Of555
|
||||
data.monster_battle_sprites = []
|
||||
for monster in data.enemy_battle_sprite_data:
|
||||
var entry = {}
|
||||
# Fetch or generate+cache palette
|
||||
var palette_offset = (monster.palette_offset_hi << 12) + (monster.palette_offset_lo << 4)
|
||||
if not (palette_offset in monster_battle_sprite_palettes):
|
||||
buffer.seek(palette_offset + PAL)
|
||||
var colors = PoolColorArray()
|
||||
for i in 16:
|
||||
colors.append(snes_graphics.bgr555_to_color(buffer.get_u16()))
|
||||
var image := generate_palette_from_colorarray(colors)
|
||||
monster_battle_sprite_palettes[palette_offset] = image
|
||||
monster_battle_sprite_palette_textures[palette_offset] = texture_from_image(image)
|
||||
entry['palette'] = monster_battle_sprite_palette_textures[palette_offset]
|
||||
# Fetch or generate+cache tiles and layout
|
||||
var bpp := 3 if monster.is_3bpp else 4
|
||||
var tiles_offset = (monster.tileset_offset_hi << 11) + (monster.tileset_offset_lo << 3)
|
||||
var key: String
|
||||
if monster.is_large_layout:
|
||||
var layout = data.enemy_battle_sprite_layouts_large[monster.layout_id]
|
||||
key = '%04X:%02X:1:%d' % [tiles_offset, monster.layout_id, bpp]
|
||||
if not (key in monster_battle_sprite_images):
|
||||
buffer.seek(tiles_offset + TILES)
|
||||
var image := Image.new()
|
||||
image.create(128, 128, false, INDEX_FORMAT)
|
||||
var max_col := 0
|
||||
var max_row := 0
|
||||
if bpp == 3:
|
||||
for y in 16:
|
||||
for x in 16:
|
||||
if (layout[y] & (0x8000 >> x)):
|
||||
image.blit_rect(snes_graphics._3plane_to_tile(buffer.get_data(24)[1]), TILE_RECT, Vector2(x, y)*8)
|
||||
if max_row < y:
|
||||
max_row = y
|
||||
if max_col < x:
|
||||
max_col = x
|
||||
else:
|
||||
for y in 16:
|
||||
for x in 16:
|
||||
if (layout[y] & (0x8000 >> x)):
|
||||
image.blit_rect(snes_graphics._4plane_to_tile(buffer.get_data(32)[1]), TILE_RECT, Vector2(x, y)*8)
|
||||
if max_row < y:
|
||||
max_row = y
|
||||
if max_col < x:
|
||||
max_col = x
|
||||
image.crop(8*(max_col+1), 8*(max_row+1))
|
||||
monster_battle_sprite_images[key] = image
|
||||
monster_battle_sprite_textures[key] = texture_from_image(image)
|
||||
else:
|
||||
var layout = data.enemy_battle_sprite_layouts_small[monster.layout_id]
|
||||
key = '%04X:%02X:0:%d' % [tiles_offset, monster.layout_id, bpp]
|
||||
if not (key in monster_battle_sprite_images):
|
||||
buffer.seek(tiles_offset + TILES)
|
||||
var image := Image.new()
|
||||
image.create(64, 64, false, INDEX_FORMAT)
|
||||
var max_col := 0
|
||||
var max_row := 0
|
||||
if bpp == 3:
|
||||
for y in 8:
|
||||
for x in 8:
|
||||
if (layout[y] & (0x80 >> x)):
|
||||
image.blit_rect(snes_graphics._3plane_to_tile(buffer.get_data(24)[1]), TILE_RECT, Vector2(x, y)*8)
|
||||
if max_row < y:
|
||||
max_row = y
|
||||
if max_col < x:
|
||||
max_col = x
|
||||
else:
|
||||
for y in 8:
|
||||
for x in 8:
|
||||
if (layout[y] & (0x80 >> x)):
|
||||
image.blit_rect(snes_graphics._4plane_to_tile(buffer.get_data(32)[1]), TILE_RECT, Vector2(x, y)*8)
|
||||
if max_row < y:
|
||||
max_row = y
|
||||
if max_col < x:
|
||||
max_col = x
|
||||
image.crop(8*(max_col+1), 8*(max_row+1))
|
||||
monster_battle_sprite_images[key] = image
|
||||
monster_battle_sprite_textures[key] = texture_from_image(image)
|
||||
entry['sprite'] = monster_battle_sprite_textures[key]
|
||||
# Save monster
|
||||
data.monster_battle_sprites.append(entry)
|
||||
|
||||
static func bias_tile(unbiased: PoolByteArray, bias: int) -> Image:
|
||||
var image := Image.new()
|
||||
var biased = ByteArray(64)
|
||||
|
@ -281,11 +377,6 @@ static func bias_tile(unbiased: PoolByteArray, bias: int) -> Image:
|
|||
image.create_from_data(8, 8, false, INDEX_FORMAT, biased)
|
||||
return image
|
||||
|
||||
# func load_snes_rom(rom: File):
|
||||
# snes_load_battle_sprites(rom)
|
||||
# snes_load_worldmap(rom)
|
||||
# # snes_load_map_sprites(rom)
|
||||
|
||||
func load_from_structs(data: Dictionary):
|
||||
# Load Battle sprites
|
||||
for character_tiles in data.character_battle_sprite_tiles:
|
||||
|
@ -296,7 +387,7 @@ func load_from_structs(data: Dictionary):
|
|||
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_image.blit_rect(job_tiles[sprite_tiles[i]], TILE_RECT, 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
|
||||
|
@ -335,7 +426,7 @@ func load_from_structs(data: Dictionary):
|
|||
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))
|
||||
image.blit_rect(tile_images[src_idx], TILE_RECT, 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)
|
||||
|
@ -353,7 +444,7 @@ func load_from_structs(data: Dictionary):
|
|||
# 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))
|
||||
# image.blit_rect(tile_images[tile], TILE_RECT, 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)
|
||||
|
@ -397,7 +488,7 @@ func load_gba_rom(filename: String):
|
|||
var strip_image = Image.new()
|
||||
strip_image.create(16, 24 * num_Character_Battle_Sprite_Layouts, false, INDEX_FORMAT)
|
||||
for i in range(6 * num_Character_Battle_Sprite_Layouts):
|
||||
strip_image.blit_rect(tiles[battle_strip_layouts[i]], Rect2(0, 0, 8, 8), Vector2((i%2) * 8, (i/2) * 8))
|
||||
strip_image.blit_rect(tiles[battle_strip_layouts[i]], TILE_RECT, Vector2((i%2) * 8, (i/2) * 8))
|
||||
strip_images.append(strip_image)
|
||||
strip_textures.append(texture_from_image(strip_image))
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
extends Control
|
||||
|
||||
const palette_mat := preload('res://palette_mat.tres')
|
||||
var save_slots = []
|
||||
var save_slot_dicts = []
|
||||
|
||||
|
@ -25,6 +25,16 @@ func _ready():
|
|||
$PartyMenu.update_labels(data)
|
||||
ThemeManager.set_menu_color_555(data.config.menu_color_r, data.config.menu_color_g, data.config.menu_color_b)
|
||||
|
||||
var monster_box := GridContainer.new()
|
||||
monster_box.columns = 8
|
||||
add_child(monster_box)
|
||||
for mon in RomLoader.snes_data.monster_battle_sprites:
|
||||
var t := TextureRect.new()
|
||||
t.material = palette_mat.duplicate()
|
||||
t.texture = mon.sprite
|
||||
t.material.set_shader_param('palette', mon.palette)
|
||||
monster_box.add_child(t)
|
||||
|
||||
# var lbl = Label.new()
|
||||
# for i in 22:
|
||||
# lbl.text = lbl.text + '%s - %s\n' % [StringLoader.get_job_name(i), StringLoader.get_job_desc(i)]
|
||||
|
|
Loading…
Reference in New Issue