Skip to content

Commit 6f59d55

Browse files
committed
Async loading of roms with loading screen
1 parent d74895b commit 6f59d55

File tree

4 files changed

+203
-53
lines changed

4 files changed

+203
-53
lines changed

platforms/shared/desktop/emu.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#define EMU_IMPORT
2020
#include "emu.h"
2121

22+
#include <thread>
23+
#include <atomic>
24+
#include <string.h>
2225
#include "geargrafx.h"
2326
#include "sound_queue.h"
2427
#include "config.h"
@@ -36,6 +39,19 @@ static s16* audio_buffer;
3639
static bool audio_enabled;
3740
static McpManager* mcp_manager;
3841

42+
enum Loading_State
43+
{
44+
Loading_State_None = 0,
45+
Loading_State_Loading,
46+
Loading_State_Finished
47+
};
48+
49+
static std::atomic<int> loading_state(Loading_State_None);
50+
static std::thread loading_thread;
51+
static bool loading_thread_active;
52+
static bool loading_result;
53+
static char loading_file_path[4096];
54+
3955
static void save_ram(void);
4056
static void load_ram(void);
4157
static void save_mb128(void);
@@ -83,6 +99,13 @@ bool emu_init(GG_Input_Pump_Fn input_pump_fn)
8399

84100
void emu_destroy(void)
85101
{
102+
if (loading_thread_active)
103+
{
104+
loading_thread.join();
105+
loading_thread_active = false;
106+
}
107+
loading_state.store(Loading_State_None);
108+
86109
save_ram();
87110
save_mb128();
88111
SafeDelete(mcp_manager);
@@ -98,6 +121,9 @@ void emu_destroy(void)
98121

99122
bool emu_load_media(const char* file_path)
100123
{
124+
if (loading_state.load() != Loading_State_None)
125+
return false;
126+
101127
emu_debug_command = Debug_Command_None;
102128
reset_buffers();
103129

@@ -116,10 +142,71 @@ bool emu_load_media(const char* file_path)
116142
return true;
117143
}
118144

145+
static void load_media_thread_func(void)
146+
{
147+
loading_result = geargrafx->LoadMedia(loading_file_path);
148+
loading_state.store(Loading_State_Finished);
149+
}
150+
151+
void emu_load_media_async(const char* file_path)
152+
{
153+
if (loading_state.load() != Loading_State_None)
154+
return;
155+
156+
emu_debug_command = Debug_Command_None;
157+
reset_buffers();
158+
save_ram();
159+
save_mb128();
160+
161+
strncpy(loading_file_path, file_path, sizeof(loading_file_path) - 1);
162+
loading_file_path[sizeof(loading_file_path) - 1] = '\0';
163+
loading_result = false;
164+
loading_state.store(Loading_State_Loading);
165+
if (loading_thread_active)
166+
loading_thread.join();
167+
loading_thread = std::thread(load_media_thread_func);
168+
loading_thread_active = true;
169+
}
170+
171+
bool emu_is_media_loading(void)
172+
{
173+
return loading_state.load() == Loading_State_Loading;
174+
}
175+
176+
bool emu_finish_media_loading(void)
177+
{
178+
if (loading_state.load() != Loading_State_Finished)
179+
return false;
180+
181+
if (loading_thread_active)
182+
{
183+
loading_thread.join();
184+
loading_thread_active = false;
185+
}
186+
187+
loading_state.store(Loading_State_None);
188+
189+
if (!loading_result)
190+
return false;
191+
192+
load_ram();
193+
load_mb128();
194+
195+
if (config_debug.debug && (config_debug.dis_look_ahead_count > 0))
196+
geargrafx->GetHuC6280()->DisassembleAhead(config_debug.dis_look_ahead_count);
197+
198+
update_savestates_data();
199+
200+
return true;
201+
}
202+
119203
void emu_update(void)
120204
{
121205
emu_mcp_pump_commands();
122206

207+
if (loading_state.load() != Loading_State_None)
208+
return;
209+
123210
if (emu_is_empty())
124211
return;
125212

@@ -202,6 +289,8 @@ bool emu_is_debug_idle(void)
202289

203290
bool emu_is_empty(void)
204291
{
292+
if (loading_state.load() != Loading_State_None)
293+
return true;
205294
return !geargrafx->GetMedia()->IsReady();
206295
}
207296

platforms/shared/desktop/emu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ EXTERN bool emu_init(GG_Input_Pump_Fn input_pump_fn);
6464
EXTERN void emu_destroy(void);
6565
EXTERN void emu_update(void);
6666
EXTERN bool emu_load_media(const char* file_path);
67+
EXTERN void emu_load_media_async(const char* file_path);
68+
EXTERN bool emu_is_media_loading(void);
69+
EXTERN bool emu_finish_media_loading(void);
6770
EXTERN void emu_key_pressed(GG_Controllers controller, GG_Keys key);
6871
EXTERN void emu_key_released(GG_Controllers controller, GG_Keys key);
6972
EXTERN void emu_pause(void);

platforms/shared/desktop/gui.cpp

Lines changed: 110 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,14 @@ static u32 status_message_start_time = 0;
4949
static u32 status_message_duration = 0;
5050
static bool error_window_active = false;
5151
static char error_message[4096] = "";
52+
static bool loading_rom_active = false;
53+
static char loading_rom_path[4096] = "";
5254
static void main_window(void);
5355
static void push_recent_rom(std::string path);
5456
static void show_status_message(void);
5557
static void show_error_window(void);
58+
static void show_loading_popup(void);
59+
static void finish_loading_rom(void);
5660
static void set_style(void);
5761
static void load_custom_palette_from_settings(void);
5862
static ImVec4 lerp(const ImVec4& a, const ImVec4& b, float t);
@@ -207,6 +211,7 @@ void gui_render(void)
207211
if (config_emulator.show_info)
208212
gui_show_info();
209213

214+
show_loading_popup();
210215
show_status_message();
211216
show_error_window();
212217

@@ -414,64 +419,18 @@ void gui_load_palette(const char* path)
414419

415420
void gui_load_rom(const char* path)
416421
{
417-
using namespace std;
422+
if (loading_rom_active)
423+
return;
418424

419-
string message("Loading ROM ");
420-
message += path;
421-
gui_set_status_message(message.c_str(), 3000);
422425
gui_debug_auto_save_settings();
423-
424426
push_recent_rom(path);
425427
emu_resume();
426428

427-
if (!emu_load_media(path))
428-
{
429-
string message("Error loading ROM:\n");
430-
message += path;
431-
gui_set_error_message(message.c_str());
432-
433-
emu_get_core()->GetMedia()->Reset();
434-
gui_action_reset();
435-
return;
436-
}
437-
438-
if (emu_get_core()->GetMedia()->IsCDROM() && !emu_get_core()->GetMedia()->IsLoadedBios())
439-
{
440-
bool is_gameexpress = emu_get_core()->GetMedia()->IsGameExpress();
441-
string bios_name = is_gameexpress ? "Game Express BIOS" : "System Card BIOS";
442-
443-
std::string message;
444-
message += bios_name;
445-
message += " is required to run this ROM!!\n";
446-
message += "Make sure you have a valid BIOS file in 'Menu->Emulator->BIOS'.";
447-
gui_set_error_message(message.c_str());
448-
449-
emu_get_core()->GetMedia()->Reset();
450-
gui_action_reset();
451-
return;
452-
}
453-
454-
gui_debug_reset();
455-
456-
std::string str(path);
457-
str = str.substr(0, str.find_last_of("."));
458-
str += ".sym";
459-
gui_debug_load_symbols_file(str.c_str());
460-
461-
gui_debug_auto_load_settings();
429+
strncpy(loading_rom_path, path, sizeof(loading_rom_path) - 1);
430+
loading_rom_path[sizeof(loading_rom_path) - 1] = '\0';
431+
loading_rom_active = true;
462432

463-
if (config_emulator.start_paused)
464-
{
465-
emu_pause();
466-
467-
for (int i=0; i < (HUC6270_MAX_RESOLUTION_WIDTH * HUC6270_MAX_RESOLUTION_HEIGHT); i++)
468-
{
469-
emu_frame_buffer[i] = 0;
470-
}
471-
}
472-
473-
if (!emu_is_empty())
474-
application_update_title_with_rom(emu_get_core()->GetMedia()->GetFileName());
433+
emu_load_media_async(path);
475434
}
476435

477436
void gui_set_status_message(const char* message, u32 milliseconds)
@@ -686,6 +645,105 @@ static void show_status_message(void)
686645
}
687646
}
688647

