diff --git a/CMakeLists.txt b/CMakeLists.txt index a90d956478..fb6edd66e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,19 +56,3 @@ else() add_subdirectory(3rdparty/hidapi/libusb) #list(APPEND LIBS hidapi-libusb) endif() - -# Linux installation - -if(UNIX AND NOT APPLE) -# Install the application icon and menu item -install(FILES rpcs3/rpcs3.svg - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps) -install(FILES rpcs3/rpcs3.png - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps) -install(FILES rpcs3/rpcs3.desktop - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) -# Install the binary -install(FILES "${PROJECT_BINARY_DIR}/bin/rpcs3" - DESTINATION ${CMAKE_INSTALL_PREFIX}/bin - PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # i.e. 755 -endif() diff --git a/Utilities/File.cpp b/Utilities/File.cpp index d712d397ad..4abdd90c36 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -110,10 +110,12 @@ static fs::error to_error(DWORD e) #include #include -#if defined(__APPLE__) || defined(__FreeBSD__) +#if defined(__APPLE__) #include #include -#else +#elif defined(__DragonFly__) || defined(__FreeBSD__) +#include // sendfile +#elif defined(__linux__) || defined(__sun) #include #endif @@ -578,14 +580,20 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit } // Here we use kernel-space copying for performance reasons -#if defined(__APPLE__) || defined(__FreeBSD__) - // fcopyfile works on FreeBSD and OS X 10.5+ +#if defined(__APPLE__) + // fcopyfile works on OS X 10.5+ if (::fcopyfile(input, output, 0, COPYFILE_ALL)) -#else +#elif defined(__DragonFly__) || defined(__FreeBSD__) + if (::sendfile(input, output, 0, 0, NULL, NULL, 0)) +#elif defined(__linux__) || defined(__sun) // sendfile will work with non-socket output (i.e. regular file) on Linux 2.6.33+ off_t bytes_copied = 0; struct ::stat fileinfo = { 0 }; if (::fstat(input, &fileinfo) || ::sendfile(output, input, &bytes_copied, fileinfo.st_size)) +#else // NetBSD, OpenBSD, etc. + fmt::throw_exception("fs::copy_file() isn't implemented for this platform.\nFrom: %s\nTo: %s", from, to); + errno = 0; + if (true) #endif { const int err = errno; diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index d66ab76182..7043e6f8ec 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -756,6 +756,90 @@ uint64_t* darwin_x64reg(x64_context *context, int reg) } } +#elif defined(__DragonFly__) || defined(__FreeBSD__) + +#define X64REG(context, reg) (freebsd_x64reg(context, reg)) +#ifdef __DragonFly__ +# define XMMREG(context, reg) (reinterpret_cast(((union savefpu*)(context)->uc_mcontext.mc_fpregs)->sv_xmm.sv_xmm[reg])) +#else +# define XMMREG(context, reg) (reinterpret_cast(((struct savefpu*)(context)->uc_mcontext.mc_fpstate)->sv_xmm[reg])) +#endif +#define EFLAGS(context) ((context)->uc_mcontext.mc_rflags) + +register_t* freebsd_x64reg(x64_context *context, int reg) +{ + auto *state = &context->uc_mcontext; + switch(reg) + { + case 0: return &state->mc_rax; + case 1: return &state->mc_rcx; + case 2: return &state->mc_rdx; + case 3: return &state->mc_rbx; + case 4: return &state->mc_rsp; + case 5: return &state->mc_rbp; + case 6: return &state->mc_rsi; + case 7: return &state->mc_rdi; + case 8: return &state->mc_r8; + case 9: return &state->mc_r9; + case 10: return &state->mc_r10; + case 11: return &state->mc_r11; + case 12: return &state->mc_r12; + case 13: return &state->mc_r13; + case 14: return &state->mc_r14; + case 15: return &state->mc_r15; + case 16: return &state->mc_rip; + default: + LOG_ERROR(GENERAL, "Invalid register index: %d", reg); + return nullptr; + } +} + +#elif defined(__OpenBSD__) + +#define X64REG(context, reg) (openbsd_x64reg(context, reg)) +#define XMMREG(context, reg) (reinterpret_cast((context)->sc_fpstate->fx_xmm[reg])) +#define EFLAGS(context) ((context)->sc_rflags) + +long* openbsd_x64reg(x64_context *context, int reg) +{ + auto *state = &context->uc_mcontext; + switch(reg) + { + case 0: return &state->sc_rax; + case 1: return &state->sc_rcx; + case 2: return &state->sc_rdx; + case 3: return &state->sc_rbx; + case 4: return &state->sc_rsp; + case 5: return &state->sc_rbp; + case 6: return &state->sc_rsi; + case 7: return &state->sc_rdi; + case 8: return &state->sc_r8; + case 9: return &state->sc_r9; + case 10: return &state->sc_r10; + case 11: return &state->sc_r11; + case 12: return &state->sc_r12; + case 13: return &state->sc_r13; + case 14: return &state->sc_r14; + case 15: return &state->sc_r15; + case 16: return &state->sc_rip; + default: + LOG_ERROR(GENERAL, "Invalid register index: %d", reg); + return nullptr; + } +} + +#elif defined(__NetBSD__) + +static const decltype(_REG_RAX) reg_table[] = +{ + _REG_RAX, _REG_RCX, _REG_RDX, _REG_RBX, _REG_RSP, _REG_RBP, _REG_RSI, _REG_RDI, + _REG_R8, _REG_R9, _REG_R10, _REG_R11, _REG_R12, _REG_R13, _REG_R14, _REG_R15, _REG_RIP +}; + +#define X64REG(context, reg) (&(context)->uc_mcontext.__gregs[reg_table[reg]]) +#define XMM_sig(context, reg) (reinterpret_cast(((struct fxsave64*)(context)->uc_mcontext.__fpregs)->fx_xmm[reg])) +#define EFLAGS(context) ((context)->uc_mcontext.__gregs[_REG_RFL]) + #else static const decltype(REG_RAX) reg_table[] = @@ -765,7 +849,11 @@ static const decltype(REG_RAX) reg_table[] = }; #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) +#ifdef __sun +#define XMMREG(context, reg) (reinterpret_cast(&(context)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[reg_table[reg]])) +#else #define XMMREG(context, reg) (reinterpret_cast(&(context)->uc_mcontext.fpregs->_xmm[reg])) +#endif // __sun #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) #endif // __APPLE__ @@ -1364,6 +1452,12 @@ static void signal_handler(int sig, siginfo_t* info, void* uct) #ifdef __APPLE__ const bool is_writing = context->uc_mcontext->__es.__err & 0x2; +#elif defined(__DragonFly__) || defined(__FreeBSD__) + const bool is_writing = context->uc_mcontext.mc_err & 0x2; +#elif defined(__OpenBSD__) + const bool is_writing = context->sc_err & 0x2; +#elif defined(__NetBSD__) + const bool is_writing = context->uc_mcontext.__gregs[_REG_ERR] & 0x2; #else const bool is_writing = context->uc_mcontext.gregs[REG_ERR] & 0x2; #endif @@ -1464,7 +1558,7 @@ void thread_ctrl::start(const std::shared_ptr& ctrl, task_stack tas #endif // TODO: this is unsafe and must be duplicated in thread_ctrl::initialize - ctrl->m_thread = thread; + ctrl->m_thread = (uintptr_t)thread; } void thread_ctrl::initialize() @@ -1520,7 +1614,7 @@ void thread_ctrl::finalize(std::exception_ptr eptr) noexcept FILETIME ctime, etime, ktime, utime; GetThreadTimes(GetCurrentThread(), &ctime, &etime, &ktime, &utime); const u64 time = ((ktime.dwLowDateTime | (u64)ktime.dwHighDateTime << 32) + (utime.dwLowDateTime | (u64)utime.dwHighDateTime << 32)) * 100ull; -#elif __linux__ +#elif defined(RUSAGE_THREAD) const u64 cycles = 0; // Not supported struct ::rusage stats{}; ::getrusage(RUSAGE_THREAD, &stats); @@ -1653,7 +1747,7 @@ thread_ctrl::~thread_ctrl() #ifdef _WIN32 CloseHandle((HANDLE)m_thread.raw()); #else - pthread_detach(m_thread.raw()); + pthread_detach((pthread_t)m_thread.raw()); #endif } } diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index a186a7c373..be16ca5b3c 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -106,7 +106,7 @@ endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") #on some Linux distros shm_unlink and similar functions are in librt only set(ADDITIONAL_LIBS "rt" "X11" "asound") -elseif(UNIX OR NOT MSVC) +elseif(NOT MSVC AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG") #it seems like glibc includes the iconv functions we use but other libc #implementations like the one on OSX don't seem implement them set(ADDITIONAL_LIBS "iconv") @@ -284,6 +284,8 @@ else() add_executable(rpcs3 ${RPCS3_SRC} ${RES_FILES} resources.qrc) endif() +add_dependencies(rpcs3 GitVersion) + if(WIN32) target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib VKstatic.1 glslang OSDependent OGLCompiler SPIRV HLSL setupapi.lib hidapi-hid Shlwapi.lib) if(NOT MSVC) @@ -293,8 +295,13 @@ if(WIN32) endif() target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS}) else() - target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES} hidapi-hidraw udev) - target_link_libraries(rpcs3 -ldl -lpthread -lvulkan ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS}) + target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES}) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_link_libraries(rpcs3 hidapi-hidraw udev vulkan) + else() + target_link_libraries(rpcs3 hidapi-libusb usb) + endif() + target_link_libraries(rpcs3 ${CMAKE_DL_LIBS} -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS}) if (USE_SYSTEM_FFMPEG) link_libraries(${FFMPEG_LIBRARY_DIR}) target_link_libraries(rpcs3 libavformat.so libavcodec.so libavutil.so libswresample.so libswscale.so) @@ -322,3 +329,16 @@ target_link_libraries(rpcs3 ${RPCS3_QT_LIBS}) set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h") cotire(rpcs3) + +# Unix installation +if(UNIX AND NOT APPLE) + # Install the binary + install(TARGETS rpcs3 RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + # Install the application icon and menu item + install(FILES rpcs3.svg + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps) + install(FILES rpcs3.png + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps) + install(FILES rpcs3.desktop + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) +endif() diff --git a/rpcs3/Emu/Cell/Modules/sys_net.h b/rpcs3/Emu/Cell/Modules/sys_net.h index 3e269b1334..cc48931848 100644 --- a/rpcs3/Emu/Cell/Modules/sys_net.h +++ b/rpcs3/Emu/Cell/Modules/sys_net.h @@ -1,3 +1,8 @@ +#if defined(__FreeBSD__) +#include +#undef fds_bits +#endif + #pragma once namespace vm { using namespace ps3; } diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index 5a640f3bb7..fcdc5ed331 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -283,7 +283,7 @@ static void open_dir(const std::string& spath) std::replace(command.begin(), command.end(), '/', '\\'); #elif __APPLE__ std::string command = "open " + spath; -#elif __linux__ +#else std::string command = "xdg-open " + spath; #endif wxExecute(fmt::FromUTF8(command)); diff --git a/rpcs3/git-version.cmake b/rpcs3/git-version.cmake index a77a9ef5e0..603407fd73 100644 --- a/rpcs3/git-version.cmake +++ b/rpcs3/git-version.cmake @@ -3,7 +3,7 @@ set(GIT_VERSION "unknown") set(GIT_VERSION_UPDATE "1") find_package(Git) -if(GIT_FOUND) +if(GIT_FOUND AND EXISTS "${SOURCE_DIR}/../.git/") execute_process(COMMAND ${GIT_EXECUTABLE} rev-list HEAD --count WORKING_DIRECTORY ${SOURCE_DIR} RESULT_VARIABLE exit_code diff --git a/rpcs3/rpcs3_app.cpp b/rpcs3/rpcs3_app.cpp index b54e9f982f..281edb0636 100644 --- a/rpcs3/rpcs3_app.cpp +++ b/rpcs3/rpcs3_app.cpp @@ -37,7 +37,9 @@ #ifdef _MSC_VER #include "Emu/RSX/D3D12/D3D12GSRender.h" #endif +#if defined(_WIN32) || defined(__linux__) #include "Emu/RSX/VK/VKGSRender.h" +#endif #ifdef _WIN32 #include "Emu/Audio/XAudio2/XAudio2Thread.h" #endif @@ -163,7 +165,9 @@ void rpcs3_app::InitializeCallbacks() { case video_renderer::null: return std::make_shared(); case video_renderer::opengl: return std::make_shared(); +#if defined(_WIN32) || defined(__linux__) case video_renderer::vulkan: return std::make_shared(); +#endif #ifdef _MSC_VER case video_renderer::dx12: return std::make_shared(); #endif diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index f7aa3b6091..104f9a8392 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -480,7 +480,7 @@ static void open_dir(const std::string& spath) process->start("explorer", QStringList() << path); #elif __APPLE__ process->start("open", QStringList() << path); -#elif __linux__ +#else process->start("xdg-open", QStringList() << path); #endif } diff --git a/rpcs3/rpcs3qt/gl_gs_frame.cpp b/rpcs3/rpcs3qt/gl_gs_frame.cpp index 7bc86d90ee..390944e43e 100644 --- a/rpcs3/rpcs3qt/gl_gs_frame.cpp +++ b/rpcs3/rpcs3qt/gl_gs_frame.cpp @@ -33,7 +33,11 @@ void* gl_gs_frame::make_context() void gl_gs_frame::set_current(draw_context_t ctx) { - ((QOpenGLContext*)ctx.get())->makeCurrent(this); + if (!((QOpenGLContext*)ctx.get())->makeCurrent(this)) + { + create(); + ((QOpenGLContext*)ctx.get())->makeCurrent(this); + } } void gl_gs_frame::delete_context(void* ctx) diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index cc04f31d17..8a02e66330 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -111,10 +111,10 @@ void gs_frame::show() void* gs_frame::handle() const { -#ifdef __linux__ - return (void *)this->winId(); -#elif _WIN32 +#ifdef _WIN32 return (HWND) this->winId(); +#else + return (void *)this->winId(); #endif }