Move more classes from common to gui

This commit is contained in:
Connor McLaughlin 2021-09-24 18:21:51 +10:00 committed by Kojin
parent c1fc018449
commit 43dfbe3f29
28 changed files with 166 additions and 176 deletions

View File

@ -23,18 +23,14 @@ target_sources(common PRIVATE
PathUtils.cpp
PrecompiledHeader.cpp
Perf.cpp
pxStaticText.cpp
pxStreams.cpp
pxTranslate.cpp
pxWindowTextWriter.cpp
RwMutex.cpp
Semaphore.cpp
SettingsWrapper.cpp
StringHelpers.cpp
StringUtil.cpp
ThreadTools.cpp
wxGuiTools.cpp
wxHelpers.cpp
emitter/bmi.cpp
emitter/cpudetect.cpp
emitter/fpu.cpp
@ -74,7 +70,6 @@ target_sources(common PRIVATE
PageFaultSource.h
PrecompiledHeader.h
pxForwardDefs.h
pxStaticText.h
pxStreams.h
RedtapeWindows.h
RwMutex.h
@ -88,7 +83,6 @@ target_sources(common PRIVATE
Threading.h
TraceLog.h
wxBaseTools.h
wxGuiTools.h
emitter/cpudetect_internal.h
emitter/implement/dwshift.h
emitter/implement/group1.h

View File

@ -28,7 +28,6 @@
#include "common/Threading.h"
#include "common/ThreadingInternal.h"
#include "common/wxBaseTools.h"
#include "common/wxGuiTools.h"
// --------------------------------------------------------------------------------------
// Semaphore Implementation for Darwin/OSX
@ -167,7 +166,6 @@ void Threading::Semaphore::Wait()
}
else if (_WaitGui_RecursionGuard(L"Semaphore::Wait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
WaitWithoutYield();
}
else
@ -200,12 +198,10 @@ bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
}
else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return WaitWithoutYield(timeout);
}
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout));
do

View File

@ -98,54 +98,6 @@ protected:
virtual void DoDeletion() = 0;
};
// --------------------------------------------------------------------------------------
// BaseDeletableObject
// --------------------------------------------------------------------------------------
// Oh the fruits and joys of multithreaded C++ coding conundrums! This class provides a way
// to be deleted from arbitraty threads, or to delete themselves (which is considered unsafe
// in C++, though it does typically work). It also gives objects a second recourse for
// doing fully virtualized cleanup, something C++ also makes impossible because of how it
// implements it's destructor hierarchy.
//
// To utilize virtual destruction, override DoDeletion() and be sure to invoke the base class
// implementation of DoDeletion().
//
// Assertions:
// This class generates an assertion of the destructor is called from anything other than
// the main/gui thread.
//
// Rationale:
// wxWidgets provides a pending deletion feature, but it's specific to wxCore (not wxBase)
// which means it requires wxApp and all that, which is bad for plugins and the possibility
// of linking PCSX2 core against a non-WX gui in the future. It's also not thread safe
// (sigh). And, finally, it requires quite a bit of red tape to implement wxObjects because
// of the wx-custom runtime type information. So I made my own.
//
class BaseDeletableObject : public virtual IDeletableObject
{
protected:
std::atomic<bool> m_IsBeingDeleted;
public:
BaseDeletableObject();
virtual ~BaseDeletableObject();
void DeleteSelf();
bool IsBeingDeleted() { return !!m_IsBeingDeleted; }
// Returns FALSE if the object is already marked for deletion, or TRUE if the app
// should schedule the object for deletion. Only schedule if TRUE is returned, otherwise
// the object could get deleted twice if two threads try to schedule it at the same time.
bool MarkForDeletion();
protected:
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?).
virtual void DoDeletion();
};
// --------------------------------------------------------------------------------------
// PageProtectionMode
// --------------------------------------------------------------------------------------

View File

