Sunshine0.0.5917
Sunshine 0.0.5917
Self-hosted game stream host for Moonlight.
Loading...
Searching...
No Matches
input.cpp File Reference

Definitions for input handling on Windows. More...

#include <array>
#include <Windows.h>
#include <memory>
#include <thread>
#include <vector>
#include <libvirtualhid/license.hpp>
#include <ViGEm/Client.h>
#include "input.h"
#include "misc.h"
#include "src/config.h"
#include "src/globals.h"
#include "src/logging.h"
#include "src/platform/common.h"
#include "src/platform/virtualhid_input.h"
Include dependency graph for input.cpp:

Classes

struct  platf::client_input_raw_t
 Per-client virtual devices for touch and pen input. More...
struct  platf::gamepad_context_t
 ViGEm target and report buffers for one virtual gamepad. More...
struct  platf::gp_touch_context_t
 Last touch coordinates reported by a virtual gamepad. More...
struct  platf::input_raw_t
 Global virtual input device handles shared by clients. More...
class  platf::vigem_t
 ViGEm client connection and virtual gamepad collection. More...

Macros

#define APPLY_CALIBRATION(val, bias, scale)
 Macro for APPLY CALIBRATION.
#define CALLBACK
 Windows callback calling convention marker.
#define DPS_TO_DS4_GYRO(x)
 Macro for DPS TO DS4 GYRO.
#define MPS2_TO_DS4_ACCEL(x)
 Macro for MPS2 TO DS4 ACCEL.

Typedefs

using platf::client_t = util::safe_ptr<_VIGEM_CLIENT_T, &vigem_free>
 ViGEm client pointer released with vigem_free.
using platf::target_t = util::safe_ptr<_VIGEM_TARGET_T, &vigem_target_free>
 ViGEm target pointer released with vigem_target_free.

Functions

int platf::alloc_gamepad (input_t &input, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue)
 Create a new virtual gamepad.
std::unique_ptr< client_input_t > platf::allocate_client_input_context (input_t &input)
 Allocate a context to store per-client input data.
void platf::ds4_notify (client_t::pointer client, target_t::pointer target, std::uint8_t largeMotor, std::uint8_t smallMotor, DS4_LIGHTBAR_COLOR, void *userdata)
 Handle DualShock 4 virtual gamepad notification events.
void platf::ds4_update_ts_and_send (vigem_t *vigem, int nr)
 Sends DS4 input with updated timestamps and repeats to keep timestamp updated.
bool platf::ensure_vigem (input_raw_t *raw)
 Create the ViGEm fallback context if it is not already available.
void platf::free_gamepad (input_t &input, int nr)
 Release gamepad resources.
void platf::freeInput (input_raw_t *input)
 Release a platform input backend created by input().
void platf::gamepad_battery (input_t &input, const gamepad_battery_t &battery)
 Send a gamepad battery event to the OS.
void platf::gamepad_motion (input_t &input, const gamepad_motion_t &motion)
 Send a gamepad motion event to the OS.
void platf::gamepad_touch (input_t &input, const gamepad_touch_t &touch)
 Send a gamepad touch event to the OS.
void platf::gamepad_update (input_t &input, int nr, const gamepad_state_t &gamepad_state)
 Submit updated Sunshine gamepad state to the virtual device.
platform_caps::caps_t platf::get_capabilities ()
 Get the supported platform capabilities to advertise to the client.
std::optional< util::point_t > platf::get_mouse_loc (input_t &input)
 Get the current mouse position for platform input tests.
input_t platf::input ()
 Create the platform input backend for a stream.
int platf::rebind_gamepad (input_t &input, const gamepad_id_t &id, feedback_queue_t feedback_queue)
 Rebind an existing virtual gamepad to a resumed client session.
bool platf::should_allocate_vigembus_gamepad (const bool virtualhid_selected)
 Check and explain whether a gamepad allocation may use ViGEmBus.
bool platf::should_use_virtualhid_gamepads (const input_raw_t &raw)
 Check whether the libvirtualhid runtime should receive gamepad allocations.
std::vector< supported_gamepad_t > & platf::supported_gamepads (input_t *input)
 Gets the supported gamepads for this platform backend.
std::vector< supported_gamepad_t > platf::vigembus_supported_gamepads (const bool available)
 Return the gamepad choices supported by ViGEmBus.
void platf::x360_notify (client_t::pointer client, target_t::pointer target, std::uint8_t largeMotor, std::uint8_t smallMotor, std::uint8_t, void *userdata)
 Handle Xbox 360 virtual gamepad notification events.

