Refactor Debug menu, and add Party Menu for saves
This commit is contained in:
parent
48c6ed2c3b
commit
923e2f463e
|
@ -16,7 +16,7 @@ script_encryption_key=""
|
|||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
variant/export_type=0
|
||||
vram_texture_compression/for_desktop=true
|
||||
vram_texture_compression/for_desktop=false
|
||||
vram_texture_compression/for_mobile=false
|
||||
html/export_icon=true
|
||||
html/custom_html_shell=""
|
||||
|
|
37
globals.gd
37
globals.gd
|
@ -2,6 +2,43 @@ extends Node
|
|||
|
||||
const INDEX_FORMAT := Image.FORMAT_L8
|
||||
|
||||
enum Menu {
|
||||
LOADER,
|
||||
MAIN,
|
||||
LOAD_SAVE,
|
||||
WORLD_MAP,
|
||||
FIELD_MAP,
|
||||
PARTY,
|
||||
SHOP,
|
||||
BATTLE,
|
||||
DEBUG,
|
||||
DEBUG_AUDIO_SYSTEM,
|
||||
DEBUG_BATTLE_SPRITES,
|
||||
}
|
||||
|
||||
const MENUS = {
|
||||
Menu.PARTY: ['res://widgets/PartyMenu.tscn', 'Party Menu'],
|
||||
Menu.BATTLE: ['res://widgets/BattleScene.tscn', 'Battle'],
|
||||
Menu.LOAD_SAVE: ['res://widgets/SaveSlotSelect.tscn', 'Load Save'],
|
||||
Menu.DEBUG: ['res://test/debug_menu.tscn', 'Debug Menu'],
|
||||
Menu.DEBUG_BATTLE_SPRITES: ['res://test/battle_sprites.tscn', 'Battle Sprites'],
|
||||
Menu.DEBUG_AUDIO_SYSTEM: ['res://test/audio_system.tscn', 'Audio'],
|
||||
Menu.WORLD_MAP: ['res://test/worldmap_system.tscn', 'World Map'],
|
||||
}
|
||||
|
||||
const INITIAL_MENUS = [
|
||||
Menu.LOAD_SAVE,
|
||||
]
|
||||
|
||||
const POST_ROM_MENUS = [
|
||||
Menu.DEBUG,
|
||||
Menu.WORLD_MAP,
|
||||
Menu.PARTY,
|
||||
Menu.BATTLE,
|
||||
Menu.DEBUG_BATTLE_SPRITES,
|
||||
Menu.DEBUG_AUDIO_SYSTEM,
|
||||
]
|
||||
|
||||
const FOLDER_ICON := preload('res://theme/icons/file_folder.tres')
|
||||
const ALLOWED_EXTS := PoolStringArray(['bin', 'iso', 'sfc', 'smc', 'srm', 'gba'])
|
||||
const CD_EXTS := PoolStringArray(['bin', 'iso']) # If you have a weird disc image format, you can mount it yourself, leave me out of it
|
||||
|
|
55
main.gd
55
main.gd
|
@ -1,43 +1,46 @@
|
|||
extends Control
|
||||
#warning-ignore-all:return_value_discarded
|
||||
|
||||
enum Menu {
|
||||
LOADER,
|
||||
MAIN,
|
||||
LOAD_SAVE,
|
||||
WORLD_MAP,
|
||||
FIELD_MAP,
|
||||
PARTY,
|
||||
SHOP,
|
||||
BATTLE,
|
||||
DEBUG,
|
||||
DEBUG_AUDIO_SYSTEM,
|
||||
DEBUG_BATTLE_SPRITES,
|
||||
}
|
||||
const globals = preload('res://globals.gd') # Make LSP shut up about non-const
|
||||
const Menu = globals.Menu
|
||||
var packed_menus = {}
|
||||
var menus = {}
|
||||
var active_menu_stack = []
|
||||
|
||||
func instantiate_menu_list(menu_list) -> void:
|
||||
for key in menu_list:
|
||||
packed_menus[key] = load(globals.MENUS[key][0])
|
||||
menus[key] = packed_menus[key].instance()
|
||||
|
||||
var is_rom_loaded := false
|
||||
func _rom_loaded() -> void:
|
||||
menus[Menu.PARTY] = preload('res://widgets/PartyMenu.tscn').instance()
|
||||
menus[Menu.WORLD_MAP] = preload('res://test/worldmap_system.tscn').instance()
|
||||
menus[Menu.DEBUG] = preload('res://test/debug_menu.tscn').instance()
|
||||
menus[Menu.DEBUG].connect('pressed_worldmap', self, 'push_menu', [Menu.WORLD_MAP])
|
||||
menus[Menu.DEBUG].connect('pressed_party', self, 'push_menu', [Menu.PARTY])
|
||||
menus[Menu.DEBUG].connect('pressed_battle_sprites', self, 'push_menu', [Menu.DEBUG_BATTLE_SPRITES])
|
||||
menus[Menu.DEBUG].connect('pressed_audio', self, 'push_menu', [Menu.DEBUG_AUDIO_SYSTEM])
|
||||
menus[Menu.DEBUG_AUDIO_SYSTEM] = preload('res://test/audio_system.tscn').instance()
|
||||
menus[Menu.DEBUG_BATTLE_SPRITES] = preload('res://test/battle_sprites.tscn').instance()
|
||||
func _on_rom_loaded() -> void:
|
||||
instantiate_menu_list(globals.POST_ROM_MENUS)
|
||||
menus[Menu.DEBUG].connect('button_pressed', self, 'push_menu')
|
||||
is_rom_loaded = true
|
||||
|
||||
var is_savefile_loaded := false
|
||||
func _on_savefile_loaded(dicts) -> void:
|
||||
push_menu(Menu.LOAD_SAVE)
|
||||
menus[Menu.LOAD_SAVE].set_data(dicts)
|
||||
menus[Menu.LOAD_SAVE].connect('slot_activated', self, '_on_saveslot_loaded')
|
||||
|
||||
func _on_saveslot_loaded(dict) -> void:
|
||||
push_menu(Menu.PARTY)
|
||||
menus[Menu.PARTY].update_labels(dict)
|
||||
|
||||
func _ready() -> void:
|
||||
if OS.get_name() != 'HTML5' or !OS.has_feature('JavaScript'):
|
||||
menus[Menu.LOADER] = preload('res://widgets/RomSelect.tscn').instance()
|
||||
packed_menus[Menu.LOADER] = preload('res://widgets/RomSelect.tscn')
|
||||
else:
|
||||
menus[Menu.LOADER] = preload('res://widgets/WebFileSelect.tscn').instance()
|
||||
packed_menus[Menu.LOADER] = preload('res://widgets/WebFileSelect.tscn')
|
||||
menus[Menu.LOADER] = packed_menus[Menu.LOADER].instance()
|
||||
push_menu(Menu.LOADER)
|
||||
|
||||
RomLoader.connect('rom_loaded', self, '_rom_loaded')
|
||||
instantiate_menu_list(globals.INITIAL_MENUS)
|
||||
|
||||
RomLoader.connect('rom_loaded', self, '_on_rom_loaded')
|
||||
menus[Menu.LOADER].connect('continue_pressed', self, 'push_debug_menu')
|
||||
menus[Menu.LOADER].connect('savefile_loaded', self, '_on_savefile_loaded')
|
||||
Common.update_window_scale()
|
||||
|
||||
func push_debug_menu():
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
[gd_scene load_steps=4 format=2]
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://theme/menu_theme.tres" type="Theme" id=1]
|
||||
[ext_resource path="res://widgets/ColorMenu.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://main.gd" type="Script" id=5]
|
||||
|
||||
[node name="main" type="Control"]
|
||||
|
@ -11,7 +10,3 @@ margin_right = -640.0
|
|||
margin_bottom = -360.0
|
||||
theme = ExtResource( 1 )
|
||||
script = ExtResource( 5 )
|
||||
|
||||
[node name="ColorMenu" parent="." instance=ExtResource( 4 )]
|
||||
margin_left = 384.0
|
||||
margin_right = 469.0
|
||||
|
|
|
@ -66,5 +66,7 @@ texture={
|
|||
|
||||
quality/driver/driver_name="GLES2"
|
||||
2d/snapping/use_gpu_pixel_snap=true
|
||||
vram_compression/import_s3tc=false
|
||||
vram_compression/import_etc2=false
|
||||
environment/default_clear_color=Color( 0, 0, 0, 1 )
|
||||
environment/default_environment="res://default_env.tres"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extends Node
|
||||
#warning-ignore-all:return_value_discarded
|
||||
|
||||
signal rom_loaded
|
||||
|
||||
|
|
|
@ -121,6 +121,39 @@ func get_save_slot(sram: File, slot_id: int) -> StreamPeerBuffer:
|
|||
buffer.set_data_array(sram.get_buffer(0x700))
|
||||
return buffer
|
||||
|
||||
func load_save_dicts_from_buffer(sram: StreamPeerBuffer) -> Array:
|
||||
# Pulls four lots of 0x700 bytes from the current buffer position
|
||||
var dicts := []
|
||||
var slot_buffer := StreamPeerBuffer.new()
|
||||
for slot_id in 4:
|
||||
slot_buffer.set_data_array(sram.get_data(0x700)[1])
|
||||
slot_buffer.seek(0)
|
||||
dicts.append(load_save_slot(slot_buffer))
|
||||
# Won't seek just in case
|
||||
sram.get_data(0x1FF8-0x1C00)
|
||||
for slot_id in 4:
|
||||
dicts[slot_id].slot_in_use = (sram.get_u16() == SLOT_IN_USE)
|
||||
return dicts
|
||||
|
||||
func load_save_dicts_from_bytes(sram: PoolByteArray) -> Array:
|
||||
var buffer := StreamPeerBuffer.new()
|
||||
buffer.set_data_array(sram)
|
||||
return load_save_dicts_from_buffer(buffer)
|
||||
|
||||
func load_save_dicts_from_file(sram: File) -> Array:
|
||||
# Pulls four lots of 0x700 bytes from the current buffer position
|
||||
var dicts := []
|
||||
var slot_buffer := StreamPeerBuffer.new()
|
||||
for slot_id in 4:
|
||||
slot_buffer.set_data_array(sram.get_buffer(0x700))
|
||||
slot_buffer.seek(0)
|
||||
dicts.append(load_save_slot(slot_buffer))
|
||||
# Won't seek just in case
|
||||
sram.get_buffer(0x1FF8-0x1C00)
|
||||
for slot_id in 4:
|
||||
dicts[slot_id].slot_in_use = (sram.get_16() == SLOT_IN_USE)
|
||||
return dicts
|
||||
|
||||
func save_slot(sram: File, slot_id: int, slot: StreamPeerBuffer):
|
||||
sram.seek(0x700 * slot_id)
|
||||
sram.store_buffer(slot.data_array)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extends Node
|
||||
const globals = preload('res://globals.gd') # Make LSP shut up about non-const
|
||||
# Portability for GLES2 vs GLES3 stuff
|
||||
const INDEX_FORMAT := globals.INDEX_FORMAT
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const globals = preload('res://globals.gd') # Make LSP shut up about non-const
|
||||
const INDEX_FORMAT := globals.INDEX_FORMAT
|
||||
|
||||
static func ByteArray(size: int) -> PoolByteArray:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const globals = preload('res://globals.gd') # Make LSP shut up about non-const
|
||||
var INDEX_FORMAT := globals.INDEX_FORMAT
|
||||
|
||||
static func ByteArray(size: int) -> PoolByteArray:
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
extends Control
|
||||
#warning-ignore-all:return_value_discarded
|
||||
|
||||
signal pressed_worldmap
|
||||
signal pressed_party
|
||||
signal pressed_battle_sprites
|
||||
signal pressed_audio
|
||||
signal button_pressed(menu)
|
||||
|
||||
func _on_btn_worldmap_pressed() -> void:
|
||||
emit_signal('pressed_worldmap')
|
||||
onready var buttons := $'%buttons'
|
||||
func _ready() -> void:
|
||||
for key in globals.POST_ROM_MENUS:
|
||||
if key == globals.Menu.DEBUG:
|
||||
continue
|
||||
var menu = globals.MENUS[key]
|
||||
var btn := Button.new()
|
||||
btn.text = menu[1]
|
||||
btn.connect('pressed', self, '_on_btn_pressed', [key])
|
||||
buttons.add_child(btn)
|
||||
|
||||
func _on_btn_party_pressed() -> void:
|
||||
emit_signal('pressed_party')
|
||||
|
||||
func _on_btn_battle_sprites_pressed() -> void:
|
||||
emit_signal('pressed_battle_sprites')
|
||||
|
||||
func _on_btn_audio_pressed() -> void:
|
||||
emit_signal('pressed_audio')
|
||||
func _on_btn_pressed(menu) -> void:
|
||||
emit_signal('button_pressed', menu)
|
||||
|
|
|
@ -16,9 +16,9 @@ anchor_bottom = 1.0
|
|||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
|
||||
margin_left = 110.0
|
||||
margin_top = 45.0
|
||||
margin_top = 101.0
|
||||
margin_right = 273.0
|
||||
margin_bottom = 194.0
|
||||
margin_bottom = 138.0
|
||||
|
||||
[node name="Label" type="Label" parent="CenterContainer/VBoxContainer"]
|
||||
margin_right = 163.0
|
||||
|
@ -27,31 +27,9 @@ text = "DEBUG MENU
|
|||
Press [backspace] to return"
|
||||
align = 1
|
||||
|
||||
[node name="btn_worldmap" type="Button" parent="CenterContainer/VBoxContainer"]
|
||||
[node name="buttons" type="GridContainer" parent="CenterContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 37.0
|
||||
margin_right = 163.0
|
||||
margin_bottom = 59.0
|
||||
text = "World Map"
|
||||
|
||||
[node name="btn_party" type="Button" parent="CenterContainer/VBoxContainer"]
|
||||
margin_top = 67.0
|
||||
margin_right = 163.0
|
||||
margin_bottom = 89.0
|
||||
text = "Party Menu"
|
||||
|
||||
[node name="btn_battle_sprites" type="Button" parent="CenterContainer/VBoxContainer"]
|
||||
margin_top = 97.0
|
||||
margin_right = 163.0
|
||||
margin_bottom = 119.0
|
||||
text = "Battle Sprites"
|
||||
|
||||
[node name="btn_audio" type="Button" parent="CenterContainer/VBoxContainer"]
|
||||
margin_top = 127.0
|
||||
margin_right = 163.0
|
||||
margin_bottom = 149.0
|
||||
text = "Audio"
|
||||
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/btn_worldmap" to="." method="_on_btn_worldmap_pressed"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/btn_party" to="." method="_on_btn_party_pressed"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/btn_battle_sprites" to="." method="_on_btn_battle_sprites_pressed"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/btn_audio" to="." method="_on_btn_audio_pressed"]
|
||||
margin_bottom = 37.0
|
||||
columns = 2
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
extends Control
|
||||
#warning-ignore-all:return_value_discarded
|
||||
|
||||
const palette_mat := preload('res://palette_mat.tres')
|
||||
var save_slots = []
|
||||
var save_slot_dicts = []
|
||||
|
||||
func _ready():
|
||||
Engine.set_target_fps(60)
|
||||
RomLoader.connect('rom_loaded', self, '_on_rom_loaded')
|
||||
# RomLoader.load_snes_rom('/home/luke/code/FF/ffv romhacks/Final Fantasy V (Japan).sfc')
|
||||
RomLoader.load_snes_rom('/home/luke/code/FF/ffv romhacks/Final Fantasy V (Japan) [En by RPGe v1.1].sfc')
|
||||
|
||||
func _on_rom_loaded():
|
||||
party_menu()
|
||||
# monster_sprites()
|
||||
# battle_bgs()
|
||||
# jobs_and_abilities()
|
||||
|
||||
func party_menu():
|
||||
var PartyMenu = preload('res://widgets/PartyMenu.tscn').instance()
|
||||
# PartyMenu.margin_right = 320.0
|
||||
PartyMenu.margin_right = 384.0
|
||||
add_child(PartyMenu)
|
||||
var save_file := File.new()
|
||||
#var error := save_file.open('test.srm', File.READ)
|
||||
var error := save_file.open('/home/luke/.config/Mesen2/Saves/FF5_SCC_WepTweaks_Inus_Dash.srm', File.READ)
|
||||
|
@ -22,9 +38,10 @@ func _ready():
|
|||
# save_slot_dicts.append(SaveLoader.get_struct(buffer, 'Save_slot'))
|
||||
var data = save_slot_dicts[0]
|
||||
data.characters[2].equipped_abilities[3] = 0x9B
|
||||
$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)
|
||||
|
||||
func monster_sprites():
|
||||
var monster_box := GridContainer.new()
|
||||
monster_box.columns = 8
|
||||
add_child(monster_box)
|
||||
|
@ -35,6 +52,7 @@ func _ready():
|
|||
t.material.set_shader_param('palette', mon.palette)
|
||||
monster_box.add_child(t)
|
||||
|
||||
func battle_bgs():
|
||||
var bbg := SpinBox.new()
|
||||
bbg.max_value = len(SpriteLoader.battle_backgrounds) - 1
|
||||
bbg.connect('value_changed', $BattleScene, 'set_bg')
|
||||
|
@ -43,13 +61,12 @@ func _ready():
|
|||
bbg.align = LineEdit.ALIGN_RIGHT
|
||||
add_child(bbg)
|
||||
|
||||
# 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)]
|
||||
# for i in 78:
|
||||
# lbl.text = lbl.text + '\n%s - %s' % [StringLoader.get_ability_name(i), StringLoader.get_ability_desc(i)]
|
||||
# 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)
|
||||
|
||||
|
||||
func jobs_and_abilities():
|
||||
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)]
|
||||
for i in 78:
|
||||
lbl.text = lbl.text + '\n%s - %s' % [StringLoader.get_ability_name(i), StringLoader.get_ability_desc(i)]
|
||||
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)
|
||||
|
|
|
@ -1,32 +1,10 @@
|
|||
[gd_scene load_steps=8 format=2]
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://widgets/PartyMenu.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://test/worldmap_system.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://test_scene.gd" type="Script" id=3]
|
||||
[ext_resource path="res://test/battle_sprites.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://test/audio_system.tscn" type="PackedScene" id=5]
|
||||
[ext_resource path="res://theme/menu_theme.tres" type="Theme" id=6]
|
||||
[ext_resource path="res://widgets/BattleScene.tscn" type="PackedScene" id=7]
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
[node name="test_scene" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
theme = ExtResource( 6 )
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="audio_system" parent="." instance=ExtResource( 5 )]
|
||||
position = Vector2( 0, 160 )
|
||||
|
||||
[node name="worldmap_system" parent="." instance=ExtResource( 2 )]
|
||||
visible = false
|
||||
position = Vector2( -600, -550 )
|
||||
|
||||
[node name="battle_sprites" parent="." instance=ExtResource( 4 )]
|
||||
visible = false
|
||||
|
||||
[node name="PartyMenu" parent="." instance=ExtResource( 1 )]
|
||||
visible = false
|
||||
margin_right = 320.0
|
||||
|
||||
[node name="BattleScene" parent="." instance=ExtResource( 7 )]
|
||||
visible = false
|
||||
|
|
|
@ -37,15 +37,15 @@ margin_bottom = 224.0
|
|||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -72.0
|
||||
margin_left = -64.0
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 8
|
||||
custom_constants/separation = 0
|
||||
alignment = 2
|
||||
|
||||
[node name="panel_menu" type="PanelContainer" parent="rightside"]
|
||||
margin_left = 16.0
|
||||
margin_right = 72.0
|
||||
margin_left = 8.0
|
||||
margin_right = 64.0
|
||||
margin_bottom = 36.0
|
||||
rect_min_size = Vector2( 56, 0 )
|
||||
size_flags_horizontal = 8
|
||||
|
@ -69,9 +69,9 @@ margin_bottom = 28.0
|
|||
text = "Ability"
|
||||
|
||||
[node name="panel_menu2" type="PanelContainer" parent="rightside"]
|
||||
margin_left = 16.0
|
||||
margin_left = 8.0
|
||||
margin_top = 36.0
|
||||
margin_right = 72.0
|
||||
margin_right = 64.0
|
||||
margin_bottom = 128.0
|
||||
rect_min_size = Vector2( 56, 0 )
|
||||
size_flags_horizontal = 8
|
||||
|
@ -120,14 +120,13 @@ text = "Save"
|
|||
|
||||
[node name="spacer" type="Control" parent="rightside"]
|
||||
margin_top = 128.0
|
||||
margin_right = 72.0
|
||||
margin_right = 64.0
|
||||
margin_bottom = 168.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="panel_time" type="PanelContainer" parent="rightside"]
|
||||
margin_left = 8.0
|
||||
margin_top = 168.0
|
||||
margin_right = 72.0
|
||||
margin_right = 64.0
|
||||
margin_bottom = 204.0
|
||||
rect_min_size = Vector2( 64, 0 )
|
||||
size_flags_horizontal = 8
|
||||
|
@ -149,32 +148,32 @@ unique_name_in_owner = true
|
|||
margin_top = 14.0
|
||||
margin_right = 56.0
|
||||
margin_bottom = 28.0
|
||||
text = "0:00"
|
||||
text = "000:00:00"
|
||||
align = 2
|
||||
|
||||
[node name="panel_gil" type="PanelContainer" parent="rightside"]
|
||||
margin_top = 204.0
|
||||
margin_right = 72.0
|
||||
margin_right = 64.0
|
||||
margin_bottom = 240.0
|
||||
rect_min_size = Vector2( 72, 0 )
|
||||
rect_min_size = Vector2( 64, 0 )
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="rightside/panel_gil"]
|
||||
margin_left = 4.0
|
||||
margin_top = 4.0
|
||||
margin_right = 68.0
|
||||
margin_right = 60.0
|
||||
margin_bottom = 32.0
|
||||
custom_constants/separation = 0
|
||||
|
||||
[node name="lbl_gilcount" type="Label" parent="rightside/panel_gil/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
margin_right = 64.0
|
||||
margin_right = 56.0
|
||||
margin_bottom = 14.0
|
||||
text = "0"
|
||||
text = "0000000"
|
||||
align = 2
|
||||
|
||||
[node name="GIL" type="Label" parent="rightside/panel_gil/VBoxContainer"]
|
||||
margin_top = 14.0
|
||||
margin_right = 64.0
|
||||
margin_right = 56.0
|
||||
margin_bottom = 28.0
|
||||
text = "Gil"
|
||||
align = 2
|
||||
|
|
|
@ -129,9 +129,9 @@ text = "LV"
|
|||
|
||||
[node name="lbl_lv_cur" type="Label" parent="ref0"]
|
||||
unique_name_in_owner = true
|
||||
margin_left = 32.0
|
||||
margin_left = 24.0
|
||||
margin_top = 12.0
|
||||
margin_right = 56.0
|
||||
margin_right = 48.0
|
||||
margin_bottom = 26.0
|
||||
text = "26"
|
||||
align = 2
|
||||
|
@ -149,9 +149,9 @@ border_color = Color( 1, 0.501961, 0, 1 )
|
|||
unique_name_in_owner = true
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 40.0
|
||||
margin_left = 32.0
|
||||
margin_top = -24.0
|
||||
margin_right = 56.0
|
||||
margin_right = 48.0
|
||||
border_color = Color( 0, 1, 0, 1 )
|
||||
|
||||
[node name="PC" parent="ref0" instance=ExtResource( 2 )]
|
||||
|
@ -162,6 +162,14 @@ margin_left = 168.0
|
|||
margin_right = 252.0
|
||||
margin_bottom = 50.0
|
||||
|
||||
[node name="Panel" type="Panel" parent="ref_commands"]
|
||||
modulate = Color( 1, 1, 1, 0.501961 )
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -4.0
|
||||
margin_top = -3.0
|
||||
margin_bottom = 3.0
|
||||
|
||||
[node name="l1" type="Label" parent="ref_commands"]
|
||||
margin_left = 12.0
|
||||
margin_right = 84.0
|
||||
|
|
|
@ -2,13 +2,18 @@ extends PanelContainer
|
|||
#warning-ignore-all:return_value_discarded
|
||||
|
||||
signal continue_pressed
|
||||
signal savefile_loaded(dicts)
|
||||
|
||||
const globals = preload('res://globals.gd') # Make LSP shut up about non-const
|
||||
const FOLDER_ICON := globals.FOLDER_ICON
|
||||
const ALLOWED_EXTS := globals.ALLOWED_EXTS
|
||||
const CD_EXTS := globals.CD_EXTS
|
||||
const EXT_ICONS := globals.EXT_ICONS
|
||||
const TYPE_DESCS := globals.TYPE_DESCS
|
||||
|
||||
enum {SELECT_ROM, SELECT_SAVE, COMPLETE}
|
||||
var current_mode = SELECT_ROM
|
||||
|
||||
var cached_cd_bin_paths := {}
|
||||
var dir := Directory.new()
|
||||
var home_path := ''
|
||||
|
@ -109,7 +114,18 @@ func load_file(entry: String):
|
|||
var ext = entry.rsplit('.', true, 1)[1].to_lower()
|
||||
match ext:
|
||||
'sfc', 'smc':
|
||||
RomLoader.load_snes_rom(filename)
|
||||
if current_mode == SELECT_ROM:
|
||||
RomLoader.load_snes_rom(filename)
|
||||
'srm':
|
||||
if current_mode == SELECT_ROM:
|
||||
return
|
||||
var file := File.new()
|
||||
match file.open(filename, File.READ):
|
||||
OK:
|
||||
emit_signal('savefile_loaded', SaveLoader.load_save_dicts_from_file(file))
|
||||
_set_mode(COMPLETE)
|
||||
var err:
|
||||
print_debug('Error loading savefile: %s - %d'%[filename, err])
|
||||
|
||||
func activate_entry(entry: String, _index: int = -1):
|
||||
var curr_dir := dir.get_current_dir()
|
||||
|
@ -168,7 +184,11 @@ func view_entry(entry: String, index: int = -1):
|
|||
lbl_filesize_content.text = human_size
|
||||
lbl_fileinfo_header.modulate = active_modulate_color if prodcode else inactive_modulate_color
|
||||
lbl_fileinfo_content.text = prodcode
|
||||
btn_ok.disabled = (ext != 'sfc' and ext != 'smc') # Only allow opening snes roms for now
|
||||
match current_mode:
|
||||
SELECT_ROM:
|
||||
btn_ok.disabled = (ext != 'sfc' and ext != 'smc') # Only allow opening snes roms for now
|
||||
SELECT_SAVE, COMPLETE:
|
||||
btn_ok.disabled = (ext != 'srm')
|
||||
|
||||
func init_labels():
|
||||
lbl_filename_header.modulate = inactive_modulate_color
|
||||
|
@ -197,6 +217,20 @@ func _ready() -> void:
|
|||
print(ProjectSettings.globalize_path('user://'))
|
||||
print(ProjectSettings.globalize_path(dir.get_current_dir()))
|
||||
|
||||
func _set_mode(new_mode) -> void:
|
||||
match new_mode:
|
||||
SELECT_ROM:
|
||||
$'%lbl_prompt'.text = "Select a ROM from your device's storage"
|
||||
btn_continue.disabled = true
|
||||
SELECT_SAVE:
|
||||
$'%lbl_prompt'.text = "Select a save file from your device's storage"
|
||||
btn_continue.disabled = false
|
||||
COMPLETE:
|
||||
$'%lbl_prompt'.text = "Save file loaded, press Continue"
|
||||
btn_continue.disabled = false
|
||||
current_mode = new_mode
|
||||
update_view()
|
||||
init_labels()
|
||||
|
||||
func _on_ItemList_item_activated(index: int) -> void:
|
||||
activate_entry(itemlist.get_item_text(index), index)
|
||||
|
@ -205,8 +239,7 @@ func _on_ItemList_item_selected(index: int) -> void:
|
|||
view_entry(itemlist.get_item_text(index), index)
|
||||
|
||||
func _on_rom_loaded() -> void:
|
||||
$'%lbl_prompt'.text = "Select a save file from your device's storage"
|
||||
btn_continue.disabled = false
|
||||
_set_mode(SELECT_SAVE)
|
||||
|
||||
func _on_continue_pressed() -> void:
|
||||
emit_signal('continue_pressed')
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
extends PanelContainer
|
||||
#warning-ignore-all:shadowed_variable
|
||||
signal clicked
|
||||
|
||||
const PC := preload('res://PC.tscn')
|
||||
var PCs = []
|
||||
|
||||
var data := {}
|
||||
|
||||
var dummy_data := {
|
||||
'characters': [
|
||||
{'character_id': 0},
|
||||
|
@ -10,8 +15,9 @@ var dummy_data := {
|
|||
{'character_id': 3},
|
||||
],
|
||||
'game_time_frames': randi() % 0x01000000,
|
||||
'character_names': ['Butz', 'Lenna', 'Galuf', 'Faris', 'Krile'],
|
||||
'config': {'menu_color_r': randi()%32, 'menu_color_g': randi()%32, 'menu_color_b': randi()%32}
|
||||
'character_names_decoded': ['Butz', 'Lenna', 'Galuf', 'Faris', 'Krile'],
|
||||
'config': {'menu_color_r': randi()%32, 'menu_color_g': randi()%32, 'menu_color_b': randi()%32},
|
||||
'slot_in_use': true,
|
||||
}
|
||||
|
||||
func _init_dummy():
|
||||
|
@ -24,6 +30,7 @@ func _init_dummy():
|
|||
dummy_data.characters.shuffle()
|
||||
|
||||
func set_data(data: Dictionary):
|
||||
self.data = data
|
||||
self.material.set_shader_param('MenuBGColour', Color(data.config.menu_color_r/31.0, data.config.menu_color_g/31.0, data.config.menu_color_b/31.0))
|
||||
for i in 4:
|
||||
var char_id: int = data.characters[i].character_id
|
||||
|
@ -33,8 +40,10 @@ func set_data(data: Dictionary):
|
|||
PCs[i].texture = SpriteLoader.strip_textures[sprite_id]
|
||||
$'%lbl_level_num'.text = '%d' % data.characters[0].level
|
||||
$'%lbl_gametime'.text = Common.game_time_frames_to_hhmm(data.game_time_frames)
|
||||
$'%lbl_name'.text = data.character_names[data.characters[0].character_id]
|
||||
$'%lbl_name'.text = data.character_names_decoded[data.characters[0].character_id]
|
||||
$'%lbl_hp'.text = '%d/%4d' % [data.characters[0].hp_current, data.characters[0].hp_max]
|
||||
$HBoxContainer.visible = data.slot_in_use
|
||||
$lbl_not_in_use.visible = !data.slot_in_use
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
|
@ -48,6 +57,9 @@ func _ready() -> void:
|
|||
set_data(dummy_data)
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta: float) -> void:
|
||||
# pass
|
||||
func _input(event: InputEvent) -> void:
|
||||
if (event is InputEventMouseButton or event is InputEventScreenTouch) and event.pressed:
|
||||
if get_rect().has_point(event.position):
|
||||
# print(event.position)
|
||||
get_tree().set_input_as_handled()
|
||||
emit_signal('clicked')
|
||||
|
|
|
@ -92,3 +92,14 @@ margin_bottom = 36.0
|
|||
size_flags_vertical = 9
|
||||
text = "1345/1345"
|
||||
align = 2
|
||||
|
||||
[node name="lbl_not_in_use" type="Label" parent="."]
|
||||
visible = false
|
||||
margin_left = 4.0
|
||||
margin_top = 15.0
|
||||
margin_right = 220.0
|
||||
margin_bottom = 29.0
|
||||
rect_min_size = Vector2( 0, 36 )
|
||||
text = "Not In Use"
|
||||
align = 1
|
||||
valign = 1
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
extends PanelContainer
|
||||
#warning-ignore-all:shadowed_variable
|
||||
signal slot_activated(dict)
|
||||
|
||||
onready var slots := [$'%SaveSlot1', $'%SaveSlot2', $'%SaveSlot3', $'%SaveSlot4']
|
||||
|
||||
var dicts := []
|
||||
func set_data(dicts: Array) -> void:
|
||||
self.dicts = dicts
|
||||
for i in 4:
|
||||
slots[i].set_data(dicts[i])
|
||||
slots[i].connect('clicked', self, 'load_slot', [i])
|
||||
|
||||
func load_slot(id: int) -> void:
|
||||
var dict = self.dicts[id]
|
||||
if dict.slot_in_use:
|
||||
emit_signal('slot_activated', dict)
|
|
@ -1,10 +1,12 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://theme/menu_theme.tres" type="Theme" id=1]
|
||||
[ext_resource path="res://widgets/SaveSlot.tscn" type="PackedScene" id=2]
|
||||
[ext_resource path="res://widgets/SaveSlotSelect.gd" type="Script" id=3]
|
||||
|
||||
[node name="SaveSlotSelect" type="PanelContainer"]
|
||||
theme = ExtResource( 1 )
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
margin_left = 4.0
|
||||
|
@ -19,21 +21,25 @@ margin_bottom = 22.0
|
|||
text = "New Game"
|
||||
|
||||
[node name="SaveSlot1" parent="VBoxContainer" instance=ExtResource( 2 )]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 22.0
|
||||
margin_right = 224.0
|
||||
margin_bottom = 66.0
|
||||
|
||||
[node name="SaveSlot2" parent="VBoxContainer" instance=ExtResource( 2 )]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 66.0
|
||||
margin_right = 224.0
|
||||
margin_bottom = 110.0
|
||||
|
||||
[node name="SaveSlot3" parent="VBoxContainer" instance=ExtResource( 2 )]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 110.0
|
||||
margin_right = 224.0
|
||||
margin_bottom = 154.0
|
||||
|
||||
[node name="SaveSlot4" parent="VBoxContainer" instance=ExtResource( 2 )]
|
||||
unique_name_in_owner = true
|
||||
margin_top = 154.0
|
||||
margin_right = 224.0
|
||||
margin_bottom = 198.0
|
||||
|
|
|
@ -2,13 +2,18 @@ extends PanelContainer
|
|||
#warning-ignore-all:return_value_discarded
|
||||
|
||||
signal continue_pressed
|
||||
signal savefile_loaded(dicts)
|
||||
|
||||
const globals = preload('res://globals.gd') # Make LSP shut up about non-const
|
||||
const FOLDER_ICON := globals.FOLDER_ICON
|
||||
const ALLOWED_EXTS := globals.ALLOWED_EXTS
|
||||
const CD_EXTS := globals.CD_EXTS
|
||||
const EXT_ICONS := globals.EXT_ICONS
|
||||
const TYPE_DESCS := globals.TYPE_DESCS
|
||||
|
||||
enum {SELECT_ROM, SELECT_SAVE, COMPLETE}
|
||||
var current_mode = SELECT_ROM
|
||||
|
||||
var uploaded_files := {} # filename: data
|
||||
var uploaded_files_types := {} # filename: type
|
||||
|
||||
|
@ -68,7 +73,12 @@ func load_file(entry: String):
|
|||
var ext = entry.rsplit('.', true, 1)[1].to_lower()
|
||||
match ext:
|
||||
'sfc', 'smc':
|
||||
RomLoader.load_snes_rom_from_bytes(uploaded_files[entry])
|
||||
if current_mode == SELECT_ROM:
|
||||
RomLoader.load_snes_rom_from_bytes(uploaded_files[entry])
|
||||
'srm':
|
||||
if current_mode != SELECT_ROM:
|
||||
emit_signal('savefile_loaded', SaveLoader.load_save_dicts_from_bytes(uploaded_files[entry]))
|
||||
_set_mode(COMPLETE)
|
||||
|
||||
func activate_entry(entry: String, _index: int = -1):
|
||||
load_file(entry)
|
||||
|
@ -108,7 +118,11 @@ func view_entry(entry: String, _index: int = -1):
|
|||
lbl_filesize_content.text = human_size
|
||||
lbl_fileinfo_header.modulate = active_modulate_color if prodcode else inactive_modulate_color
|
||||
lbl_fileinfo_content.text = prodcode
|
||||
btn_ok.disabled = (ext != 'sfc' and ext != 'smc') # Only allow opening snes roms for now
|
||||
match current_mode:
|
||||
SELECT_ROM:
|
||||
btn_ok.disabled = (ext != 'sfc' and ext != 'smc') # Only allow opening snes roms for now
|
||||
SELECT_SAVE, COMPLETE:
|
||||
btn_ok.disabled = (ext != 'srm')
|
||||
|
||||
func init_labels():
|
||||
lbl_filename_header.modulate = inactive_modulate_color
|
||||
|
@ -123,6 +137,7 @@ func init_labels():
|
|||
func _upload_file(filename: String, file_type: String, data): # data is Javascript ArrayBuffer, which should be castable to PoolByteArray
|
||||
uploaded_files[filename] = data
|
||||
uploaded_files_types[filename] = file_type
|
||||
print('uploaded "%s" with filesize %d bytes'%[filename, len(data)])
|
||||
update_view()
|
||||
|
||||
func _ready() -> void:
|
||||
|
@ -135,6 +150,20 @@ func _ready() -> void:
|
|||
RomLoader.connect('rom_loaded', self, '_on_rom_loaded')
|
||||
HTML5.connect('uploaded_file', self, '_upload_file')
|
||||
|
||||
func _set_mode(new_mode) -> void:
|
||||
match new_mode:
|
||||
SELECT_ROM:
|
||||
$'%lbl_prompt'.text = "Select a ROM from your device's storage"
|
||||
btn_continue.disabled = true
|
||||
SELECT_SAVE:
|
||||
$'%lbl_prompt'.text = "Select a save file from your device's storage"
|
||||
btn_continue.disabled = false
|
||||
COMPLETE:
|
||||
$'%lbl_prompt'.text = "Save file loaded, press Continue"
|
||||
btn_continue.disabled = false
|
||||
current_mode = new_mode
|
||||
update_view()
|
||||
init_labels()
|
||||
|
||||
func _on_ItemList_item_activated(index: int) -> void:
|
||||
activate_entry(itemlist.get_item_text(index), index)
|
||||
|
@ -146,8 +175,7 @@ func _on_btn_upload_pressed() -> void:
|
|||
HTML5.upload_file()
|
||||
|
||||
func _on_rom_loaded() -> void:
|
||||
$'%lbl_prompt'.text = "Select a save file from your device's storage"
|
||||
btn_continue.disabled = false
|
||||
_set_mode(SELECT_SAVE)
|
||||
|
||||
func _on_continue_pressed() -> void:
|
||||
emit_signal('continue_pressed')
|
||||
|
|
Loading…
Reference in New Issue