Files
CoopAllTheThings/CMakeLists.txt
BlackMark e370c8dcc5 Phase 1a: input forwarding via DLL injection + XInput hook
The host can now inject coop_hook.dll into a running game and forward
controller state to it over shared memory, so the game reads the host's
(eventually the guest's) input and nothing else.

- hook/: coop_hook.dll. DllMain spawns a worker that opens the shared-memory
  channel (named by the game's pid) and installs SafetyHook inline hooks on
  XInputGetState/GetStateEx/GetCapabilities/SetState. Detours synthesize state
  from shared memory; unmanaged slots report disconnected, hiding physical pads.
- host/: process picker (Toolhelp32), CreateRemoteThread(LoadLibraryW) injector
  with an IsWow64Process2 bitness guard, IPC server publishing pads each frame,
  and an ImGui Injection panel wiring it together.
- tests/: hook_selftest exercises the IPC seqlock + hook detours in-process
  (no game/controller needed); passes.

Build: SafetyHook wired in (COOP_BUILD_HOOK=ON), Zydis via FetchContent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 23:21:20 +02:00

44 lines
1.4 KiB
CMake

cmake_minimum_required(VERSION 3.21)
project(CoopAllTheThings
VERSION 0.0.1
DESCRIPTION "Steam Remote Play Together for any XInput game"
LANGUAGES CXX)
if(NOT WIN32)
message(FATAL_ERROR "CoopAllTheThings targets Windows only.")
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Single output dir keeps the donor-launch / inject workflow simple: host exe and
# hook dll land next to each other under /bin (already in .gitignore).
set(COOP_OUTPUT_DIR "${CMAKE_SOURCE_DIR}/bin/$<CONFIG>")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${COOP_OUTPUT_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${COOP_OUTPUT_DIR}")
if(MSVC)
add_compile_options(/W4 /permissive- /Zc:__cplusplus /utf-8 /MP)
add_compile_definitions(UNICODE _UNICODE WIN32_LEAN_AND_MEAN NOMINMAX)
endif()
add_subdirectory(third_party)
add_subdirectory(common)
add_subdirectory(host)
# The injected hook DLL pulls in SafetyHook, which fetches Zydis via FetchContent
# at configure time (allowed for transitive deps).
option(COOP_BUILD_HOOK "Build the injected game-side hook DLL" ON)
if(COOP_BUILD_HOOK)
# SafetyHook's own tests/examples/docs are noise for us.
set(SAFETYHOOK_BUILD_TEST OFF CACHE BOOL "" FORCE)
set(SAFETYHOOK_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(SAFETYHOOK_BUILD_DOCS OFF CACHE BOOL "" FORCE)
add_subdirectory(third_party/safetyhook)
add_subdirectory(hook)
enable_testing()
add_subdirectory(tests)
endif()