@ -15,7 +15,6 @@
#include "common/Threading.h"
#include "common/wxBaseTools.h"
#include "common/wxGuiTools.h"
#include "common/ThreadingInternal.h"
namespace Threading
@ -205,7 +204,6 @@ void Threading::Mutex::Acquire()
}
else if (_WaitGui_RecursionGuard(L"Mutex::Acquire"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
pthread_mutex_lock(&m_mutex);
}
else
@ -228,7 +226,6 @@ bool Threading::Mutex::Acquire(const wxTimeSpan& timeout)
}
else if (_WaitGui_RecursionGuard(L"Mutex::TimedAcquire"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return AcquireWithoutYield(timeout);
}
else

View File

@ -191,32 +191,3 @@ wxString Path::GetRootDirectory(const wxString& src)
else
return wxString(src.begin(), src.begin() + pos);
}
// ------------------------------------------------------------------------
// Launches the specified file according to its mime type
//
void pxLaunch(const wxString& filename)
{
wxLaunchDefaultBrowser(filename);
}
void pxLaunch(const char* filename)
{
pxLaunch(fromUTF8(filename));
}
// ------------------------------------------------------------------------
// Launches a file explorer window on the specified path. If the given path is not
// a qualified URI (with a prefix:// ), file:// is automatically prepended. This
// bypasses wxWidgets internal filename checking, which can end up launching things
// through browser more often than desired.
//
void pxExplore(const wxString& path)
{
wxLaunchDefaultBrowser(!path.Contains(L"://") ? L"file://" + path : path);
}
void pxExplore(const char* path)
{
pxExplore(fromUTF8(path));
}

View File

@ -17,7 +17,6 @@
#include "common/Threading.h"
#include "common/wxBaseTools.h"
#include "common/wxGuiTools.h"
#include "common/ThreadingInternal.h"
// --------------------------------------------------------------------------------------
@ -87,7 +86,6 @@ void Threading::Semaphore::Wait()
}
else if (_WaitGui_RecursionGuard(L"Semaphore::Wait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
sem_wait(&m_sema);
}
else
@ -119,7 +117,6 @@ bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
}
else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return WaitWithoutYield(timeout);
}
else

View File

@ -51,7 +51,6 @@
<ClCompile Include="IniInterface.cpp" />
<ClCompile Include="pxStreams.cpp" />
<ClCompile Include="pxTranslate.cpp" />
<ClCompile Include="pxWindowTextWriter.cpp" />
<ClCompile Include="StringUtil.cpp" />
<ClCompile Include="SettingsWrapper.cpp" />
<ClCompile Include="VirtualMemory.cpp" />
@ -61,10 +60,7 @@
<ClCompile Include="PrecompiledHeader.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="pxStaticText.cpp" />
<ClCompile Include="StringHelpers.cpp" />
<ClCompile Include="wxGuiTools.cpp" />
<ClCompile Include="wxHelpers.cpp" />
<ClCompile Include="Linux\LnxHostSys.cpp" />
<ClCompile Include="Linux\LnxMisc.cpp" />
<ClCompile Include="Linux\LnxThreads.cpp" />
@ -115,12 +111,10 @@
<ClInclude Include="MemcpyFast.h" />
<ClInclude Include="Path.h" />
<ClInclude Include="PrecompiledHeader.h" />
<ClInclude Include="pxStaticText.h" />
<ClInclude Include="RedtapeWindows.h" />
<ClInclude Include="SafeArray.h" />
<ClInclude Include="StringHelpers.h" />
<ClInclude Include="wxBaseTools.h" />
<ClInclude Include="wxGuiTools.h" />
<ClInclude Include="Threading.h" />
<ClInclude Include="PersistentThread.h" />
<ClInclude Include="RwMutex.h" />

View File

@ -67,18 +67,12 @@
<ClCompile Include="PrecompiledHeader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pxStaticText.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pxStreams.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pxTranslate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pxWindowTextWriter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RwMutex.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -109,12 +103,6 @@
<ClCompile Include="Windows\WinThreads.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wxGuiTools.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wxHelpers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="emitter\x86emitter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -210,9 +198,6 @@
<ClInclude Include="PrecompiledHeader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pxStaticText.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RedtapeWindows.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -258,9 +243,6 @@
<ClInclude Include="wxBaseTools.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wxGuiTools.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="emitter\x86emitter.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -26,12 +26,6 @@
// which require wxCore, see wxGuiTools.h
// --------------------------------------------------------------------------------------
extern void pxExplore(const wxString& path);
extern void pxExplore(const char* path);
extern void pxLaunch(const wxString& path);
extern void pxLaunch(const char* path);
// --------------------------------------------------------------------------------------
// wxDoNotLogInThisScope
// --------------------------------------------------------------------------------------

View File

