SDL: Fix crashes on starting emulation

This commit is contained in:
Connor McLaughlin 2020-02-16 00:33:43 +09:00
parent 8aed270a1f
commit 961bc09979
4 changed files with 29 additions and 29 deletions

View file

@ -381,6 +381,7 @@ void D3D11HostDisplay::Render()
RenderDisplay(); RenderDisplay();
ImGui::Render();
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
if (!m_vsync && m_allow_tearing_supported) if (!m_vsync && m_allow_tearing_supported)

View file

@ -355,6 +355,7 @@ void OpenGLHostDisplay::Render()
RenderDisplay(); RenderDisplay();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(m_window); SDL_GL_SwapWindow(m_window);

View file

@ -27,7 +27,7 @@ Log_SetChannel(SDLHostInterface);
SDLHostInterface::SDLHostInterface() SDLHostInterface::SDLHostInterface()
{ {
m_update_settings_event_id = SDL_RegisterEvents(1); m_run_later_event_id = SDL_RegisterEvents(1);
} }
SDLHostInterface::~SDLHostInterface() SDLHostInterface::~SDLHostInterface()
@ -198,20 +198,22 @@ void SDLHostInterface::OnControllerTypeChanged(u32 slot)
g_sdl_controller_interface.SetDefaultBindings(); g_sdl_controller_interface.SetDefaultBindings();
} }
void SDLHostInterface::SaveSettings() void SDLHostInterface::RunLater(std::function<void()> callback)
{
SDLSettingsInterface si(GetSettingsFileName().c_str());
m_settings.Save(si);
}
void SDLHostInterface::QueueUpdateSettings()
{ {
SDL_Event ev = {}; SDL_Event ev = {};
ev.type = SDL_USEREVENT; ev.type = SDL_USEREVENT;
ev.user.code = m_update_settings_event_id; ev.user.code = m_run_later_event_id;
ev.user.data1 = new std::function<void()>(std::move(callback));
SDL_PushEvent(&ev); SDL_PushEvent(&ev);
} }
void SDLHostInterface::SaveAndUpdateSettings()
{
SDLSettingsInterface si(GetSettingsFileName().c_str());
m_settings.Save(si);
m_settings.Load(si);
}
void SDLHostInterface::UpdateFullscreen() void SDLHostInterface::UpdateFullscreen()
{ {
SDL_SetWindowFullscreen(m_window, m_settings.display_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); SDL_SetWindowFullscreen(m_window, m_settings.display_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
@ -309,12 +311,12 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event)
case SDL_USEREVENT: case SDL_USEREVENT:
{ {
if (static_cast<u32>(event->user.code) == m_update_settings_event_id) if (static_cast<u32>(event->user.code) == m_run_later_event_id)
{ {
UpdateSettings([this]() { std::function<void()>* callback = static_cast<std::function<void()>*>(event->user.data1);
SDLSettingsInterface si(GetSettingsFileName().c_str()); Assert(callback);
m_settings.Load(si); (*callback)();
}); delete callback;
} }
} }
break; break;
@ -784,10 +786,7 @@ void SDLHostInterface::DrawQuickSettingsMenu()
settings_changed |= ImGui::MenuItem("Display Linear Filtering", nullptr, &m_settings.display_linear_filtering); settings_changed |= ImGui::MenuItem("Display Linear Filtering", nullptr, &m_settings.display_linear_filtering);
if (settings_changed) if (settings_changed)
{ RunLater(std::bind(&SDLHostInterface::SaveAndUpdateSettings, this));
SaveSettings();
QueueUpdateSettings();
}
} }
void SDLHostInterface::DrawDebugMenu() void SDLHostInterface::DrawDebugMenu()
@ -851,7 +850,7 @@ void SDLHostInterface::DrawPoweredOffWindow()
ImGui::SetCursorPosX(button_left); ImGui::SetCursorPosX(button_left);
if (ImGui::Button("Resume", button_size)) if (ImGui::Button("Resume", button_size))
{ {
ResumeSystemFromMostRecentState(); RunLater([this]() { ResumeSystemFromMostRecentState(); });
ClearImGuiFocus(); ClearImGuiFocus();
} }
ImGui::NewLine(); ImGui::NewLine();
@ -859,7 +858,7 @@ void SDLHostInterface::DrawPoweredOffWindow()
ImGui::SetCursorPosX(button_left); ImGui::SetCursorPosX(button_left);
if (ImGui::Button("Start Disc", button_size)) if (ImGui::Button("Start Disc", button_size))
{ {
DoStartDisc(); RunLater([this]() { DoStartDisc(); });
ClearImGuiFocus(); ClearImGuiFocus();
} }
ImGui::NewLine(); ImGui::NewLine();
@ -867,7 +866,7 @@ void SDLHostInterface::DrawPoweredOffWindow()
ImGui::SetCursorPosX(button_left); ImGui::SetCursorPosX(button_left);
if (ImGui::Button("Start BIOS", button_size)) if (ImGui::Button("Start BIOS", button_size))
{ {
BootSystemFromFile(nullptr); RunLater([this]() { BootSystemFromFile(nullptr); });
ClearImGuiFocus(); ClearImGuiFocus();
} }
ImGui::NewLine(); ImGui::NewLine();
@ -883,7 +882,7 @@ void SDLHostInterface::DrawPoweredOffWindow()
std::snprintf(buf, sizeof(buf), "State %u", i); std::snprintf(buf, sizeof(buf), "State %u", i);
if (ImGui::MenuItem(buf)) if (ImGui::MenuItem(buf))
{ {
LoadState(true, i); RunLater([this, i]() { LoadState(true, i); });
ClearImGuiFocus(); ClearImGuiFocus();
} }
} }
@ -1152,10 +1151,7 @@ void SDLHostInterface::DrawSettingsWindow()
ImGui::End(); ImGui::End();
if (settings_changed) if (settings_changed)
{ RunLater(std::bind(&SDLHostInterface::SaveAndUpdateSettings, this));
SaveSettings();
QueueUpdateSettings();
}
} }
void SDLHostInterface::DrawAboutWindow() void SDLHostInterface::DrawAboutWindow()

View file

@ -83,8 +83,10 @@ private:
void DestroyDisplay(); void DestroyDisplay();
void CreateImGuiContext(); void CreateImGuiContext();
void SaveSettings(); /// Executes a callback later, after the UI has finished rendering. Needed to boot while rendering ImGui.
void QueueUpdateSettings(); void RunLater(std::function<void()> callback);
void SaveAndUpdateSettings();
void UpdateFullscreen(); void UpdateFullscreen();
@ -115,7 +117,7 @@ private:
KeyboardControllerActionMap m_keyboard_button_mapping; KeyboardControllerActionMap m_keyboard_button_mapping;
u32 m_update_settings_event_id = 0; u32 m_run_later_event_id = 0;
bool m_quit_request = false; bool m_quit_request = false;
bool m_frame_step_request = false; bool m_frame_step_request = false;