Variables

constexpr DS4_REPORT_EX platf::ds4_report_init_ex
 DS4 report init ex.
constexpr DS4_TOUCH platf::ds4_touch_unused
 DS4 touch unused.
constexpr float platf::EARTH_G = 9.80665f
 Meters per second squared represented by one gravity unit.

Detailed Description

Definitions for input handling on Windows.

Macro Definition Documentation

◆ APPLY_CALIBRATION

#define APPLY_CALIBRATION ( val,
bias,
scale )
Value:
(int32_t) (((float) (val) + (bias)) / (scale))

Macro for APPLY CALIBRATION.

◆ DPS_TO_DS4_GYRO

#define DPS_TO_DS4_GYRO ( x)
Value:
(int32_t) ((x) * (1024 / 64))

Macro for DPS TO DS4 GYRO.

◆ MPS2_TO_DS4_ACCEL

#define MPS2_TO_DS4_ACCEL ( x)
Value:
(int32_t) (((x) / EARTH_G) * 8192)

Macro for MPS2 TO DS4 ACCEL.

Function Documentation

◆ alloc_gamepad()

int platf::alloc_gamepad ( input_t & input,
const gamepad_id_t & id,
const gamepad_arrival_t & metadata,
feedback_queue_t feedback_queue )

Create a new virtual gamepad.

Parameters
inputThe global input context.
idThe gamepad ID.
metadataController metadata from client (empty if none provided).
feedback_queueThe queue for posting messages back to the client.
Returns
0 on success.

◆ allocate_client_input_context()

std::unique_ptr< client_input_t > platf::allocate_client_input_context ( input_t & input)

Allocate a context to store per-client input data.

Allocates a context to store per-client input data.

Parameters
inputThe global input context.
Returns
A unique pointer to a per-client input data context.

◆ ds4_notify()

void platf::ds4_notify ( client_t::pointer client,
target_t::pointer target,
std::uint8_t largeMotor,
std::uint8_t smallMotor,
DS4_LIGHTBAR_COLOR led_color,
void * userdata )

Handle DualShock 4 virtual gamepad notification events.

Parameters
clientViGEm client.
targetViGEm target.
largeMotorLarge motor strength.
smallMotorSmall motor strength.
led_colorRequested lightbar color.
userdataUser data pointer.

◆ ds4_update_ts_and_send()

void platf::ds4_update_ts_and_send ( vigem_t * vigem,
int nr )

Sends DS4 input with updated timestamps and repeats to keep timestamp updated.

Some applications require updated timestamps values to register DS4 input.

Parameters
vigemThe global ViGEm context object.
nrThe global gamepad index.

◆ ensure_vigem()

bool platf::ensure_vigem ( input_raw_t * raw)

Create the ViGEm fallback context if it is not already available.

Parameters
rawPlatform input context.
Returns
True when ViGEm fallback is available.

◆ free_gamepad()

void platf::free_gamepad ( input_t & input,
int nr )

Release gamepad resources.

Parameters
inputPlatform input backend that receives the event.
nrController index assigned by the client.

◆ freeInput()

void platf::freeInput ( input_raw_t * input)

Release a platform input backend created by input().

Parameters
inputPlatform input backend to release.

◆ gamepad_battery()

void platf::gamepad_battery ( input_t & input,
const gamepad_battery_t & battery )

Send a gamepad battery event to the OS.

Sends a gamepad battery event to the OS.

Parameters
inputThe global input context.
batteryThe battery event.

◆ gamepad_motion()

void platf::gamepad_motion ( input_t & input,
const gamepad_motion_t & motion )

Send a gamepad motion event to the OS.

Sends a gamepad motion event to the OS.

Parameters
inputThe global input context.
motionThe motion event.

◆ gamepad_touch()

void platf::gamepad_touch ( input_t & input,
const gamepad_touch_t & touch )

Send a gamepad touch event to the OS.

Sends a gamepad touch event to the OS.

Parameters
inputThe global input context.
touchThe touch event.

◆ gamepad_update()

void platf::gamepad_update ( input_t & input,
int nr,
const gamepad_state_t & gamepad_state )

Submit updated Sunshine gamepad state to the virtual device.

Parameters
inputThe input context.
nrThe gamepad index to update.
gamepad_stateThe gamepad button/axis state sent from the client.

◆ get_capabilities()

platform_caps::caps_t platf::get_capabilities ( )

Get the supported platform capabilities to advertise to the client.

Returns the supported platform capabilities to advertise to the client.