@ -1031,12 +1031,16 @@ set(pcsx2GuiSources
gui/Panels/VideoPanel.cpp
gui/pxCheckBox.cpp
gui/pxRadioPanel.cpp
gui/pxStaticText.cpp
gui/pxWindowTextWriter.cpp
gui/RecentIsoList.cpp
gui/Saveslots.cpp
gui/SysState.cpp
gui/ThreadingDialogs.cpp
gui/UpdateUI.cpp
gui/wxAppWithHelpers.cpp
gui/wxGuiTools.cpp
gui/wxHelpers.cpp
gui/wxSettingsInterface.cpp
)
@ -1079,11 +1083,13 @@ set(pcsx2GuiHeaders
gui/pxEvents.h
gui/pxEventThread.h
gui/pxRadioPanel.h
gui/pxStaticText.h
gui/RecentIsoList.h
gui/Saveslots.h
gui/ThreadingDialogs.h
gui/ThreadingDialogs.cpp
gui/wxSettingsInterface.cpp
gui/wxGuiTools.h
gui/wxSettingsInterface.h
)
# Warning: the declaration of the .h are mandatory in case of resources files. It will ensure the creation

View File

@ -19,10 +19,10 @@
#include "common/EventSource.h"
#include "common/PersistentThread.h"
#include "common/wxGuiTools.h"
#include "gui/wxGuiTools.h"
#include "gui/pxRadioPanel.h"
#include "gui/pxCheckBox.h"
#include "common/pxStaticText.h"
#include "gui/pxStaticText.h"
#include "gui/CheckedStaticBox.h"
#include "AppForwardDefs.h"

View File

