Steam Input as the primary guest-input path (optional, SDK-gated)
Add SteamInputSource: initializes SteamAPI + Steam Input, loads a bundled action manifest via SetInputActionManifestFilePath (no partner-backend config needed), and reads the GameControls action set into CoopPadState -- falling back to XInput per slot, and to pure XInput if Steam isn't available, so the host always runs. Enabled automatically when the Steamworks SDK is vendored at third_party/steamworks_sdk/ (auto-detected by CMake; gitignored and never committed -- the build is XInput-only without it). Stages steam_api64.dll + the manifest next to the host and builds coop_steam_input_probe (a console smoke test). Verified: the probe initializes against the live Steam client and enumerates controllers; the host degrades gracefully when launched standalone. All 5 tests pass. Reading actual controller state needs a pad bound through Steam Input for the running (donor) appid, which XInput otherwise covers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -23,9 +23,31 @@
|
||||
#include "log_panel.hpp"
|
||||
#include "ui/app_chrome.hpp"
|
||||
|
||||
#ifdef COOP_WITH_STEAM
|
||||
#include <string>
|
||||
|
||||
#include "input/steam_input_source.hpp"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#ifdef COOP_WITH_STEAM
|
||||
// Absolute path to the bundled Steam Input action manifest (next to the exe).
|
||||
std::string steam_manifest_path()
|
||||
{
|
||||
char buffer[MAX_PATH] = {};
|
||||
const DWORD len = GetModuleFileNameA(nullptr, buffer, MAX_PATH);
|
||||
std::string path(buffer, len);
|
||||
const std::size_t slash = path.find_last_of("\\/");
|
||||
if (slash != std::string::npos)
|
||||
{
|
||||
path.resize(slash + 1);
|
||||
}
|
||||
return path + "steam_input_actions.vdf";
|
||||
}
|
||||
#endif
|
||||
|
||||
// When the overlay is hidden, briefly show a fading hint so the operator can find
|
||||
// the way back. The window is borderless and non-interactive so it never steals a
|
||||
// click or a frame from the mirror underneath.
|
||||
@@ -64,7 +86,18 @@ int run()
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto input = std::make_unique<coop::XInputSource>();
|
||||
// Steam Input is the plan's primary guest-input path (it falls back to XInput
|
||||
// per slot, and to pure XInput if Steam isn't available). When the host is built
|
||||
// without the Steamworks SDK, use XInput directly.
|
||||
#ifdef COOP_WITH_STEAM
|
||||
std::unique_ptr<coop::InputSource> input = [] {
|
||||
auto steam = std::make_unique<coop::SteamInputSource>();
|
||||
steam->init(steam_manifest_path());
|
||||
return steam;
|
||||
}();
|
||||
#else
|
||||
std::unique_ptr<coop::InputSource> input = std::make_unique<coop::XInputSource>();
|
||||
#endif
|
||||
coop::ControllersPanel controllers;
|
||||
coop::InjectionPanel injection;
|
||||
coop::AudioPanel audio;
|
||||
|
||||
Reference in New Issue
Block a user