Returns
Capability flags.

◆ get_mouse_loc()

std::optional< util::point_t > platf::get_mouse_loc ( input_t & input)

Get the current mouse position for platform input tests.

Parameters
inputThe input_t instance to use.
Returns
Screen coordinates of the mouse, or std::nullopt when the platform cannot observe the cursor.
Note
This helper exists only so tests can observe virtual mouse movement. Production input paths should submit mouse events through move_mouse() or abs_mouse() instead of reading the host cursor location.

Examples

if (auto location = get_mouse_loc(input)) {
auto [x, y] = *location;
}

◆ input()

input_t platf::input ( )

Create the platform input backend for a stream.

Returns
Platform-specific input backend for the active stream.

◆ rebind_gamepad()

int platf::rebind_gamepad ( input_t & input,
const gamepad_id_t & id,
feedback_queue_t feedback_queue )

Rebind an existing virtual gamepad to a resumed client session.

Parameters
inputPlatform input backend that owns the virtual gamepad.
idGlobal and client-relative identifiers for the resumed controller.
feedback_queueQueue used to return gamepad feedback to the resumed client.
Returns
0 when the gamepad exists and was rebound; otherwise -1.

◆ should_allocate_vigembus_gamepad()

bool platf::should_allocate_vigembus_gamepad ( const bool virtualhid_selected)

Check and explain whether a gamepad allocation may use ViGEmBus.

Parameters
virtualhid_selectedWhether Virtual HID Driver was selected for the allocation.
Returns
True when the allocation may continue through ViGEmBus.

◆ should_use_virtualhid_gamepads()

bool platf::should_use_virtualhid_gamepads ( const input_raw_t & raw)

Check whether the libvirtualhid runtime should receive gamepad allocations.

Backends that do not require the installed Windows driver, such as the fake test backend, do not require a machine license.

Parameters
rawGlobal Windows input context.
Returns
True when Virtual HID Driver gamepads are available and selected.

◆ supported_gamepads()

std::vector< supported_gamepad_t > & platf::supported_gamepads ( input_t * input)

Gets the supported gamepads for this platform backend.

This may be called prior to platf::input()!

Parameters
inputPointer to the platform's input_t or nullptr.
Returns
Vector of gamepad options and status.

◆ vigembus_supported_gamepads()

std::vector< supported_gamepad_t > platf::vigembus_supported_gamepads ( const bool available)

Return the gamepad choices supported by ViGEmBus.

Parameters
availableWhether Sunshine can connect to ViGEmBus.
Returns
Automatic, Xbox 360, and DualShock 4 choices with availability metadata.

◆ x360_notify()

void platf::x360_notify ( client_t::pointer client,
target_t::pointer target,
std::uint8_t largeMotor,
std::uint8_t smallMotor,
std::uint8_t ,
void * userdata )

Handle Xbox 360 virtual gamepad notification events.

Parameters
clientViGEm client.
targetViGEm target.
largeMotorLarge motor strength.
smallMotorSmall motor strength.
userdataUser data pointer.

Variable Documentation

◆ ds4_report_init_ex

DS4_REPORT_EX platf::ds4_report_init_ex
constexpr
Initial value:
= {
{{.bThumbLX = 0x80,
.bThumbLY = 0x80,
.bThumbRX = 0x80,
.bThumbRY = 0x80,
.wButtons = DS4_BUTTON_DPAD_NONE,
.bSpecial = 0,
.bTriggerL = 0,
.bTriggerR = 0,
.wTimestamp = 0,
.bBatteryLvl = 0xFF,
.wGyroX = 0,
.wGyroY = 0,
.wGyroZ = 0,
.wAccelX = 0,
.wAccelY = 0,
.wAccelZ = 0,
._bUnknown1 = {0x00, 0x00, 0x00, 0x00, 0x00},
.bBatteryLvlSpecial = 0x1A,
._bUnknown2 = {0x00, 0x00},
.bTouchPacketsN = 1,
.sCurrentTouch = ds4_touch_unused,
.sPreviousTouch = {ds4_touch_unused, ds4_touch_unused}}}
}

DS4 report init ex.

◆ ds4_touch_unused

DS4_TOUCH platf::ds4_touch_unused
constexpr
Initial value:
= {
.bPacketCounter = 0,
.bIsUpTrackingNum1 = 0x80,
.bTouchData1 = {0x00, 0x00, 0x00},
.bIsUpTrackingNum2 = 0x80,
.bTouchData2 = {0x00, 0x00, 0x00},
}

DS4 touch unused.