648+
static void show_loading_popup(void)
649+
{
650+
if (!loading_rom_active)
651+
return;
652+
653+
if (!emu_is_media_loading())
654+
{
655+
loading_rom_active = false;
656+
gui_dialog_in_use = false;
657+
bool success = emu_finish_media_loading();
658+
659+
if (success)
660+
{
661+
finish_loading_rom();
662+
}
663+
else
664+
{
665+
std::string message("Error loading ROM:\n");
666+
message += loading_rom_path;
667+
gui_set_error_message(message.c_str());
668+
669+
emu_get_core()->GetMedia()->Reset();
670+
gui_action_reset();
671+
}
672+
return;
673+
}
674+
675+
gui_dialog_in_use = true;
676+
677+
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
678+
ImGui::SetNextWindowPos(center, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
679+
ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f));
680+
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(30.0f, 20.0f));
681+
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f);
682+
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 12.0f));
683+
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImVec4(0.10f, 0.10f, 0.10f, 0.95f));
684+
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.87f, 0.01f, 0.39f, 0.80f));
685+
ImGui::OpenPopup("##loading");
686+
687+
if (ImGui::BeginPopupModal("##loading", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove))
688+
{
689+
ImGui::PushFont(gui_roboto_font);
690+
691+
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.87f, 0.01f, 0.39f, 1.0f));
692+
ImGui::TextUnformatted(ICON_MD_HOURGLASS_EMPTY);
693+
ImGui::PopStyleColor();
694+
695+
ImGui::SameLine();
696+
ImGui::Text("LOADING...");
697+
698+
ImGui::PopFont();
699+
ImGui::EndPopup();
700+
}
701+
702+
ImGui::PopStyleColor(2);
703+
ImGui::PopStyleVar(3);
704+
}
705+
706+
static void finish_loading_rom(void)
707+
{
708+
if (emu_get_core()->GetMedia()->IsCDROM() && !emu_get_core()->GetMedia()->IsLoadedBios())
709+
{
710+
bool is_gameexpress = emu_get_core()->GetMedia()->IsGameExpress();
711+
std::string bios_name = is_gameexpress ? "Game Express BIOS" : "System Card BIOS";
712+
713+
std::string message;
714+
message += bios_name;
715+
message += " is required to run this ROM!!\n";
716+
message += "Make sure you have a valid BIOS file in 'Menu->Emulator->BIOS'.";
717+
gui_set_error_message(message.c_str());
718+
719+
emu_get_core()->GetMedia()->Reset();
720+
gui_action_reset();
721+
return;
722+
}
723+
724+
gui_debug_reset();
725+
726+
std::string str(loading_rom_path);
727+
str = str.substr(0, str.find_last_of("."));
728+
str += ".sym";
729+
gui_debug_load_symbols_file(str.c_str());
730+
731+
gui_debug_auto_load_settings();
732+
733+
if (config_emulator.start_paused)
734+
{
735+
emu_pause();
736+
737+
for (int i = 0; i < (HUC6270_MAX_RESOLUTION_WIDTH * HUC6270_MAX_RESOLUTION_HEIGHT); i++)
738+
{
739+
emu_frame_buffer[i] = 0;
740+
}
741+
}
742+
743+
if (!emu_is_empty())
744+
application_update_title_with_rom(emu_get_core()->GetMedia()->GetFileName());
745+
}
746+
689747
static void show_error_window(void)
690748
{
691749
if (error_window_active)

platforms/shared/desktop/mcp/mcp_debug_adapter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,7 @@ json DebugAdapter::LoadMedia(const std::string& file_path)
13151315
return result;
13161316
}
13171317

1318-
gui_load_rom(file_path.c_str());
1318+
emu_load_media(file_path.c_str());
13191319

13201320
if (!m_core || !m_core->GetMedia()->IsReady())
13211321
{

0 commit comments

Comments
 (0)