@ -15,7 +15,7 @@
#pragma once
#include "common/wxGuiTools.h"
#include "gui/wxGuiTools.h"
class CheckedStaticBox : public wxPanelWithHelpers
{

View File

@ -18,7 +18,7 @@
#include "gui/App.h"
#include "ConfigurationDialog.h"
#include "common/wxGuiTools.h"
#include "gui/wxGuiTools.h"
#include "gui/CheckedStaticBox.h"
namespace Dialogs {

View File

@ -15,7 +15,7 @@
#include "PrecompiledHeader.h"
#include "gui/ThreadingDialogs.h"
#include "common/pxStaticText.h"
#include "gui/pxStaticText.h"
using namespace pxSizerFlags;

View File

@ -15,7 +15,7 @@
#include "PrecompiledHeader.h"
#include "gui/pxCheckBox.h"
#include "common/pxStaticText.h"
#include "gui/pxStaticText.h"
using namespace pxSizerFlags;

View File

@ -16,7 +16,7 @@
#pragma once
#include <wx/wx.h>
#include "common/wxGuiTools.h"
#include "gui/wxGuiTools.h"
// -------------------------------------------------------------------------------------
// pxCheckBox

View File

@ -15,7 +15,7 @@
#include "PrecompiledHeader.h"
#include "gui/pxRadioPanel.h"
#include "common/pxStaticText.h"
#include "gui/pxStaticText.h"
#include "common/SafeArray.inl"
template class SafeArray<RadioPanelObjects>;

View File

@ -17,7 +17,7 @@
#include <wx/wx.h>
#include "common/SafeArray.h"
#include "common/wxGuiTools.h"
#include "gui/wxGuiTools.h"
// --------------------------------------------------------------------------------------
// RadioPanelItem

View File

@ -13,9 +13,11 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <wx/wizard.h>
#include "common/pxStaticText.h"
#include "common/Assertions.h"
#include "gui/pxStaticText.h"
// --------------------------------------------------------------------------------------
// pxStaticText (implementations)

View File

@ -13,9 +13,11 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <wx/wx.h>
#include "common/wxGuiTools.h"
#include "common/StringHelpers.h"
#include "gui/wxGuiTools.h"
// --------------------------------------------------------------------------------------
// pxWindowTextWriter Implementations

View File

@ -38,6 +38,39 @@ ConsoleLogSource_App::ConsoleLogSource_App()
ConsoleLogSource_App pxConLog_App;
// --------------------------------------------------------------------------------------
// BaseDeletableObject Implementation
// --------------------------------------------------------------------------------------
// This code probably deserves a better home. It's general purpose non-GUI code (the single
// wxApp/Gui dependency is in wxGuiTools.cpp for now).
//
bool BaseDeletableObject::MarkForDeletion()
{
return !m_IsBeingDeleted.exchange(true);
}
void BaseDeletableObject::DeleteSelf()
{
if (MarkForDeletion())
DoDeletion();
}
BaseDeletableObject::BaseDeletableObject()
{
#ifdef _MSC_VER
// Bleh, this fails because _CrtIsValidHeapPointer calls HeapValidate on the
// pointer, but the pointer is a virtual base class, so it's not a valid block. >_<
//pxAssertDev( _CrtIsValidHeapPointer( this ), "BaseDeletableObject types cannot be created on the stack or as temporaries!" );
#endif
m_IsBeingDeleted.store(false, std::memory_order_relaxed);
}
BaseDeletableObject::~BaseDeletableObject()
{
AffinityAssert_AllowFrom_MainUI();
}
void BaseDeletableObject::DoDeletion()
{
wxAppWithHelpers* app = wxDynamicCast(wxApp::GetInstance(), wxAppWithHelpers);
@ -45,7 +78,6 @@ void BaseDeletableObject::DoDeletion()
app->DeleteObject(*this);
}
// --------------------------------------------------------------------------------------
// SynchronousActionState Implementations
// --------------------------------------------------------------------------------------

View File

@ -18,14 +18,62 @@
#include <wx/wx.h>
#include "common/Threading.h"
#include "common/wxGuiTools.h"
#include "gui/pxEvents.h"
#include "gui/wxGuiTools.h"
#include "common/AppTrait.h"
using namespace Threading;
class pxSynchronousCommandEvent;
// --------------------------------------------------------------------------------------
// BaseDeletableObject
// --------------------------------------------------------------------------------------
// Oh the fruits and joys of multithreaded C++ coding conundrums! This class provides a way
// to be deleted from arbitraty threads, or to delete themselves (which is considered unsafe
// in C++, though it does typically work). It also gives objects a second recourse for
// doing fully virtualized cleanup, something C++ also makes impossible because of how it
// implements it's destructor hierarchy.
//
// To utilize virtual destruction, override DoDeletion() and be sure to invoke the base class
// implementation of DoDeletion().
//
// Assertions:
// This class generates an assertion of the destructor is called from anything other than
// the main/gui thread.
//
// Rationale:
// wxWidgets provides a pending deletion feature, but it's specific to wxCore (not wxBase)
// which means it requires wxApp and all that, which is bad for plugins and the possibility
// of linking PCSX2 core against a non-WX gui in the future. It's also not thread safe
// (sigh). And, finally, it requires quite a bit of red tape to implement wxObjects because
// of the wx-custom runtime type information. So I made my own.
//
class BaseDeletableObject : public virtual IDeletableObject
{
protected:
std::atomic<bool> m_IsBeingDeleted;
public:
BaseDeletableObject();
virtual ~BaseDeletableObject();
void DeleteSelf();
bool IsBeingDeleted() { return !!m_IsBeingDeleted; }
// Returns FALSE if the object is already marked for deletion, or TRUE if the app
// should schedule the object for deletion. Only schedule if TRUE is returned, otherwise
// the object could get deleted twice if two threads try to schedule it at the same time.
bool MarkForDeletion();
protected:
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?).
virtual void DoDeletion();
};
// --------------------------------------------------------------------------------------
// pxAppLog / ConsoleLogSource_App
// --------------------------------------------------------------------------------------

View File

@ -13,9 +13,10 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "common/PrecompiledHeader.h"
#include "common/wxGuiTools.h"
#include "common/pxStaticText.h"
#include "PrecompiledHeader.h"
#include "gui/wxGuiTools.h"
#include "gui/pxStaticText.h"
#include <wx/app.h>
#include <wx/window.h>
@ -649,3 +650,33 @@ wxString pxGetAppName()
pxAssert(wxTheApp);
return wxTheApp->GetAppName();
}
// ------------------------------------------------------------------------
// Launches the specified file according to its mime type
//
void pxLaunch(const wxString& filename)
{
wxLaunchDefaultBrowser(filename);
}
void pxLaunch(const char* filename)
{
pxLaunch(fromUTF8(filename));
}
// ------------------------------------------------------------------------
// Launches a file explorer window on the specified path. If the given path is not
// a qualified URI (with a prefix:// ), file:// is automatically prepended. This
// bypasses wxWidgets internal filename checking, which can end up launching things
// through browser more often than desired.
//
void pxExplore(const wxString& path)
{
wxLaunchDefaultBrowser(!path.Contains(L"://") ? L"file://" + path : path);
}
void pxExplore(const char* path)
{
pxExplore(fromUTF8(path));
}

View File

@ -802,3 +802,9 @@ extern void pxSetToolTip(wxWindow& wind, const wxString& src);
extern wxFont pxGetFixedFont(int ptsize = 8, wxFontWeight weight = wxFONTWEIGHT_NORMAL, bool underline = false);
extern pxDialogCreationFlags pxDialogFlags();
extern void pxExplore(const wxString& path);
extern void pxExplore(const char* path);
extern void pxLaunch(const wxString& path);
extern void pxLaunch(const char* path);

View File

