Files
CoopAllTheThings/tools/steam_input_probe/main.cpp
BlackMark edf2da69d8 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>
2026-06-20 11:51:58 +02:00

60 lines
1.6 KiB
C++

// coop_steam_input_probe -- console smoke test for SteamInputSource. Brings up
// Steam Input via the shipping host code (no GUI), prints whether it initialized,
// how many Steam controllers are connected, and a few polled snapshots, then
// exits. Needs Steam running and an appid context: either launch it under Steam,
// or drop a steam_appid.txt (e.g. "480") next to the exe. Built only when the
// Steamworks SDK is vendored.
#include <cstdio>
#include <windows.h>
#include "input/steam_input_source.hpp"
namespace
{
std::string 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";
}
} // namespace
int main()
{
coop::SteamInputSource src;
const bool ok = src.init(manifest_path());
std::printf("init=%d steam_active=%d backend=\"%s\"\n", ok ? 1 : 0, src.steam_active() ? 1 : 0,
src.name());
for (int frame = 0; frame < 20; ++frame)
{
src.poll();
Sleep(50);
}
std::printf("steam_controllers=%d\n", src.steam_controllers());
const auto& pads = src.pads();
for (std::uint32_t i = 0; i < coop::kMaxPads; ++i)
{
const coop::PadInfo& p = pads[i];
if (p.connected)
{
std::printf(" slot %u: source=\"%s\" buttons=0x%04X LX=%d LY=%d LT=%u RT=%u\n", i,
p.source.c_str(), p.state.buttons, p.state.thumb_lx, p.state.thumb_ly,
p.state.left_trigger, p.state.right_trigger);
}
}
src.shutdown();
std::printf("done.\n");
return 0;
}