diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 5f5ba4d..a5b031a --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,55 +1,100 @@ -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.5) project(koku-xinput-wine) -if (NOT CMAKE_C_COMPILER MATCHES "i686-w64-mingw32-gcc" - AND NOT CMAKE_C_COMPILER MATCHES "x86_64-w64-mingw32-gcc") - find_program(X86_64_MINGW64_GCC x86_64-w64-mingw32-gcc) - if (X86_64_MINGW64_GCC) - execute_process( - COMMAND ${CMAKE_COMMAND} - -B${CMAKE_BINARY_DIR}/x86_64-w64-mingw32 - -H${CMAKE_SOURCE_DIR} - -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/Toolchain-Windows-x86_64.cmake) - add_custom_target(x86_64-w64-mingw32-tests ALL - COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/x86_64-w64-mingw32) - endif() +set(USING_CROSS_COMPILER OFF) +if (CMAKE_C_COMPILER MATCHES "i686-w64-mingw32-gcc" OR + CMAKE_C_COMPILER MATCHES "x86_64-w64-mingw32-gcc") + set(USING_CROSS_COMPILER ON) +endif() - find_program(I686_MINGW64_GCC i686-w64-mingw32-gcc) - if (I686_MINGW64_GCC) - execute_process( - COMMAND ${CMAKE_COMMAND} - -B${CMAKE_BINARY_DIR}/i686-w64-mingw32 - -H${CMAKE_SOURCE_DIR} - -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/Toolchain-Windows-i686.cmake) - add_custom_target(i686-w64-mingw32-tests ALL - COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/i686-w64-mingw32) - endif() +set(USING_64BIT_COMPILER OFF) +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(USING_64BIT_COMPILER ON) +endif() + +option(BUILD_LIBRARY "Build main library" ON) +option(BUILD_32BIT_LIBRARY "Build main library for 32-bit wine" ON) +option(BUILD_64BIT_LIBRARY "Build main library for 64-bit wine" ${USING_64BIT_COMPILER}) +option(BUILD_TESTS "Build test executables" ON) + +if (BUILD_LIBRARY) + if (USING_CROSS_COMPILER) + message(WARNING "Called with cross-compiler; skipping main library") + elseif (NOT BUILD_32BIT_LIBRARY AND NOT BUILD_64BIT_LIBRARY) + message(WARNING "No architectures enabled; skipping main library") + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(SDL2 REQUIRED sdl2) + + find_path(WINE_INCLUDE_DIR windows.h + HINTS ${WINEROOT}/include ${WINE_ROOT}/include ${WINE_INCLUDEDIR} + PATHS /opt/wine-staging/include + PATH_SUFFIXES wine-development/windows wine/windows) + if (WINE_INCLUDE_DIR) + message(STATUS "Found wine headers: ${WINE_INCLUDE_DIR}") + else() + message(FATAL_ERROR "Couldn't find wine headers!") + endif() - option(BUILD_M32 "Build library in 32Bit mode" ON) - if(BUILD_M32) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") - add_compile_options(-m32) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_SHARED_LIBRARY_PREFIX "") + + set(KOKU_SOURCE_FILES main.cpp xinput.cpp device.cpp) + set(KOKU_INCLUDE_DIRS ${WINE_INCLUDE_DIR} ${SDL2_INCLUDE_DIR}) + set(KOKU_LINK_LIBRARIES ${SDL2_LIBRARIES}) + set(KOKU_COMPILE_OPTIONS -Wall -Wextra + -Wno-attributes -Wno-ignored-attributes -Wno-subobject-linkage + -Wno-unused-parameter -Wno-unused-variable) + + if (BUILD_32BIT_LIBRARY) + add_library(koku-xinput-wine SHARED ${KOKU_SOURCE_FILES}) + target_include_directories(koku-xinput-wine PRIVATE ${KOKU_INCLUDE_DIRS}) + target_link_libraries(koku-xinput-wine PRIVATE -m32 ${KOKU_LINK_LIBRARIES}) + target_compile_options(koku-xinput-wine PRIVATE -m32 ${KOKU_COMPILE_OPTIONS}) + endif() + + if (BUILD_64BIT_LIBRARY) + add_library(koku-xinput-wine64 SHARED ${KOKU_SOURCE_FILES}) + target_include_directories(koku-xinput-wine64 PRIVATE ${KOKU_INCLUDE_DIRS}) + target_link_libraries(koku-xinput-wine64 PRIVATE ${KOKU_LINK_LIBRARIES}) + target_compile_options(koku-xinput-wine64 PRIVATE ${KOKU_COMPILE_OPTIONS}) + endif() endif() +endif() + +if (BUILD_TESTS) + if (USING_CROSS_COMPILER) + add_executable(ditest test/ditest.cpp) + target_link_libraries(ditest PRIVATE -static -static-libgcc + dinput dinput8 dxguid user32 ole32 oleaut32) + add_executable(xitest test/xitest.cpp) + target_link_libraries(xitest PRIVATE -static -static-libgcc + xinput) + else() + find_program(I686_MINGW64_GCC i686-w64-mingw32-gcc) + if (I686_MINGW64_GCC) + execute_process( + COMMAND ${CMAKE_COMMAND} + -B${CMAKE_BINARY_DIR}/i686-w64-mingw32 + -H${CMAKE_SOURCE_DIR} + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/Toolchain-Windows-i686.cmake) + add_custom_target(i686-w64-mingw32-tests ALL + COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/i686-w64-mingw32) + else() + message(WARNING "No 32-bit cross-compiler; skipping 32-bit tests") + endif() - add_library(koku-xinput-wine SHARED main.h main.cpp xinput.cpp - device.cpp jumper.h) - set_target_properties(koku-xinput-wine PROPERTIES CXX_STANDARD 11 PREFIX "") - target_include_directories(koku-xinput-wine PRIVATE - /opt/wine-staging/include/wine/windows - /usr/include/wine-development/windows - /usr/include/wine/windows) - target_compile_options(koku-xinput-wine PRIVATE -Wno-ignored-attributes - -Wno-subobject-linkage) - - find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL2 REQUIRED sdl2) - target_include_directories(koku-xinput-wine PRIVATE ${SDL2_INCLUDE_DIR}) - target_link_libraries(koku-xinput-wine PRIVATE ${SDL2_LIBRARIES}) -else() - add_executable(ditest test/ditest.cpp) - target_link_libraries(ditest PRIVATE -static -static-libgcc - dinput dinput8 dxguid user32 ole32 oleaut32) - add_executable(xitest test/xitest.cpp) - target_link_libraries(xitest PRIVATE -static -static-libgcc - xinput) + find_program(X86_64_MINGW64_GCC x86_64-w64-mingw32-gcc) + if (X86_64_MINGW64_GCC) + execute_process( + COMMAND ${CMAKE_COMMAND} + -B${CMAKE_BINARY_DIR}/x86_64-w64-mingw32 + -H${CMAKE_SOURCE_DIR} + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/Toolchain-Windows-x86_64.cmake) + add_custom_target(x86_64-w64-mingw32-tests ALL + COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/x86_64-w64-mingw32) + else() + message(WARNING "No 64-bit cross-compiler; skipping 64-bit tests") + endif() + endif() endif() diff --git a/README.md b/README.md index 0b6b706..ea10afc 100644 --- a/README.md +++ b/README.md @@ -6,34 +6,56 @@ Modified to use SDL2 gamepad mappings. Install --------------------- -If you are on 64Bit you will need 32Bit tool-chain (multilib) - -It depens on SDL2-Librarys. - - [user@host code]$git clone https://github.com/KoKuToru/koku-xinput-wine.git - [user@host code]$cd koku-xinput-wine - [user&host code]$cmake . - [user@host code]$make - -After this there will be a 'koku-xinput-wine.so' in the folder. - -64-Bit Version ---------------------- +If you are on 64Bit you will need a 32Bit tool-chain (multilib). + +You will also need SDL2 libraries and development headers installed. On 64Bit systems you will need both 32Bit and 64Bit SDL2 libraries. -Same as normal just initialize with `cmake -DBUILD_M32=OFF .` + [user@host code]$ git clone https://github.com/KoKuToru/koku-xinput-wine.git + [user@host code]$ cd koku-xinput-wine + [user&host code]$ cmake . + [user@host code]$ make + +After this there will be a 'koku-xinput-wine.so' in the folder, and on 64Bit systems there will also be 'koku-xinput-wine64.so'. Usage --------------------- - [user@host game]$export LD_PRELOAD=/lib-path/koku-xinput-wine.so - [user@host game]$wine game.exe - +To hook a 32Bit application: + + [user@host game]$ export LD_PRELOAD=/lib-path/koku-xinput-wine.so + [user@host game]$ wine game.exe + +To hook a 64Bit application: + + [user@host game]$ export LD_PRELOAD=/lib-path/koku-xinput-wine64.so + [user@host game]$ wine game64.exe + +To hook both 32Bit and 64Bit applications (the correct hook will be automatically selected): + + [user@host game]$ export LD_PRELOAD="/lib-path/koku-xinput-wine.so /lib-path/koku-xinput-wine64.so" + [user@host game]$ wine game.exe + [user@host game]$ wine game64.exe + Simple Elegance, without patching wine. Of course it would be wiser to put this code into wine.. Config --------------------- -You can add sdl2 gamepad mappings by putting them in file named "gamecontrollerdb.txt" and place it next to your game executable, or via the *SDL_GAMECONTROLLERCONFIG* environment variable. +You can add SDL2 gamepad mappings by putting them in file named "gamecontrollerdb.txt" and place it next to your game executable, or via the *SDL_GAMECONTROLLERCONFIG* environment variable. + +You can find a premade gamecontrollerdb.txt with a lot of mappings [here](https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt). + +These mappings are not needed if you're already using a standard Xbox controller. + +Troubleshooting +--------------------- + +When the library is properly loaded, you should notice two quick rumbles sent to the controller. + +When running on a 64bit system, you may see errors like this: + + ERROR: ld.so: object '/lib-path/koku-xinput-wine.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored. + ERROR: ld.so: object '/lib-path/koku-xinput-wine64.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS64): ignored. -You can find a premade gamecontrollerdb.txt with a lot of mappings [here](https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt) +These messages don't necessarily mean there is a problem. They're just saying that the 64Bit hooks aren't installed into 32Bit applications and vica-versa. If you're seeing these errors and not getting the "welcome" rumbles, double-check that you're preloading the correct library. diff --git a/device.cpp b/device.cpp index 3cc5826..0c1ec87 100644 --- a/device.cpp +++ b/device.cpp @@ -4,8 +4,8 @@ #define CINTERFACE #define INITGUID -#include "objbase.h" -#include "wbemcli.h" +#include +#include namespace koku { unsigned short wine_gamepad[] = {'V', 'I', 'D', '_', '3', 'E', 'D', '9', diff --git a/jumper.h b/jumper.h index bf8dba2..3b39d9e 100644 --- a/jumper.h +++ b/jumper.h @@ -16,10 +16,10 @@ template struct jumper { F *dst = nullptr; #if UINTPTR_MAX == UINT64_MAX - std::array header = {0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0}; + std::array header = {{0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0}}; #elif UINTPTR_MAX == UINT32_MAX - std::array header = {0xe9, 0x00, 0x00, 0x00, 0x00}; + std::array header = {{0xe9, 0x00, 0x00, 0x00, 0x00}}; #else #error "Unsupported architecture" #endif diff --git a/xinput.cpp b/xinput.cpp old mode 100755 new mode 100644