@ -13,14 +13,16 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <wx/cshelp.h>
#include <wx/tooltip.h>
#include <wx/spinctrl.h>
#include "common/General.h"
#include "common/wxGuiTools.h"
#include "common/pxStaticText.h"
#include "common/Threading.h"
#include "common/IniInterface.h"
#include "gui/wxGuiTools.h"
#include "gui/pxStaticText.h"
using namespace pxSizerFlags;
@ -30,40 +32,6 @@ pxDialogCreationFlags pxDialogFlags()
}
// --------------------------------------------------------------------------------------
// BaseDeletableObject Implementation
// --------------------------------------------------------------------------------------
// This code probably deserves a better home. It's general purpose non-GUI code (the single
// wxApp/Gui dependency is in wxGuiTools.cpp for now).
//
bool BaseDeletableObject::MarkForDeletion()
{
return !m_IsBeingDeleted.exchange(true);
}
void BaseDeletableObject::DeleteSelf()
{
if (MarkForDeletion())
DoDeletion();
}
BaseDeletableObject::BaseDeletableObject()
{
#ifdef _MSC_VER
// Bleh, this fails because _CrtIsValidHeapPointer calls HeapValidate on the
// pointer, but the pointer is a virtual base class, so it's not a valid block. >_<
//pxAssertDev( _CrtIsValidHeapPointer( this ), "BaseDeletableObject types cannot be created on the stack or as temporaries!" );
#endif
m_IsBeingDeleted.store(false, std::memory_order_relaxed);
}
BaseDeletableObject::~BaseDeletableObject()
{
AffinityAssert_AllowFrom_MainUI();
}
// --------------------------------------------------------------------------------------

View File

@ -318,6 +318,8 @@
<ClCompile Include="gui\Panels\MemoryCardListView.cpp" />
<ClCompile Include="gui\pxCheckBox.cpp" />
<ClCompile Include="gui\pxRadioPanel.cpp" />
<ClCompile Include="gui\pxStaticText.cpp" />
<ClCompile Include="gui\pxWindowTextWriter.cpp" />
<ClCompile Include="gui\ThreadingDialogs.cpp" />
<ClCompile Include="gui\wxAppWithHelpers.cpp" />
<ClCompile Include="gui\wxSettingsInterface.cpp" />
@ -667,6 +669,8 @@
<ClCompile Include="gui\MSWstuff.cpp" />
<ClCompile Include="gui\RecentIsoList.cpp" />
<ClCompile Include="gui\UpdateUI.cpp" />
<ClCompile Include="gui\wxGuiTools.cpp" />
<ClCompile Include="gui\wxHelpers.cpp" />
<ClCompile Include="gui\Dialogs\AboutBoxDialog.cpp" />
<ClCompile Include="gui\Dialogs\AssertionDialog.cpp" />
<ClCompile Include="gui\Dialogs\BaseConfigurationDialog.cpp" />
@ -757,6 +761,7 @@
<ClInclude Include="gui\pxCheckBox.h" />
<ClInclude Include="gui\pxEvents.h" />
<ClInclude Include="gui\pxRadioPanel.h" />
<ClInclude Include="gui\pxStaticText.h" />
<ClInclude Include="gui\Saveslots.h" />
<ClInclude Include="gui\Debugger\BreakpointWindow.h" />
<ClInclude Include="gui\Debugger\CtrlDisassemblyView.h" />
@ -1087,6 +1092,7 @@
<ClInclude Include="gui\MainFrame.h" />
<ClInclude Include="gui\pxEventThread.h" />
<ClInclude Include="gui\RecentIsoList.h" />
<ClInclude Include="gui\wxGuiTools.h" />
<ClInclude Include="PathDefs.h" />
<ClInclude Include="SysForwardDefs.h" />
<ClInclude Include="cheatscpp.h" />

View File

@ -1664,6 +1664,14 @@
<ClCompile Include="gui\wxSettingsInterface.cpp">
<Filter>AppHost</Filter>
</ClCompile>
<ClCompile Include="gui\wxGuiTools.cpp" />
<ClCompile Include="gui\wxHelpers.cpp" />
<ClCompile Include="gui\pxStaticText.cpp">
<Filter>AppHost</Filter>
</ClCompile>
<ClCompile Include="gui\pxWindowTextWriter.cpp">
<Filter>AppHost</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Patch.h">
@ -2767,6 +2775,10 @@
<ClInclude Include="gui\wxSettingsInterface.h">
<Filter>AppHost</Filter>
</ClInclude>
<ClInclude Include="gui\wxGuiTools.h" />
<ClInclude Include="gui\pxStaticText.h">
<Filter>AppHost</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="windows\wxResources.rc">