From 7a57c6729db3898af0f3cb257f7feed30bf21cff Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Mon, 11 Dec 2023 00:21:12 +1030 Subject: [PATCH] Add loading screen feedback now that dialog loading is uncomfortably long --- scripts/loaders/RomLoader.gd | 39 +++++++++++++++++++++++++-------- scripts/loaders/StringLoader.gd | 4 ++++ widgets/FileSelect.gd | 10 +++++++++ widgets/FileSelect.tscn | 16 ++++++++++++++ widgets/FileSelectWeb.gd | 10 +++++++++ widgets/FileSelectWeb.tscn | 16 ++++++++++++++ 6 files changed, 86 insertions(+), 9 deletions(-) diff --git a/scripts/loaders/RomLoader.gd b/scripts/loaders/RomLoader.gd index deb5045..724f7c9 100644 --- a/scripts/loaders/RomLoader.gd +++ b/scripts/loaders/RomLoader.gd @@ -1,8 +1,10 @@ extends Node #warning-ignore-all:return_value_discarded - +signal loading_stage_updated(stage) # String signal rom_loaded +const THREADED_LOADING := false + const STRUCT := preload('res://scripts/struct.gd') const STRUCT_SNES := preload('res://scripts/loaders/snes/structs.gd') var structdefs := {} @@ -19,7 +21,7 @@ var rom_snes := File.new() var snes_data := {} var snes_bytes: PoolByteArray var snes_buffer: StreamPeerBuffer -#var thread := Thread.new() +var thread: Thread func load_snes_structs(buffer: StreamPeerBuffer) -> Dictionary: var data := {} @@ -61,7 +63,14 @@ func load_snes_structs(buffer: StreamPeerBuffer) -> Dictionary: data.job_levels.append(ability_list) return data -func load_snes_audio_thread(data_and_buffer: Array): +func _on_loader_loading_stage_updated(stage: String, loader: String) -> void: + var output := '%s: %s' % [loader, stage] + print(output) + emit_signal('loading_stage_updated', output) + yield(get_tree(), 'idle_frame') + +func _load_snes_audio(data_and_buffer: Array): + yield(_on_loader_loading_stage_updated('Loading sound samples and music data', 'SoundLoader'), 'completed') SoundLoader.parse_rom(data_and_buffer[0], data_and_buffer[1]) func load_snes_rom_from_bytes(bytes: PoolByteArray) -> void: @@ -71,16 +80,25 @@ func load_snes_rom_from_bytes(bytes: PoolByteArray) -> void: self.snes_buffer = StreamPeerBuffer.new() self.snes_buffer.data_array = bytes + yield(_on_loader_loading_stage_updated('Loading struct definitions', 'StructLoader'), 'completed') self.snes_data = load_snes_structs(self.snes_buffer) - #print(snes_data.job_levels) - # Give this its own buffer if threaded, avoid file pointer conflicts - self.load_snes_audio_thread([self.snes_data, self.snes_buffer]) - # var _thread_error = thread.start(self, 'load_snes_audio_thread', [self.snes_data, self.snes_buffer.duplicate()]) - StringLoader.load_snes_rom(self.snes_buffer, true) + if THREADED_LOADING: + # Give this its own buffer if threaded, avoid file pointer conflicts + var _thread_error = thread.start(self, '_load_snes_audio', [self.snes_data, self.snes_buffer.duplicate()]) + else: + self._load_snes_audio([self.snes_data, self.snes_buffer]) + yield(_on_loader_loading_stage_updated('Loading strings', 'StringLoader'), 'completed') + StringLoader.connect('loading_stage_updated', self, '_on_loader_loading_stage_updated', ['StringLoader']) + yield(StringLoader.load_snes_rom(self.snes_buffer, true), 'completed') + yield(_on_loader_loading_stage_updated('Loading sprites', 'SpriteLoader'), 'completed') SpriteLoader.load_from_structs(self.snes_data) + yield(_on_loader_loading_stage_updated('Loading enemy battle sprites', 'SpriteLoader'), 'completed') SpriteLoader.load_enemy_battle_sprites(self.snes_data, self.snes_buffer) + yield(_on_loader_loading_stage_updated('Loading battle backgrounds', 'SpriteLoader'), 'completed') SpriteLoader.load_battle_bgs(self.snes_data, self.snes_buffer) + yield(_on_loader_loading_stage_updated('Loading map data', 'MapLoader'), 'completed') MapLoader.load_snes_rom(self.snes_buffer) + yield(_on_loader_loading_stage_updated('Finished loading!', 'RomLoader'), 'completed') emit_signal('rom_loaded') func load_snes_rom(filename: String) -> void: @@ -111,6 +129,8 @@ func load_psx_image(filename: String): func _ready(): + if THREADED_LOADING: + thread = Thread.new() structdefs.merge(STRUCT.get_base_structarraytypes()) structdefs.merge(STRUCT_SNES.get_structtypes()) STRUCT.parse_struct_definitions_from_tsv_filename('res://data/SNES_save.tsv', structdefs) @@ -121,4 +141,5 @@ func _ready(): func _exit_tree() -> void: pass -# thread.wait_to_finish() + if THREADED_LOADING: + thread.wait_to_finish() diff --git a/scripts/loaders/StringLoader.gd b/scripts/loaders/StringLoader.gd index bc8f966..47ec11d 100644 --- a/scripts/loaders/StringLoader.gd +++ b/scripts/loaders/StringLoader.gd @@ -1,4 +1,6 @@ extends Node +signal loading_stage_updated(stage) # String + const ff5_dialog := preload('res://scripts/loaders/snes/ff5_dialog.gd') var SNES_block_addresses := Common.load_tsv('res://data/string_blocks.tsv') @@ -98,6 +100,8 @@ func _load_block(block_name: String, buffer: StreamPeerBuffer, is_RPGe: bool = f func load_snes_rom(buffer: StreamPeerBuffer, is_RPGe: bool = false) -> void: for block_name in SNES_block_addresses: + emit_signal('loading_stage_updated', 'Loading string block "%s"'%block_name) + yield(get_tree(), 'idle_frame') self._load_block(block_name, buffer, is_RPGe) func get_ability_name(id: int) -> String: diff --git a/widgets/FileSelect.gd b/widgets/FileSelect.gd index 93d0a31..09323f9 100644 --- a/widgets/FileSelect.gd +++ b/widgets/FileSelect.gd @@ -31,6 +31,8 @@ onready var lbl_filesize_header: Label = $'%lbl_filesize_header' onready var lbl_filesize_content: Label = $'%lbl_filesize_content' onready var lbl_fileinfo_header: Label = $'%lbl_fileinfo_header' onready var lbl_fileinfo_content: Label = $'%lbl_fileinfo_content' +onready var splash_filter := $'%splash_filter' +onready var splash_label := $'%splash_label' const inactive_modulate_color := Color(0.5, 0.5, 0.5) const active_modulate_color := Color.white var last_dir := '' @@ -115,6 +117,9 @@ func load_file(entry: String): match ext: 'sfc', 'smc': if current_mode == SELECT_ROM: + splash_filter.visible = true + splash_label.text = 'Loading ROM: %s'%filename + yield(get_tree(), 'idle_frame') RomLoader.load_snes_rom(filename) 'srm': if current_mode == SELECT_ROM: @@ -214,6 +219,7 @@ func _ready() -> void: btn_load.connect('pressed', self, 'activate_current_entry') btn_debug.connect('pressed', self, '_on_debug_pressed') RomLoader.connect('rom_loaded', self, '_on_rom_loaded') + RomLoader.connect('loading_stage_updated', self, '_on_loading_stage_updated') print(ProjectSettings.globalize_path('user://')) print(ProjectSettings.globalize_path(dir.get_current_dir())) @@ -238,7 +244,11 @@ func _on_ItemList_item_activated(index: int) -> void: func _on_ItemList_item_selected(index: int) -> void: view_entry(itemlist.get_item_text(index), index) +func _on_loading_stage_updated(stage: String) -> void: + splash_label.text += '\n' + stage + func _on_rom_loaded() -> void: + splash_filter.visible = false _set_mode(SELECT_SAVE) func _on_debug_pressed() -> void: diff --git a/widgets/FileSelect.tscn b/widgets/FileSelect.tscn index 8b4fe80..44a3137 100644 --- a/widgets/FileSelect.tscn +++ b/widgets/FileSelect.tscn @@ -184,5 +184,21 @@ size_flags_vertical = 8 disabled = true text = "Debug Menu" +[node name="splash_filter" type="ColorRect" parent="."] +unique_name_in_owner = true +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +color = Color( 0, 0, 0, 0.627451 ) + +[node name="splash_label" type="Label" parent="splash_filter"] +unique_name_in_owner = true +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 12.0 +margin_top = -1000.0 +margin_bottom = -12.0 +valign = 2 + [connection signal="item_activated" from="VBoxContainer/HBoxContainer/PanelContainer/ItemList" to="." method="_on_ItemList_item_activated"] [connection signal="item_selected" from="VBoxContainer/HBoxContainer/PanelContainer/ItemList" to="." method="_on_ItemList_item_selected"] diff --git a/widgets/FileSelectWeb.gd b/widgets/FileSelectWeb.gd index 9f51581..fa2fbeb 100644 --- a/widgets/FileSelectWeb.gd +++ b/widgets/FileSelectWeb.gd @@ -32,6 +32,8 @@ onready var lbl_filesize_header: Label = $'%lbl_filesize_header' onready var lbl_filesize_content: Label = $'%lbl_filesize_content' onready var lbl_fileinfo_header: Label = $'%lbl_fileinfo_header' onready var lbl_fileinfo_content: Label = $'%lbl_fileinfo_content' +onready var splash_filter := $'%splash_filter' +onready var splash_label := $'%splash_label' const inactive_modulate_color := Color(0.5, 0.5, 0.5) const active_modulate_color := Color.white var last_dir := '' @@ -74,6 +76,9 @@ func load_file(entry: String): match ext: 'sfc', 'smc': if current_mode == SELECT_ROM: + splash_filter.visible = true + splash_label.text = 'Loading ROM: %s'%filename + yield(get_tree(), 'idle_frame') RomLoader.load_snes_rom_from_bytes(uploaded_files[entry]) 'srm': if current_mode != SELECT_ROM: @@ -148,6 +153,7 @@ func _ready() -> void: btn_load.connect('pressed', self, 'activate_current_entry') btn_debug.connect('pressed', self, '_on_debug_pressed') RomLoader.connect('rom_loaded', self, '_on_rom_loaded') + RomLoader.connect('loading_stage_updated', self, '_on_loading_stage_updated') HTML5.connect('uploaded_file', self, '_upload_file') func _set_mode(new_mode) -> void: @@ -174,7 +180,11 @@ func _on_ItemList_item_selected(index: int) -> void: func _on_btn_upload_pressed() -> void: HTML5.upload_file() +func _on_loading_stage_updated(stage: String) -> void: + splash_label.text += '\n' + stage + func _on_rom_loaded() -> void: + splash_filter.visible = false _set_mode(SELECT_SAVE) func _on_debug_pressed() -> void: diff --git a/widgets/FileSelectWeb.tscn b/widgets/FileSelectWeb.tscn index 7d333f6..4a10b28 100644 --- a/widgets/FileSelectWeb.tscn +++ b/widgets/FileSelectWeb.tscn @@ -195,6 +195,22 @@ size_flags_vertical = 8 disabled = true text = "Debug Menu" +[node name="splash_filter" type="ColorRect" parent="."] +unique_name_in_owner = true +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +color = Color( 0, 0, 0, 0.627451 ) + +[node name="splash_label" type="Label" parent="splash_filter"] +unique_name_in_owner = true +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 12.0 +margin_top = -1000.0 +margin_bottom = -12.0 +valign = 2 + [connection signal="pressed" from="VBoxContainer/ScrollContainer/folder_buttons/btn_upload" to="." method="_on_btn_upload_pressed"] [connection signal="item_activated" from="VBoxContainer/HBoxContainer/PanelContainer/ItemList" to="." method="_on_ItemList_item_activated"] [connection signal="item_selected" from="VBoxContainer/HBoxContainer/PanelContainer/ItemList" to="." method="_on_ItemList_item_selected"]