Add HexStringViewer

A test scene for visually scanning for strings within the ROM
This commit is contained in:
Luke Hubmayer-Werner 2023-08-16 22:05:16 +09:30
parent a60639760f
commit c9dcb8a17c
6 changed files with 95 additions and 11 deletions

View File

@ -74,3 +74,4 @@ worldmap_tiles.1 0x1BA000 /nar/ff5_bin3.bin 0x039B00 256 of TileSNESMode7c Add t
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
74 worldmap_tiles.2 0x1BC000 /nar/ff5_bin3.bin 0x039B00 128 of TileSNESMode7c Add the biases
75 font_glyphs_kanji 0x1BD000 426 of SNESTritile length of 0x27F0
76 ? 0x1BF800
77 RPGe_font_character_widths 0x203225 512 of u8 RPGe only, Includes the 1px spacing

View File

@ -17,6 +17,7 @@ var GBA_filename := '2564 - Final Fantasy V Advance (U)(Independent).gba'
var rom_snes := File.new()
var snes_data := {}
var snes_bytes: PoolByteArray
var thread := Thread.new()
func load_snes_rom(filename: String):
@ -24,7 +25,9 @@ func load_snes_rom(filename: String):
if error == OK:
# Copy entire SNES ROM to a buffer for StreamPeerBuffer usage.
# Unfortunately, the File API is different and slightly worse than the StreamPeer API.
var bytes := rom_snes.get_buffer(rom_snes.get_len())
var rom_size := rom_snes.get_len()
var bytes := rom_snes.get_buffer(rom_size)
self.snes_bytes = bytes
var buffer = StreamPeerBuffer.new()
buffer.data_array = bytes
# SpriteLoader.load_snes_rom(rom_snes)
@ -35,7 +38,7 @@ func load_snes_rom(filename: String):
# Can concurrently work with the preloaded StreamPeerBuffer though
for key in Common.SNES_PSX_addresses:
var d = Common.SNES_PSX_addresses[key]
if d.format:
if d.format and (d.SNES < rom_size): # Don't try to grab RPGe bank E0-E7 stuff from a smaller JP ROM
var s: STRUCT.StructType
if d.format in structdefs:
s = structdefs[d.format]

20
shaders/hex2font.gdshader Normal file
View File

@ -0,0 +1,20 @@
shader_type canvas_item;
uniform sampler2D glyph_atlas : hint_normal;
uniform vec2 tilemap_size = vec2(32.0, 20.0); // Update this to match the texture size
// tile_atlas hardcoded to 64x4 tiles for now
void fragment() {
// GLES2
vec2 xy = UV * tilemap_size; // Texel-space coord of our texture
float t = texture(TEXTURE, UV).r;
int tile_idx = int(t * 255.0); // Luminosity channel (any RGB channel works)
// Convert tile_idx to a texel coordinate, then to a UV coordinate
ivec2 tile_xy = ivec2(tile_idx%64, tile_idx/64);
vec2 tile_uv = vec2(tile_xy)/64.0;
// Get sub-tile UV
vec2 sub_tile_uv = fract(xy);
vec2 uv = tile_uv + (sub_tile_uv/64.0);
COLOR = texture(glyph_atlas, uv);
}

View File

@ -35,12 +35,6 @@ func _ready():
t.material.set_shader_param('palette', mon.palette)
monster_box.add_child(t)
#var battle_bg := OptionButton.new()
#for i in len(SpriteLoader.battle_backgrounds):
# battle_bg.add_item('BG %d' % i)
#battle_bg.connect('item_focused', $BattleScene, 'set_bg')
#battle_bg.connect('item_selected', $BattleScene, 'set_bg')
#add_child(battle_bg)
var bbg := SpinBox.new()
bbg.max_value = len(SpriteLoader.battle_backgrounds) - 1
bbg.connect('value_changed', $BattleScene, 'set_bg')
@ -49,9 +43,9 @@ func _ready():
bbg.align = LineEdit.ALIGN_RIGHT
add_child(bbg)
var fontbox := TextureRect.new()
fontbox.texture = SpriteLoader.font_atlas_texture
add_child(fontbox)
# var fontbox := TextureRect.new()
# fontbox.texture = SpriteLoader.font_atlas_texture
# add_child(fontbox)
# var lbl = Label.new()
# for i in 22:
@ -61,3 +55,5 @@ func _ready():
# for i in range(128, 161):
# lbl.text = lbl.text + '\n%s - %s' % [StringLoader.get_ability_name(i), StringLoader.get_ability_desc(i)]
# add_child(lbl)

View File

@ -0,0 +1,56 @@
extends Control
const hex2font_shader := preload('res://shaders/hex2font.gdshader')
var hexbox: TextureRect
var hexbox_rows: int
var hexbox_cols: int
func make_hexview(data: PoolByteArray, width: int = 256):
var hex2font_mat := ShaderMaterial.new()
hex2font_mat.shader = hex2font_shader
hex2font_mat.set_shader_param('glyph_atlas', SpriteLoader.font_atlas_texture)
var hex_img := Image.new()
var l := len(RomLoader.snes_bytes)
self.hexbox_cols = width
self.hexbox_rows = l / self.hexbox_cols
var remainder = l % self.hexbox_cols
if remainder:
self.hexbox_rows += 1
var padding = PoolByteArray()
padding.resize(self.hexbox_cols - remainder)
padding.fill(0)
data = data + padding
hex2font_mat.set_shader_param('tilemap_size', Vector2(self.hexbox_cols, self.hexbox_rows))
hex_img.create_from_data(self.hexbox_cols, self.hexbox_rows, false, Image.FORMAT_L8, data)
hexbox = TextureRect.new()
hexbox.texture = SpriteLoader.texture_from_image(hex_img)
hexbox.material = hex2font_mat
hexbox.rect_scale *= 4
add_child(hexbox)
func _ready() -> void:
ProjectSettings.set_setting('display/window/size/snap_to_integer', false)
make_hexview(RomLoader.snes_bytes, 480)
func scroll_hexview(rows: int):
var current_row: int = (-hexbox.rect_position.y)/4
var next_row = current_row + rows
if next_row > (hexbox_rows - 270):
next_row = hexbox_rows - 270
if next_row < 0:
next_row = 0
hexbox.rect_position.y = -next_row * 4
func _input(event: InputEvent) -> void:
if event is InputEventMouseButton:
match event.button_index:
BUTTON_WHEEL_DOWN:
scroll_hexview(16)
BUTTON_WHEEL_UP:
scroll_hexview(-16)
elif event is InputEventMouseMotion:
var row: int = (event.position.y - hexbox.rect_position.y) / 4
var col: int = event.position.x / 4
var address: int = col + (row * 480)
hexbox.set_tooltip('0x%06X' % address)

View File

@ -0,0 +1,8 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://widgets/HexStringViewer.gd" type="Script" id=1]
[node name="HexStringViewer" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )