diff --git a/CMakeLists.txt b/CMakeLists.txt index c705dd1e5c..a4bd368105 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ if(APPLE) #list(APPEND LIBS hidapi) elseif(CMAKE_SYSTEM MATCHES "Linux") add_subdirectory(3rdparty/hidapi/linux EXCLUDE_FROM_ALL) -elseif(MSVC) +elseif(WIN32) add_subdirectory(3rdparty/hidapi/windows EXCLUDE_FROM_ALL) else() add_subdirectory(3rdparty/hidapi/libusb EXCLUDE_FROM_ALL) diff --git a/README.md b/README.md index 73ff99b90d..a8be3ac8f6 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,34 @@ If you're not using precompiled libs, build the projects in *__BUILD_BEFORE* fol `Build > Build Solution` +## Building on Windows (MinGW): + +1) Install packages +- `pacman -S base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-yasm mingw-w64-x86_64-python2 mingw-w64-x86_64-ntldd-git mingw-w64-x86_64-qt5 mingw-w64-x86_64-openal mingw-w64-x86_64-glew git` +2) Clone repository +- `git clone https://github.com/RPCS3/rpcs3.git` +3) Update submodules +- `cd rpcs3` +- `git submodule update --init` +- `cd ..` +4) Configure and compile rpcs3 +- `mkdir rpcs3_build && cd rpcs3_build` +- `cmake -G "MSYS Makefiles" -DCMAKE_MAKE_PROGRAM=mingw32-make ../rpcs3/` +- `mingw32-make.exe GitVersion && mingw32-make.exe discord-rpc` +- If you use ```-DUSE_SYSTEM_FFMPEG=OFF```, run `mingw32-make ffmpeg-mingw` +5) Build rpcs3 +- Run `mingw32-make` or `mingw32-make -jX` where X is your CPU cores. +6) Copy dependencies +- `cd ./bin` +- `for l in $(ntldd.exe -R rpcs3.exe|grep mingw64|sed -e 's/^[ \t]*//'|cut -d' ' -f3);do cp $l .;done` +7) Copy qt plugins +- `mkdir -p ./qt/plugins/{bearer,imageformats,platforms,styles}` +- `cp /mingw64/share/qt5/plugins/bearer/qgenericbearer.dll ./qt/plugins/bearer/` +- `cp /mingw64/share/qt5/plugins/imageformats/{qgif.dll,qicns.dll,qico.dll,qjpeg.dll,qtga.dll,qtiff.dll,qwbmp.dll,qwebp.dll} ./qt/plugins/imageformats/` +- `cp /mingw64/share/qt5/plugins/platforms/qwindows.dll ./qt/plugins/platforms/` +- `cp /mingw64/share/qt5/plugins/styles/qwindowsvistastyle.dll ./qt/plugins/styles/` +8) Run RPCS3 with `./rpcs3` + ## Building on Linux & Mac OS: diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index ebf885d2d7..3260dce4bf 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -4,6 +4,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules") set(RES_FILES "") set(CMAKE_CXX_STANDARD 17) include(CheckCXXCompilerFlag) +include(ExternalProject) # Qt section find_package(Qt5 5.10 COMPONENTS Widgets Network Qml) @@ -205,6 +206,10 @@ if(NOT WITHOUT_LLVM) option(LLVM_INCLUDE_UTILS OFF) option(WITH_POLLY OFF) + if(WIN32 AND NOT MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_FORMAT_MACROS=1") + endif() + # LLVM needs to be built out-of-tree add_subdirectory(../llvm ../llvm_build EXCLUDE_FROM_ALL) set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/../llvm_build/lib/cmake/llvm/") @@ -283,7 +288,31 @@ if(USE_SYSTEM_FFMPEG) include_directories("${FFMPEG_INCLUDE_DIR}") else() message("-- RPCS3: using builtin ffmpeg") - include_directories("${RPCS3_SRC_DIR}/../3rdparty/ffmpeg/${PLATFORM_ARCH}/include") + if(MSVC OR NOT WIN32) + include_directories("${RPCS3_SRC_DIR}/../3rdparty/ffmpeg/${PLATFORM_ARCH}/include") + link_directories("${RPCS3_SRC_DIR}/../3rdparty/ffmpeg/${PLATFORM_ARCH}/lib") + else() + ExternalProject_Add(ffmpeg-mingw + DOWNLOAD_COMMAND "" + SOURCE_DIR /e/src/rpcs3/3rdparty/ffmpeg + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/ffmpeg + CONFIGURE_COMMAND /e/src/rpcs3/3rdparty/ffmpeg/configure --prefix=./Windows/x86_64 --arch=x86_64 --disable-avdevice --disable-programs --disable-avfilter --disable-postproc --disable-doc --disable-pthreads --enable-w32threads --disable-network --disable-everything --disable-encoders --disable-muxers --disable-hwaccels --disable-parsers --disable-protocols --enable-dxva2 --enable-static --disable-shared --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=atrac3 --enable-decoder=atrac3p --enable-decoder=mp3 --enable-decoder=pcm_s16le --enable-decoder=pcm_s8 --enable-decoder=h264 --enable-decoder=mpeg4 --enable-decoder=mpeg2video --enable-decoder=mjpeg --enable-decoder=mjpegb --enable-encoder=pcm_s16le --enable-encoder=ffv1 --enable-encoder=mpeg4 --enable-parser=h264 --enable-parser=mpeg4video --enable-parser=mpegaudio --enable-parser=mpegvideo --enable-parser=mjpeg --enable-parser=aac --enable-parser=aac_latm --enable-muxer=avi --enable-demuxer=h264 --enable-demuxer=m4v --enable-demuxer=mp3 --enable-demuxer=mpegvideo --enable-demuxer=mpegps --enable-demuxer=mjpeg --enable-demuxer=avi --enable-demuxer=aac --enable-demuxer=pmp --enable-demuxer=oma --enable-demuxer=pcm_s16le --enable-demuxer=pcm_s8 --enable-demuxer=wav --enable-hwaccel=h264_dxva2 --enable-indev=dshow --enable-protocol=file + BUILD_COMMAND make -j 4 + INSTALL_COMMAND make install + ) + include_directories("${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/${PLATFORM_ARCH}/include") + link_directories("${CMAKE_CURRENT_BINARY_DIR}/ffmpeg/${PLATFORM_ARCH}/lib") + endif() +endif() + +# Build discord-rpc for mingw +if(WIN32 AND NOT MSVC) + ExternalProject_Add(discord-rpc + GIT_REPOSITORY https://github.com/discordapp/discord-rpc + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/discord-rpc + INSTALL_COMMAND "" + ) + link_directories(rpcs3 "${CMAKE_CURRENT_BINARY_DIR}/discord-rpc/src/") endif() include_directories( @@ -326,12 +355,6 @@ endif() link_directories("${RPCS3_SRC_DIR}/../3rdparty/minidx12/") -if(NOT USE_SYSTEM_FFMPEG) - if(MSVC OR NOT WIN32) - link_directories("${RPCS3_SRC_DIR}/../3rdparty/ffmpeg/${PLATFORM_ARCH}/lib") - endif() -endif() - get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) foreach (dir ${dirs}) message(STATUS "dir='${dir}'") @@ -406,15 +429,15 @@ target_include_directories(rpcs3 PUBLIC ${ZLIB_INCLUDE_DIRS}) target_link_libraries(rpcs3 ${ZLIB_LIBRARIES}) if(WIN32) - target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib gdi32.lib setupapi.lib hidapi-hid Shlwapi.lib) - if(NOT MSVC) - target_link_libraries(rpcs3 ${OPENGL_LIBRARIES} opengl32.lib glu32.lib) + target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib gdi32.lib Shlwapi.lib) + if(MSVC) + target_link_libraries(rpcs3 dxgi.lib d2d1.lib dwrite.lib hidapi-hid setupapi.lib) + # Link Discord Rich Presence + target_link_libraries(rpcs3 "${RPCS3_SRC_DIR}/../3rdparty/discord-rpc/lib/discord-rpc.lib") else() - target_link_libraries(rpcs3 dxgi.lib d2d1.lib dwrite.lib) + target_link_libraries(rpcs3 ${OPENGL_LIBRARIES} opengl32.lib glu32.lib hidapi-hid libsetupapi.a libdiscord-rpc.a) endif() target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swscale.lib png_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS}) - # Link Discord Rich Presence - target_link_libraries(rpcs3 "${RPCS3_SRC_DIR}/../3rdparty/discord-rpc/lib/discord-rpc.lib") else() target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${OPENGL_LIBRARIES}) if(APPLE) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 1eed52c461..151010c3b7 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -99,10 +99,8 @@ void fmt_class_string::format(std::string& out, u64 arg) case pad_handler::null: return "Null"; case pad_handler::keyboard: return "Keyboard"; case pad_handler::ds4: return "DualShock 4"; -#ifdef _MSC_VER - case pad_handler::xinput: return "XInput"; -#endif #ifdef _WIN32 + case pad_handler::xinput: return "XInput"; case pad_handler::mm: return "MMJoystick"; #endif #ifdef HAVE_LIBEVDEV diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 0efd37e196..c61da9cd62 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -62,10 +62,8 @@ enum class pad_handler null, keyboard, ds4, -#ifdef _MSC_VER - xinput, -#endif #ifdef _WIN32 + xinput, mm, #endif #ifdef HAVE_LIBEVDEV diff --git a/rpcs3/mm_joystick_handler.cpp b/rpcs3/mm_joystick_handler.cpp index 73aa21ac50..b126904e71 100644 --- a/rpcs3/mm_joystick_handler.cpp +++ b/rpcs3/mm_joystick_handler.cpp @@ -493,8 +493,8 @@ std::unordered_map mm_joystick_handler::GetButtonValues(const JOYINFOE }; float rad = static_cast(js_info.dwPOV / 100 * acos(-1) / 180); - emplacePOVs(std::cosf(rad) * 255.0f, JOY_POVBACKWARD, JOY_POVFORWARD); - emplacePOVs(std::sinf(rad) * 255.0f, JOY_POVLEFT, JOY_POVRIGHT); + emplacePOVs(cosf(rad) * 255.0f, JOY_POVBACKWARD, JOY_POVFORWARD); + emplacePOVs(sinf(rad) * 255.0f, JOY_POVLEFT, JOY_POVRIGHT); } } else if (js_caps.wCaps & JOYCAPS_POV4DIR) diff --git a/rpcs3/pad_thread.cpp b/rpcs3/pad_thread.cpp index 853f05c334..4b14131327 100644 --- a/rpcs3/pad_thread.cpp +++ b/rpcs3/pad_thread.cpp @@ -60,12 +60,10 @@ void pad_thread::Init(const u32 max_connect) case pad_handler::ds4: cur_pad_handler = std::make_shared(); break; -#ifdef _MSC_VER +#ifdef _WIN32 case pad_handler::xinput: cur_pad_handler = std::make_shared(); break; -#endif -#ifdef _WIN32 case pad_handler::mm: cur_pad_handler = std::make_shared(); break; diff --git a/rpcs3/rpcs3_app.cpp b/rpcs3/rpcs3_app.cpp index a54bf79ded..559acdb38d 100644 --- a/rpcs3/rpcs3_app.cpp +++ b/rpcs3/rpcs3_app.cpp @@ -24,10 +24,8 @@ #include "Emu/Io/Null/NullPadHandler.h" #include "keyboard_pad_handler.h" #include "ds4_pad_handler.h" -#ifdef _MSC_VER -#include "xinput_pad_handler.h" -#endif #ifdef _WIN32 +#include "xinput_pad_handler.h" #include "mm_joystick_handler.h" #endif #ifdef HAVE_LIBEVDEV diff --git a/rpcs3/rpcs3qt/gl_gs_frame.cpp b/rpcs3/rpcs3qt/gl_gs_frame.cpp index 14b479fa3b..a43e6d2dee 100644 --- a/rpcs3/rpcs3qt/gl_gs_frame.cpp +++ b/rpcs3/rpcs3qt/gl_gs_frame.cpp @@ -85,9 +85,7 @@ void gl_gs_frame::delete_context(draw_context_t ctx) auto gl_ctx = (GLContext*)ctx; gl_ctx->handle->doneCurrent(); -#ifndef _WIN32 - delete gl_ctx->handle; -#else +#ifdef _MSC_VER //AMD driver crashes when executing wglDeleteContext //Catch with SEH __try @@ -98,6 +96,8 @@ void gl_gs_frame::delete_context(draw_context_t ctx) { LOG_FATAL(RSX, "Your graphics driver just crashed whilst cleaning up. All consumed VRAM should have been released, but you may want to restart the emulator just in case"); } +#else + delete gl_ctx->handle; #endif if (gl_ctx->owner) diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index ac959f02ae..9f414ea3be 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -16,8 +16,6 @@ #include "ds4_pad_handler.h" #ifdef _WIN32 #include "xinput_pad_handler.h" -#endif -#ifdef _MSC_VER #include "mm_joystick_handler.h" #endif #ifdef HAVE_LIBEVDEV @@ -673,12 +671,10 @@ std::shared_ptr pad_settings_dialog::GetHandler(pad_handler type case pad_handler::ds4: ret_handler = std::make_unique(); break; -#ifdef _MSC_VER +#ifdef _WIN32 case pad_handler::xinput: ret_handler = std::make_unique(); break; -#endif -#ifdef _WIN32 case pad_handler::mm: ret_handler = std::make_unique(); break; @@ -720,7 +716,7 @@ void pad_settings_dialog::ChangeInputType() // Refill the device combobox with currently available devices switch (m_handler->m_type) { -#ifdef _MSC_VER +#ifdef _WIN32 case pad_handler::xinput: { const QString name_string = qstr(m_handler->name_string()); @@ -819,12 +815,10 @@ void pad_settings_dialog::ChangeProfile() case pad_handler::ds4: ((ds4_pad_handler*)m_handler.get())->init_config(&m_handler_cfg, cfg_name); break; -#ifdef _MSC_VER +#ifdef _WIN32 case pad_handler::xinput: ((xinput_pad_handler*)m_handler.get())->init_config(&m_handler_cfg, cfg_name); break; -#endif -#ifdef _WIN32 case pad_handler::mm: ((mm_joystick_handler*)m_handler.get())->init_config(&m_handler_cfg, cfg_name); break; diff --git a/rpcs3/xinput_pad_handler.cpp b/rpcs3/xinput_pad_handler.cpp index c3c024899b..64dad106a1 100644 --- a/rpcs3/xinput_pad_handler.cpp +++ b/rpcs3/xinput_pad_handler.cpp @@ -1,5 +1,5 @@ -#ifdef _MSC_VER +#ifdef _WIN32 #include "xinput_pad_handler.h" xinput_pad_handler::xinput_pad_handler() : PadHandlerBase(pad_handler::xinput)