diff --git a/pcsx2/Host.cpp b/pcsx2/Host.cpp
new file mode 100644
index 0000000000..6a3057ca30
--- /dev/null
+++ b/pcsx2/Host.cpp
@@ -0,0 +1,29 @@
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2021 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#include "PrecompiledHeader.h"
+#include "Host.h"
+#include "common/StringHelpers.h"
+#include
+
+void Host::ReportFormattedErrorAsync(const std::string_view& title, const char* format, ...)
+{
+ std::va_list ap;
+ va_start(ap, format);
+ FastFormatAscii fmt;
+ fmt.WriteV(fmt, ap);
+ va_end(ap);
+ ReportErrorAsync(title, fmt.c_str());
+}
\ No newline at end of file
diff --git a/pcsx2/Host.h b/pcsx2/Host.h
index b980ac2980..46fa17eeac 100644
--- a/pcsx2/Host.h
+++ b/pcsx2/Host.h
@@ -16,8 +16,10 @@
#pragma once
#include "common/Pcsx2Defs.h"
-#include
+
#include
+#include
+#include
#include
struct HostKeyEvent
@@ -36,9 +38,13 @@ struct HostKeyEvent
namespace Host
{
/// Reads a file from the resources directory of the application.
- /// This may be outside of the "normally" filesystem on platforms such as Mac.
+ /// This may be outside of the "normal" filesystem on platforms such as Mac.
std::optional> ReadResourceFile(const char* filename);
/// Reads a resource file file from the resources directory as a string.
std::optional ReadResourceFileToString(const char* filename);
+
+ /// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
+ void ReportErrorAsync(const std::string_view& title, const std::string_view& message);
+ void ReportFormattedErrorAsync(const std::string_view& title, const char* format, ...);
} // namespace Host
diff --git a/pcsx2/gui/AppHost.cpp b/pcsx2/gui/AppHost.cpp
index 4b8fb3ff57..d133250748 100644
--- a/pcsx2/gui/AppHost.cpp
+++ b/pcsx2/gui/AppHost.cpp
@@ -19,9 +19,12 @@
#include "common/FileSystem.h"
#include "common/Path.h"
-#include "AppConfig.h"
#include "Host.h"
+#include "gui/App.h"
+#include "gui/AppConfig.h"
+#include "gui/pxEvents.h"
+
static auto OpenResourceCFile(const char* filename, const char* mode)
{
const std::string full_filename(Path::CombineStdString(EmuFolders::Resources, filename));
@@ -67,3 +70,11 @@ std::optional Host::ReadResourceFileToString(const char* filename)
return ret;
}
+void Host::ReportErrorAsync(const std::string_view& title, const std::string_view& message)
+{
+ wxGetApp().PostEvent(pxMessageBoxEvent(
+ title.empty() ? wxString() : wxString::FromUTF8(title.data(), title.length()),
+ message.empty() ? wxString() : wxString::FromUTF8(message.data(), message.length()),
+ MsgButtons().OK()));
+}
+
diff --git a/pcsx2/pcsx2.vcxproj b/pcsx2/pcsx2.vcxproj
index 40e6c50afb..e208251fcf 100644
--- a/pcsx2/pcsx2.vcxproj
+++ b/pcsx2/pcsx2.vcxproj
@@ -331,6 +331,7 @@
+
@@ -744,6 +745,7 @@
+
diff --git a/pcsx2/pcsx2.vcxproj.filters b/pcsx2/pcsx2.vcxproj.filters
index dbab03798e..a840c61946 100644
--- a/pcsx2/pcsx2.vcxproj.filters
+++ b/pcsx2/pcsx2.vcxproj.filters
@@ -274,6 +274,9 @@
{78f5077b-255e-435e-9a51-352171dfaee8}
+
+ {65f21394-287a-471b-a0c1-d8f0d5d95a81}
+
@@ -1640,6 +1643,9 @@
System\Ps2\SPU2
+
+ Host
+
@@ -2722,9 +2728,6 @@
System\Ps2\Iop
-
- System\Include
-
AppHost
@@ -2738,7 +2741,10 @@
System\Ps2\PAD
- System
+ System\Include
+
+
+ Host