aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Beyer <beyert_freebsd@fastmail.net>2022-05-17 03:53:46 +0000
committerNeel Chauhan <nc@FreeBSD.org>2022-05-19 17:49:22 +0000
commitb8b789478ef4616e10614abc1ed1488425aa8336 (patch)
tree5976e9e8458b3e134ec9cf1f27c01f8366191798
parent316d2de4b5ea9565b4b81bc3e6e00165454d792c (diff)
downloadports-b8b789478ef4616e10614abc1ed1488425aa8336.tar.gz
ports-b8b789478ef4616e10614abc1ed1488425aa8336.zip
emulators/libretro-pcsx2: New port: Standalone port of pcsx2 to libretro emulator
PR: 252191
-rw-r--r--emulators/Makefile1
-rw-r--r--emulators/libretro-pcsx2/Makefile65
-rw-r--r--emulators/libretro-pcsx2/distinfo3
-rw-r--r--emulators/libretro-pcsx2/files/3rdparty_wxwidgets3.0_src_unix_fswatcher__kqueue.cpp459
-rw-r--r--emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_CMakeLists.txt14
-rw-r--r--emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_UsewxWidgets.cmake11
-rw-r--r--emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_include_nogui_wx_setup.h11
-rw-r--r--emulators/libretro-pcsx2/files/patch-CMakeLists.txt14
-rw-r--r--emulators/libretro-pcsx2/files/patch-common_include_Utilities_General.h11
-rw-r--r--emulators/libretro-pcsx2/files/patch-pcsx2_SPU2_spu2.cpp14
-rw-r--r--emulators/libretro-pcsx2/pkg-descr9
11 files changed, 612 insertions, 0 deletions
diff --git a/emulators/Makefile b/emulators/Makefile
index 574973a982a1..20c3c7fbd15c 100644
--- a/emulators/Makefile
+++ b/emulators/Makefile
@@ -59,6 +59,7 @@
SUBDIR += libdsk
SUBDIR += libretro-flycast
SUBDIR += libretro-mame
+ SUBDIR += libretro-pcsx2
SUBDIR += libretro-ppsspp
SUBDIR += libretro-reicast
SUBDIR += libretro-vice
diff --git a/emulators/libretro-pcsx2/Makefile b/emulators/libretro-pcsx2/Makefile
new file mode 100644
index 000000000000..779c89f7d839
--- /dev/null
+++ b/emulators/libretro-pcsx2/Makefile
@@ -0,0 +1,65 @@
+# $FreeBSD$
+
+PORTNAME= libretro-pcsx2
+PORTVERSION= 0.20201030
+CATEGORIES= emulators games
+
+MAINTAINER= beyert@cs.ucr.edu
+COMMENT= Standalone port of pcsx2 to libretro
+
+LICENSE= GPLv3
+LICENSE_FILE= ${WRKSRC}/COPYING.GPLv3
+
+ONLY_FOR_ARCHS= >i386 amd64
+
+LIB_DEPENDS= libcdio.so:sysutils/libcdio \
+ libharfbuzz.so:print/harfbuzz \
+ libpng16.so:graphics/png \
+ libportaudio.so:audio/portaudio \
+ libSoundTouch.so:audio/soundtouch
+
+USES= cmake compiler:c++11-lib
+
+CPPFLAGS+= -I${LOCALBASE}/include/wx-3.0
+USE_CXXSTD= c++11
+#LDFLAGS+= -L${LOCALBASE}/lib -I/usr/lib
+USE_LDCONFIG= yes
+CMAKE_CPP_FLAGS= ${CPPFLAGS}
+CMAKE_PREFIX_PATH= ${LOCALBASE}/include/wx-3.0
+CMAKE_C_FLAGS= ${CFLAGS}
+CMAKE_CXX_FLAGS= ${CFLAGS}
+CMAKE_ARGS+= -DLIBRETRO=yes
+CMAKE_ARGS+= -Dgtk_INCLUDE_DIR="${LOCALBASE}/include/gtk-3.0" \
+ -DwxWidgets_INCLUDE_DIRS="${LOCALBASE}/include/wx-3.0"
+
+# lib depends on devel/ccache
+WITH_CCACHE_BUILD= yes
+
+HAVE_GTK3= true
+#USES= gnome xorg gl sdl dos2unix cmake:insource iconv gettext linux:c7 pkgconfig
+#USE_LINUX= libaio
+USE_WX= 3.0+
+#USE_XORG= ice x11 xv xext xxf86vm xtst xrandr xi
+USE_GL= gl glew glu
+USE_GNOME= glib20
+#USE_SDL= sdl2
+
+MAKE_JOBS_UNSAFE= yes
+
+USE_GITHUB= yes
+GH_ACCOUNT= libretro
+GH_PROJECT= pcsx2
+GH_TAGNAME= 1251fa4
+
+PLIST_FILES= lib/libretro/pcsx2_libretro.so
+
+post-patch:
+ ${CP} files/3rdparty_wxwidgets3.0_src_unix_fswatcher__kqueue.cpp \
+ ${WRKSRC}/3rdparty/wxwidgets3.0/src/unix/fswatcher_kqueue.cpp
+
+do-install:
+ ${MKDIR} ${STAGEDIR}/${PREFIX}/lib/libretro;
+ ${INSTALL_LIB} ${WRKDIR}/.build/pcsx2/pcsx2_libretro.so \
+ ${STAGEDIR}/${PREFIX}/lib/libretro;
+
+.include <bsd.port.mk>
diff --git a/emulators/libretro-pcsx2/distinfo b/emulators/libretro-pcsx2/distinfo
new file mode 100644
index 000000000000..36d8005daf71
--- /dev/null
+++ b/emulators/libretro-pcsx2/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1604098409
+SHA256 (libretro-pcsx2-0.20201030-1251fa4_GH0.tar.gz) = 01b329b4bba210022f0f0f889b2e4722ef530b766eaf7036194a53668b47a245
+SIZE (libretro-pcsx2-0.20201030-1251fa4_GH0.tar.gz) = 15636747
diff --git a/emulators/libretro-pcsx2/files/3rdparty_wxwidgets3.0_src_unix_fswatcher__kqueue.cpp b/emulators/libretro-pcsx2/files/3rdparty_wxwidgets3.0_src_unix_fswatcher__kqueue.cpp
new file mode 100644
index 000000000000..55cb787cd1ae
--- /dev/null
+++ b/emulators/libretro-pcsx2/files/3rdparty_wxwidgets3.0_src_unix_fswatcher__kqueue.cpp
@@ -0,0 +1,459 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: src/unix/fswatcher_kqueue.cpp
+// Purpose: kqueue-based wxFileSystemWatcher implementation
+// Author: Bartosz Bekier
+// Created: 2009-05-26
+// Copyright: (c) 2009 Bartosz Bekier <bartosz.bekier@gmail.com>
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_FSWATCHER
+
+#include "wx/fswatcher.h"
+
+#ifdef wxHAS_KQUEUE
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/param.h>
+
+#include "wx/dynarray.h"
+#include "wx/evtloop.h"
+#include "wx/evtloopsrc.h"
+
+#include "wx/private/fswatcher.h"
+
+namespace
+{
+
+// NetBSD is different as it uses intptr_t as type of kevent struct udata field
+// for some reason, instead of "void*" as all the other platforms using kqueue.
+#ifdef __NetBSD__
+ inline intptr_t ToUdata(void* d) { return reinterpret_cast<intptr_t>(d); }
+ inline void* FromUdata(intptr_t d) { return reinterpret_cast<void*>(d); }
+#else
+ inline void* ToUdata(void* d) { return d; }
+ inline void* FromUdata(void* d) { return d; }
+#endif
+
+} // anonymous namespace
+
+// ============================================================================
+// wxFSWSourceHandler helper class
+// ============================================================================
+
+class wxFSWatcherImplKqueue;
+
+/**
+ * Handler for handling i/o from inotify descriptor
+ */
+class wxFSWSourceHandler : public wxEventLoopSourceHandler
+{
+public:
+ wxFSWSourceHandler(wxFSWatcherImplKqueue* service) :
+ m_service(service)
+ { }
+
+ virtual void OnReadWaiting();
+ virtual void OnWriteWaiting();
+ virtual void OnExceptionWaiting();
+
+protected:
+ wxFSWatcherImplKqueue* m_service;
+};
+
+// ============================================================================
+// wxFSWatcherImpl implementation & helper wxFSWSourceHandler implementation
+// ============================================================================
+
+/**
+ * Helper class encapsulating inotify mechanism
+ */
+class wxFSWatcherImplKqueue : public wxFSWatcherImpl
+{
+public:
+ wxFSWatcherImplKqueue(wxFileSystemWatcherBase* watcher) :
+ wxFSWatcherImpl(watcher),
+ m_source(NULL),
+ m_kfd(-1)
+ {
+ m_handler = new wxFSWSourceHandler(this);
+ }
+
+ virtual ~wxFSWatcherImplKqueue()
+ {
+ // we close kqueue only if initialized before
+ if (IsOk())
+ {
+ Close();
+ }
+
+ delete m_handler;
+ }
+
+ bool Init()
+ {
+ wxCHECK_MSG( !IsOk(), false,
+ "Kqueue appears to be already initialized" );
+
+ wxEventLoopBase *loop = wxEventLoopBase::GetActive();
+ wxCHECK_MSG( loop, false, "File system watcher needs an active loop" );
+
+ // create kqueue
+ m_kfd = kqueue();
+ if (m_kfd == -1)
+ {
+ wxLogSysError(_("Unable to create kqueue instance"));
+ return false;
+ }
+
+ // create source
+ m_source = loop->AddSourceForFD(m_kfd, m_handler, wxEVENT_SOURCE_INPUT);
+
+ return m_source != NULL;
+ }
+
+ void Close()
+ {
+ wxCHECK_RET( IsOk(),
+ "Kqueue not initialized or invalid kqueue descriptor" );
+
+ if ( close(m_kfd) != 0 )
+ {
+ wxLogSysError(_("Error closing kqueue instance"));
+ }
+
+ wxDELETE(m_source);
+ }
+
+ virtual bool DoAdd(wxSharedPtr<wxFSWatchEntryKq> watch)
+ {
+ wxCHECK_MSG( IsOk(), false,
+ "Kqueue not initialized or invalid kqueue descriptor" );
+
+ struct kevent event;
+ int action = EV_ADD | EV_ENABLE | EV_CLEAR | EV_ERROR;
+ int flags = Watcher2NativeFlags(watch->GetFlags());
+ EV_SET( &event, watch->GetFileDescriptor(), EVFILT_VNODE, action,
+ flags, 0, ToUdata(watch.get()) );
+
+ // TODO more error conditions according to man
+ // TODO best deal with the error here
+ int ret = kevent(m_kfd, &event, 1, NULL, 0, NULL);
+ if (ret == -1)
+ {
+ wxLogSysError(_("Unable to add kqueue watch"));
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual bool DoRemove(wxSharedPtr<wxFSWatchEntryKq> watch)
+ {
+ wxCHECK_MSG( IsOk(), false,
+ "Kqueue not initialized or invalid kqueue descriptor" );
+
+ // TODO more error conditions according to man
+ // XXX closing file descriptor removes the watch. The logic resides in
+ // the watch which is not nice, but effective and simple
+ if ( !watch->Close() )
+ {
+ wxLogSysError(_("Unable to remove kqueue watch"));
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual bool RemoveAll()
+ {
+ wxFSWatchEntries::iterator it = m_watches.begin();
+ for ( ; it != m_watches.end(); ++it )
+ {
+ (void) DoRemove(it->second);
+ }
+ m_watches.clear();
+ return true;
+ }
+
+ // return true if there was no error, false on error
+ bool ReadEvents()
+ {
+ wxCHECK_MSG( IsOk(), false,
+ "Kqueue not initialized or invalid kqueue descriptor" );
+
+ // read events
+ do
+ {
+ struct kevent event;
+ struct timespec timeout = {0, 0};
+ int ret = kevent(m_kfd, NULL, 0, &event, 1, &timeout);
+ if (ret == -1)
+ {
+ wxLogSysError(_("Unable to get events from kqueue"));
+ return false;
+ }
+ else if (ret == 0)
+ {
+ return true;
+ }
+
+ // we have event, so process it
+ ProcessNativeEvent(event);
+ }
+ while (true);
+
+ // when ret>0 we still have events, when ret<=0 we return
+ wxFAIL_MSG( "Never reached" );
+ return true;
+ }
+
+ bool IsOk() const
+ {
+ return m_source != NULL;
+ }
+
+protected:
+ // returns all new dirs/files present in the immediate level of the dir
+ // pointed by watch.GetPath(). "new" means created between the last time
+ // the state of watch was computed and now
+ void FindChanges(wxFSWatchEntryKq& watch,
+ wxArrayString& changedFiles,
+ wxArrayInt& changedFlags)
+ {
+ wxFSWatchEntryKq::wxDirState old = watch.GetLastState();
+ watch.RefreshState();
+ wxFSWatchEntryKq::wxDirState curr = watch.GetLastState();
+
+ // iterate over old/curr file lists and compute changes
+ wxArrayString::iterator oit = old.files.begin();
+ wxArrayString::iterator cit = curr.files.begin();
+ for ( ; oit != old.files.end() && cit != curr.files.end(); )
+ {
+ if ( *cit == *oit )
+ {
+ ++cit;
+ ++oit;
+ }
+ else if ( *cit <= *oit )
+ {
+ changedFiles.push_back(*cit);
+ changedFlags.push_back(wxFSW_EVENT_CREATE);
+ ++cit;
+ }
+ else // ( *cit > *oit )
+ {
+ changedFiles.push_back(*oit);
+ changedFlags.push_back(wxFSW_EVENT_DELETE);
+ ++oit;
+ }
+ }
+
+ // border conditions
+ if ( oit == old.files.end() )
+ {
+ for ( ; cit != curr.files.end(); ++cit )
+ {
+ changedFiles.push_back( *cit );
+ changedFlags.push_back(wxFSW_EVENT_CREATE);
+ }
+ }
+ else if ( cit == curr.files.end() )
+ {
+ for ( ; oit != old.files.end(); ++oit )
+ {
+ changedFiles.push_back( *oit );
+ changedFlags.push_back(wxFSW_EVENT_DELETE);
+ }
+ }
+
+ wxASSERT( changedFiles.size() == changedFlags.size() );
+
+#if 0
+ wxLogTrace(wxTRACE_FSWATCHER, "Changed files:");
+ wxArrayString::iterator it = changedFiles.begin();
+ wxArrayInt::iterator it2 = changedFlags.begin();
+ for ( ; it != changedFiles.end(); ++it, ++it2)
+ {
+ wxString action = (*it2 == wxFSW_EVENT_CREATE) ?
+ "created" : "deleted";
+ wxLogTrace(wxTRACE_FSWATCHER, wxString::Format("File: '%s' %s",
+ *it, action));
+ }
+#endif
+ }
+
+ void ProcessNativeEvent(const struct kevent& e)
+ {
+ void* const udata = FromUdata(e.udata);
+
+ wxASSERT_MSG(udata, "Null user data associated with kevent!");
+ wxLogTrace(wxTRACE_FSWATCHER, "Event: ident=%" PRIuPTR ", filter=%hd, flags=%hu, "
+#if __FreeBSD_version >= 1200033
+ "fflags=%u, data=%" PRId64 ", user_data=%p",
+#else
+ "fflags=%u, data=%" PRIdPTR ", user_data=%p",
+#endif
+ e.ident, e.filter, e.flags, e.fflags, e.data, udata);
+
+ // for ease of use
+ wxFSWatchEntryKq& w = *(static_cast<wxFSWatchEntry*>(udata));
+ int nflags = e.fflags;
+
+ // clear ignored flags
+ nflags &= ~NOTE_REVOKE;
+
+ // TODO ignore events we didn't ask for + refactor this cascade ifs
+ // check for events
+ while ( nflags )
+ {
+ // when monitoring dir, this means create/delete
+ const wxString basepath = w.GetPath();
+ if ( nflags & NOTE_WRITE && wxDirExists(basepath) )
+ {
+ // NOTE_LINK is set when the dir was created, but we
+ // don't care - we look for new names in directory
+ // regardless of type. Also, clear all this, because
+ // it cannot mean more by itself
+ nflags &= ~(NOTE_WRITE | NOTE_ATTRIB | NOTE_LINK);
+
+ wxArrayString changedFiles;
+ wxArrayInt changedFlags;
+ FindChanges(w, changedFiles, changedFlags);
+
+ wxArrayString::iterator it = changedFiles.begin();
+ wxArrayInt::iterator changeType = changedFlags.begin();
+ for ( ; it != changedFiles.end(); ++it, ++changeType )
+ {
+ const wxString fullpath = w.GetPath() +
+ wxFileName::GetPathSeparator() +
+ *it;
+ const wxFileName path(wxDirExists(fullpath)
+ ? wxFileName::DirName(fullpath)
+ : wxFileName::FileName(fullpath));
+
+ wxFileSystemWatcherEvent event(*changeType, path, path);
+ SendEvent(event);
+ }
+ }
+ else if ( nflags & NOTE_RENAME )
+ {
+ // CHECK it'd be only possible to detect name if we had
+ // parent files listing which we could confront with now and
+ // still we couldn't be sure we have the right name...
+ nflags &= ~NOTE_RENAME;
+ wxFileSystemWatcherEvent event(wxFSW_EVENT_RENAME,
+ basepath, wxFileName());
+ SendEvent(event);
+ }
+ else if ( nflags & NOTE_WRITE || nflags & NOTE_EXTEND )
+ {
+ nflags &= ~(NOTE_WRITE | NOTE_EXTEND);
+ wxFileSystemWatcherEvent event(wxFSW_EVENT_MODIFY,
+ basepath, basepath);
+ SendEvent(event);
+ }
+ else if ( nflags & NOTE_DELETE )
+ {
+ nflags &= ~(NOTE_DELETE);
+ wxFileSystemWatcherEvent event(wxFSW_EVENT_DELETE,
+ basepath, basepath);
+ SendEvent(event);
+ }
+ else if ( nflags & NOTE_ATTRIB )
+ {
+ nflags &= ~(NOTE_ATTRIB);
+ wxFileSystemWatcherEvent event(wxFSW_EVENT_ACCESS,
+ basepath, basepath);
+ SendEvent(event);
+ }
+
+ // clear any flags that won't mean anything by themselves
+ nflags &= ~(NOTE_LINK);
+ }
+ }
+
+ void SendEvent(wxFileSystemWatcherEvent& evt)
+ {
+ m_watcher->GetOwner()->ProcessEvent(evt);
+ }
+
+ static int Watcher2NativeFlags(int WXUNUSED(flags))
+ {
+ // TODO: it would be better to only subscribe to what we need
+ return NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND |
+ NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME |
+ NOTE_REVOKE;
+ }
+
+ wxFSWSourceHandler* m_handler; // handler for kqueue event source
+ wxEventLoopSource* m_source; // our event loop source
+
+ // descriptor created by kqueue()
+ int m_kfd;
+};
+
+
+// once we get signaled to read, actuall event reading occurs
+void wxFSWSourceHandler::OnReadWaiting()
+{
+ wxLogTrace(wxTRACE_FSWATCHER, "--- OnReadWaiting ---");
+ m_service->ReadEvents();
+}
+
+void wxFSWSourceHandler::OnWriteWaiting()
+{
+ wxFAIL_MSG("We never write to kqueue descriptor.");
+}
+
+void wxFSWSourceHandler::OnExceptionWaiting()
+{
+ wxFAIL_MSG("We never receive exceptions on kqueue descriptor.");
+}
+
+
+// ============================================================================
+// wxKqueueFileSystemWatcher implementation
+// ============================================================================
+
+wxKqueueFileSystemWatcher::wxKqueueFileSystemWatcher()
+ : wxFileSystemWatcherBase()
+{
+ Init();
+}
+
+wxKqueueFileSystemWatcher::wxKqueueFileSystemWatcher(const wxFileName& path,
+ int events)
+ : wxFileSystemWatcherBase()
+{
+ if (!Init())
+ {
+ wxDELETE(m_service);
+ return;
+ }
+
+ Add(path, events);
+}
+
+wxKqueueFileSystemWatcher::~wxKqueueFileSystemWatcher()
+{
+}
+
+bool wxKqueueFileSystemWatcher::Init()
+{
+ m_service = new wxFSWatcherImplKqueue(this);
+ return m_service->Init();
+}
+
+#endif // wxHAS_KQUEUE
+
+#endif // wxUSE_FSWATCHER
diff --git a/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_CMakeLists.txt b/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_CMakeLists.txt
new file mode 100644
index 000000000000..8fa9ee4b563d
--- /dev/null
+++ b/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_CMakeLists.txt
@@ -0,0 +1,14 @@
+--- 3rdparty/wxwidgets3.0/CMakeLists.txt.orig 2020-10-29 23:31:05 UTC
++++ 3rdparty/wxwidgets3.0/CMakeLists.txt
+@@ -1,10 +1,10 @@
+ if(UNIX)
+ set(wxUnixSources
++ src/unix/fswatcher_kqueue.cpp
+ src/unix/appunix.cpp
+ src/unix/dir.cpp
+ src/unix/dlunix.cpp
+ src/unix/evtloopunix.cpp
+- src/unix/epolldispatcher.cpp
+ src/unix/fdiounix.cpp
+ src/unix/stackwalk.cpp
+ src/unix/stdpaths.cpp
diff --git a/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_UsewxWidgets.cmake b/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_UsewxWidgets.cmake
new file mode 100644
index 000000000000..96b899de88ec
--- /dev/null
+++ b/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_UsewxWidgets.cmake
@@ -0,0 +1,11 @@
+--- 3rdparty/wxwidgets3.0/UsewxWidgets.cmake.orig 2020-10-29 23:31:05 UTC
++++ 3rdparty/wxwidgets3.0/UsewxWidgets.cmake
+@@ -11,7 +11,7 @@ if(UNIX)
+ if(APPLE)
+ add_definitions(-D__DARWIN__)
+ else()
+- add_definitions(-D__LINUX__)
++ add_definitions(-D__BSD__)
+ endif()
+ elseif(WIN32)
+ add_definitions(-D__WINDOWS__)
diff --git a/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_include_nogui_wx_setup.h b/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_include_nogui_wx_setup.h
new file mode 100644
index 000000000000..fe0096b422c0
--- /dev/null
+++ b/emulators/libretro-pcsx2/files/patch-3rdparty_wxwidgets3.0_include_nogui_wx_setup.h
@@ -0,0 +1,11 @@
+--- 3rdparty/wxwidgets3.0/include/nogui/wx/setup.h.orig 2020-10-29 23:31:05 UTC
++++ 3rdparty/wxwidgets3.0/include/nogui/wx/setup.h
+@@ -1108,7 +1108,7 @@
+ #define HAVE_SYS_SELECT_H 1
+
+ /* Define if you have abi::__forced_unwind in your <cxxabi.h>. */
+-#define HAVE_ABI_FORCEDUNWIND 1
++/*#define HAVE_ABI_FORCEDUNWIND 1*/
+
+ /* Define if fdopen is available. */
+ #define HAVE_FDOPEN 1
diff --git a/emulators/libretro-pcsx2/files/patch-CMakeLists.txt b/emulators/libretro-pcsx2/files/patch-CMakeLists.txt
new file mode 100644
index 000000000000..233cd0e95aa3
--- /dev/null
+++ b/emulators/libretro-pcsx2/files/patch-CMakeLists.txt
@@ -0,0 +1,14 @@
+--- CMakeLists.txt.orig 2020-10-29 23:31:05 UTC
++++ CMakeLists.txt
+@@ -44,7 +44,10 @@ if (LIBRETRO)
+ set(BUILD_REPLAY_LOADERS FALSE)
+ # add_definitions(-D__LIBRETRO__ -DDISABLE_RECORDING)
+ #add_definitions(-D__LIBRETRO__ -DDISABLE_RECORDING -DwxUSE_UNICODE=0)
+-add_definitions(-D__LIBRETRO__ -DDISABLE_RECORDING -DwxUSE_GUI=0)
++message("wxWidgets_INCLUDE_DIRS: ${wxWidgets_INCLUDE_DIRS}")
++include_directories(${wxWidgets_INCLUDE_DIRS})
++#include_directories(${gdk_INCLUDE_DIRS})
++add_definitions(-D__LIBRETRO__ -DDISABLE_RECORDING -DwxUSE_GUI=0 -I${gtk_INCLUDE_DIR} -D__USE_ISOC11)
+ endif()
+
+ if(NOT NO_TRANSLATION)
diff --git a/emulators/libretro-pcsx2/files/patch-common_include_Utilities_General.h b/emulators/libretro-pcsx2/files/patch-common_include_Utilities_General.h
new file mode 100644
index 000000000000..5a9326ab92fe
--- /dev/null
+++ b/emulators/libretro-pcsx2/files/patch-common_include_Utilities_General.h
@@ -0,0 +1,11 @@
+--- common/include/Utilities/General.h.orig 2020-10-29 23:31:05 UTC
++++ common/include/Utilities/General.h
+@@ -257,7 +257,7 @@ void MemProtectStatic(u8 (&arr)[size], const PageProte
+
+ // Safe version of Munmap -- NULLs the pointer variable immediately after free'ing it.
+ #define SafeSysMunmap(ptr, size) \
+- ((void)(HostSys::Munmap((uptr)(ptr), size), (ptr) = NULL))
++ ((void)(HostSys::Munmap((uptr)(ptr), size), (ptr) = 0))
+
+ extern void InitCPUTicks();
+ extern u64 GetTickFrequency();
diff --git a/emulators/libretro-pcsx2/files/patch-pcsx2_SPU2_spu2.cpp b/emulators/libretro-pcsx2/files/patch-pcsx2_SPU2_spu2.cpp
new file mode 100644
index 000000000000..5eba4c5b24db
--- /dev/null
+++ b/emulators/libretro-pcsx2/files/patch-pcsx2_SPU2_spu2.cpp
@@ -0,0 +1,14 @@
+--- pcsx2/SPU2/spu2.cpp.orig 2020-10-29 23:31:05 UTC
++++ pcsx2/SPU2/spu2.cpp
+@@ -17,7 +17,10 @@
+ #include "Global.h"
+ #include "spu2.h"
+ #include "Dma.h"
+-#ifdef __linux__
++#ifdef __BSD__
++#include "Linux/Dialogs.h"
++#include "Linux/Config.h"
++#elif defined(__linux__)
+ #include "Linux/Dialogs.h"
+ #include "Linux/Config.h"
+ #elif defined(_WIN32)
diff --git a/emulators/libretro-pcsx2/pkg-descr b/emulators/libretro-pcsx2/pkg-descr
new file mode 100644
index 000000000000..81a1235957f0
--- /dev/null
+++ b/emulators/libretro-pcsx2/pkg-descr
@@ -0,0 +1,9 @@
+Standalone port of pcsx2 to libretro.
+
+PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its
+purpose is to emulate the PS2's hardware, using a combination of MIPS
+CPU Interpreters, Recompilers and a Virtual Machine which manages
+hardware states and PS2 system memory. This allows you to play PS2
+games on your PC, with many additional features and benefits.
+
+WWW: https://github.com/libretro/pcsx2