### vigem_connect Source: https://context7.com/nefarius/vigemclient/llms.txt Initializes the driver connection and establishes communication with the ViGEmBus device. This is an expensive operation and should be performed once at application startup. Returns VIGEM_ERROR_BUS_NOT_FOUND if no compatible bus driver is installed, or VIGEM_ERROR_BUS_ACCESS_FAILED if the handle cannot be opened. ```APIDOC ## vigem_connect ### Description Initializes the driver connection and establishes communication with the ViGEmBus device. This is an expensive operation and should be performed once at application startup. Returns `VIGEM_ERROR_BUS_NOT_FOUND` if no compatible bus driver is installed, or `VIGEM_ERROR_BUS_ACCESS_FAILED` if the handle cannot be opened. ### Method (Implicitly C function call) ### Parameters - **client** (PVIGEM_CLIENT) - The client handle allocated by `vigem_alloc`. ### Request Example ```cpp PVIGEM_CLIENT client = vigem_alloc(); const VIGEM_ERROR retval = vigem_connect(client); if (!VIGEM_SUCCESS(retval)) { fprintf(stderr, "ViGEm Bus connection failed: 0x%08X\n", retval); vigem_free(client); return -1; } // client is now connected to ViGEmBus ``` ### Response #### Success Response (VIGEM_SUCCESS) - (No specific return value, indicates success) #### Error Responses - **VIGEM_ERROR_BUS_NOT_FOUND**: No compatible bus driver is installed. - **VIGEM_ERROR_BUS_ACCESS_FAILED**: The handle cannot be opened. #### Response Example (See Request Example for usage) ``` -------------------------------- ### Get XInput Player Index for X360 Pad Source: https://context7.com/nefarius/vigemclient/llms.txt Retrieves the system-assigned XInput player index (0-3) for a virtual Xbox 360 controller. This is only valid after the device is fully connected. ```cpp ULONG index = 0; const VIGEM_ERROR ret = vigem_target_x360_get_user_index(client, pad, &index); if (VIGEM_SUCCESS(ret)) printf("Virtual pad is XInput player index: %lu\n", index); ``` -------------------------------- ### Include Basic Headers for ViGEmClient Source: https://github.com/nefarius/vigemclient/blob/master/README.md Includes necessary headers for Windows API, XInput, and the ViGEm API. Links against setupapi.lib. ```cpp #define WIN32_LEAN_AND_MEAN #include #include #include #pragma comment(lib, "setupapi.lib") ``` -------------------------------- ### Plug in a virtual device (non-blocking) Source: https://context7.com/nefarius/vigemclient/llms.txt Use `vigem_target_add_async` for non-blocking device addition, suitable for UIs. An optional callback is invoked upon completion or failure. Execution continues immediately after the call. ```cpp VOID CALLBACK OnDeviceReady( PVIGEM_CLIENT Client, PVIGEM_TARGET Target, VIGEM_ERROR Result) { if (VIGEM_SUCCESS(Result)) printf("Virtual controller is ready!\n"); else fprintf(stderr, "Async plug-in failed: 0x%08X\n", Result); } PVIGEM_TARGET pad = vigem_target_x360_alloc(); const VIGEM_ERROR ret = vigem_target_add_async(client, pad, &OnDeviceReady); if (!VIGEM_SUCCESS(ret)) { fprintf(stderr, "vigem_target_add_async failed: 0x%08X\n", ret); } // Execution continues immediately; OnDeviceReady fires later ``` -------------------------------- ### Connect to ViGEm Driver Source: https://github.com/nefarius/vigemclient/blob/master/README.md Establishes a connection to the ViGEm driver. Recommended to do this once per project for performance. ```cpp const auto retval = vigem_connect(client); if (!VIGEM_SUCCESS(retval)) { std::cerr << "ViGEm Bus connection failed with error code: 0x" << std::hex << retval << std::endl; return -1; } ``` -------------------------------- ### Plug in a virtual device (blocking) Source: https://context7.com/nefarius/vigemclient/llms.txt Use `vigem_target_add` to add a virtual device to the bus. This function blocks until the device is ready. It returns `VIGEM_ERROR_ALREADY_CONNECTED` if the device is already present. ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); const VIGEM_ERROR pir = vigem_target_add(client, pad); if (!VIGEM_SUCCESS(pir)) { fprintf(stderr, "Target plug-in failed: 0x%08X\n", pir); vigem_target_free(pad); return -1; } // Virtual Xbox 360 controller is now live on the system ``` -------------------------------- ### Initialize ViGEmClient Source: https://github.com/nefarius/vigemclient/blob/master/README.md Allocates a handle for the ViGEm client. Returns an error if memory allocation fails. ```cpp const auto client = vigem_alloc(); if (client == nullptr) { std::cerr << "Uh, not enough memory to do that?!" << std::endl; return -1; } ``` -------------------------------- ### Connect to ViGEmBus Driver Source: https://context7.com/nefarius/vigemclient/llms.txt Establishes communication with the ViGEmBus driver. This is a resource-intensive operation and should ideally be performed once during application startup. Handles potential connection errors like VIGEM_ERROR_BUS_NOT_FOUND or VIGEM_ERROR_BUS_ACCESS_FAILED. ```cpp PVIGEM_CLIENT client = vigem_alloc(); const VIGEM_ERROR retval = vigem_connect(client); if (!VIGEM_SUCCESS(retval)) { fprintf(stderr, "ViGEm Bus connection failed: 0x%08X\n", retval); vigem_free(client); return -1; } // client is now connected to ViGEmBus ``` -------------------------------- ### vigem_alloc Source: https://context7.com/nefarius/vigemclient/llms.txt Allocates and initializes an opaque PVIGEM_CLIENT handle needed to connect to the ViGEmBus driver. Returns NULL if the system cannot provide sufficient memory. The returned handle must eventually be released with vigem_free. ```APIDOC ## vigem_alloc ### Description Allocates and initializes an opaque `PVIGEM_CLIENT` handle needed to connect to the ViGEmBus driver. Returns `NULL` if the system cannot provide sufficient memory. The returned handle must eventually be released with `vigem_free`. ### Method (Implicitly C function call) ### Parameters None ### Request Example ```cpp #define WIN32_LEAN_AND_MEAN #include #include #pragma comment(lib, "setupapi.lib") int main() { PVIGEM_CLIENT client = vigem_alloc(); if (client == nullptr) { // Out of memory return -1; } // client is now ready to be connected vigem_free(client); // release when done return 0; } ``` ### Response #### Success Response - **client** (PVIGEM_CLIENT) - A pointer to the allocated client object. #### Response Example (See Request Example for usage) ``` -------------------------------- ### vigem_target_add_async Source: https://context7.com/nefarius/vigemclient/llms.txt Adds a virtual target device to the bus without blocking the calling thread. A callback function is invoked upon completion, either on success or failure, allowing for non-blocking UI updates. ```APIDOC ## vigem_target_add_async ### Description Adds the target device to the bus and returns immediately. An optional `EVT_VIGEM_TARGET_ADD_RESULT` callback is invoked when the device becomes operational or on failure. Useful for UIs that must not block the main thread. ### Method ```cpp const VIGEM_ERROR ret = vigem_target_add_async(client, pad, &OnDeviceReady); ``` ### Parameters - `client`: A pointer to the `VIGEM_CLIENT` instance. - `pad`: A pointer to the `VIGEM_TARGET` representing the virtual device. - `OnDeviceReady`: A pointer to a callback function (`EVT_VIGEM_TARGET_ADD_RESULT`) that will be called when the operation completes. ### Return Value - `VIGEM_ERROR`: Indicates success or failure of initiating the asynchronous operation. `VIGEM_SUCCESS` on success, or an error code on failure. ### Callback Signature ```cpp VOID CALLBACK OnDeviceReady( PVIGEM_CLIENT Client, PVIGEM_TARGET Target, VIGEM_ERROR Result) { // Handle result } ``` ### Request Example ```cpp VOID CALLBACK OnDeviceReady( PVIGEM_CLIENT Client, PVIGEM_TARGET Target, VIGEM_ERROR Result) { if (VIGEM_SUCCESS(Result)) printf("Virtual controller is ready!\n"); else fprintf(stderr, "Async plug-in failed: 0x%08X\n", Result); } PVIGEM_TARGET pad = vigem_target_x360_alloc(); const VIGEM_ERROR ret = vigem_target_add_async(client, pad, &OnDeviceReady); if (!VIGEM_SUCCESS(ret)) { fprintf(stderr, "vigem_target_add_async failed: 0x%08X\n", ret); } // Execution continues immediately; OnDeviceReady fires later ``` ``` -------------------------------- ### Override VID/PID for Target Device Source: https://context7.com/nefarius/vigemclient/llms.txt Sets a custom Vendor ID and Product ID for a virtual target device. This must be called before adding the target to the client. ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); vigem_target_set_vid(pad, 0x045E); // Microsoft VID vigem_target_set_pid(pad, 0x028E); // Xbox 360 Controller PID vigem_target_add(client, pad); USHORT vid = vigem_target_get_vid(pad); // 0x045E USHORT pid = vigem_target_get_pid(pad); // 0x028E ``` -------------------------------- ### Allocate ViGEm Client Handle Source: https://context7.com/nefarius/vigemclient/llms.txt Allocates and initializes a PVIGEM_CLIENT handle. This handle is required for connecting to the ViGEmBus driver and must be released using vigem_free when no longer needed. Returns NULL on memory allocation failure. ```cpp #define WIN32_LEAN_AND_MEAN #include #include #pragma comment(lib, "setupapi.lib") int main() { PVIGEM_CLIENT client = vigem_alloc(); if (client == nullptr) { // Out of memory return -1; } // client is now ready to be connected vigem_free(client); // release when done return 0; } ``` -------------------------------- ### Register Xbox 360 output callback Source: https://context7.com/nefarius/vigemclient/llms.txt Use `vigem_target_x360_register_notification` to register a callback for output reports from the virtual Xbox 360 device. This callback handles rumble and LED changes and runs on a dedicated thread. ```cpp VOID CALLBACK X360Notification( PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber, LPVOID UserData) { printf("Rumble — Large: %u Small: %u LED: %u\n", LargeMotor, SmallMotor, LedNumber); } const VIGEM_ERROR ret = vigem_target_x360_register_notification( client, pad, &X360Notification, nullptr /* UserData */); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "Notification registration failed: 0x%08X\n", ret); // Later: remove the callback vigem_target_x360_unregister_notification(pad); ``` -------------------------------- ### Define and Register Notification Callback Source: https://github.com/nefarius/vigemclient/blob/master/README.md Defines a callback function to handle notifications from the virtual controller (e.g., rumble requests). Registers this callback with the ViGEm client. ```cpp // // Define the callback function // VOID CALLBACK notification( PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber, LPVOID UserData ) { static int count = 1; std::cout.width(3); std::cout << count++ << " "; std::cout.width(3); std::cout << (int)LargeMotor << " "; std::cout.width(3); std::cout << (int)SmallMotor << std::endl; } const auto retval = vigem_target_x360_register_notification(client, pad, ¬ification, nullptr); // // Error handling // if (!VIGEM_SUCCESS(retval)) { std::cerr << "Registering for notification failed with error code: 0x" << std::hex <(&state.Gamepad)); // // We're done with this pad, free resources (this disconnects the virtual device) // vigem_target_remove(client, pad); vigem_target_free(pad); ``` -------------------------------- ### vigem_target_add Source: https://context7.com/nefarius/vigemclient/llms.txt Adds a virtual target device to the bus, simulating a physical plug-in. This function blocks until the device is ready to receive input reports. It returns an error if the device is already connected. ```APIDOC ## vigem_target_add ### Description Adds the target device to the bus, equivalent to a physical plug-in event. Blocks until the device is fully operational and ready to receive input reports. Returns `VIGEM_ERROR_ALREADY_CONNECTED` if the device is already on the bus. ### Method ```cpp const VIGEM_ERROR pir = vigem_target_add(client, pad); ``` ### Parameters - `client`: A pointer to the `VIGEM_CLIENT` instance. - `pad`: A pointer to the `VIGEM_TARGET` representing the virtual device. ### Return Value - `VIGEM_ERROR`: Indicates success or failure. `VIGEM_SUCCESS` on success, `VIGEM_ERROR_ALREADY_CONNECTED` if the device is already on the bus, or other error codes on failure. ### Request Example ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); const VIGEM_ERROR pir = vigem_target_add(client, pad); if (!VIGEM_SUCCESS(pir)) { fprintf(stderr, "Target plug-in failed: 0x%08X\n", pir); vigem_target_free(pad); return -1; } // Virtual Xbox 360 controller is now live on the system ``` ``` -------------------------------- ### Check for Waitable Add IOCTL Support Source: https://context7.com/nefarius/vigemclient/llms.txt Verifies if the ViGEmBus driver version supports the waitable add IOCTL (version 1.17+). This helps in choosing between blocking and asynchronous add methods. ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); vigem_target_add(client, pad); // must be plugged in first if (vigem_target_is_waitable_add_supported(pad)) printf("Driver >= 1.17: waitable add is supported\n"); else printf("Driver <= 1.16: use async add with callback\n"); ``` -------------------------------- ### Send input report to Xbox 360 controller Source: https://context7.com/nefarius/vigemclient/llms.txt Use `vigem_target_x360_update` to send an `XUSB_REPORT` to a virtual Xbox 360 device. This structure is compatible with `XINPUT_GAMEPAD` and should be called in your input loop. ```cpp #include #include // Forward physical XInput pad 0 to the virtual pad XINPUT_STATE state; ZeroMemory(&state, sizeof(state)); XInputGetState(0, &state); // XINPUT_GAMEPAD is layout-compatible with XUSB_REPORT const VIGEM_ERROR ret = vigem_target_x360_update( client, pad, *reinterpret_cast(&state.Gamepad) ); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "X360 update failed: 0x%08X\n", ret); ``` -------------------------------- ### vigem_target_x360_get_user_index Source: https://context7.com/nefarius/vigemclient/llms.txt Retrieves the zero-based XInput player index assigned to a virtual Xbox 360 controller. This is only valid after the device is fully plugged in. ```APIDOC ## vigem_target_x360_get_user_index ### Description Returns the zero-based player index (0–3) assigned by the system to the virtual Xbox 360 controller, compatible with the `dwUserIndex` parameter of the XInput APIs. Only valid after the device is fully plugged in. ### Method `vigem_target_x360_get_user_index(client, pad, index)` ### Parameters #### Path Parameters - **client** (PVIGEMUX_CLIENT) - Required - Handle to the ViGEmBus client. - **pad** (PVIGEM_TARGET) - Required - Handle to the virtual Xbox 360 device. - **index** (PULONG) - Required - Pointer to a ULONG to store the player index. ### Request Example ```cpp ULONG index = 0; const VIGEM_ERROR ret = vigem_target_x360_get_user_index(client, pad, &index); if (VIGEM_SUCCESS(ret)) printf("Virtual pad is XInput player index: %lu\n", index); ``` ``` -------------------------------- ### vigem_target_set_vid / vigem_target_set_pid Source: https://context7.com/nefarius/vigemclient/llms.txt Overrides the default Vendor ID (VID) or Product ID (PID) of a target device before it is plugged in. These functions must be called before `vigem_target_add`. ```APIDOC ## vigem_target_set_vid / vigem_target_set_pid ### Description Overrides the default Vendor ID or Product ID of a target device before it is plugged in. Must be called before `vigem_target_add`. ### Method `vigem_target_set_vid(target, vid)` `vigem_target_set_pid(target, pid)` ### Parameters #### Path Parameters - **target** (PVIGEM_TARGET) - Required - Handle to the virtual device. - **vid** (USHORT) - Required - The Vendor ID to set. - **pid** (USHORT) - Required - The Product ID to set. ### Request Example ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); vigem_target_set_vid(pad, 0x045E); // Microsoft VID vigem_target_set_pid(pad, 0x028E); // Xbox 360 Controller PID vigem_target_add(client, pad); USHORT vid = vigem_target_get_vid(pad); // 0x045E USHORT pid = vigem_target_get_pid(pad); // 0x028E ``` ``` -------------------------------- ### vigem_target_x360_alloc Source: https://context7.com/nefarius/vigemclient/llms.txt Allocates a PVIGEM_TARGET handle representing an Xbox 360 wired controller. The device is not active until vigem_target_add is called. Default VID/PID match a standard Xbox 360 controller. ```APIDOC ## vigem_target_x360_alloc ### Description Allocates a `PVIGEM_TARGET` handle representing an Xbox 360 wired controller. The device is not active until `vigem_target_add` is called. Default VID/PID match a standard Xbox 360 controller. ### Method (Implicitly C function call) ### Parameters None ### Request Example ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); if (pad == nullptr) { fprintf(stderr, "Failed to allocate X360 target\n"); return -1; } ``` ### Response #### Success Response - **pad** (PVIGEM_TARGET) - A pointer to the allocated target object for an Xbox 360 controller. #### Response Example (See Request Example for usage) ``` -------------------------------- ### vigem_target_ds4_await_output_report Source: https://context7.com/nefarius/vigemclient/llms.txt Blocks until an output report arrives from the host for a virtual DS4 device. It writes the raw 64-byte buffer to the provided DS4_OUTPUT_BUFFER. Each call delivers one packet in arrival order. Returns VIGEM_ERROR_TARGET_NOT_PLUGGED_IN if the device is removed while waiting. ```APIDOC ## vigem_target_ds4_await_output_report ### Description Waits (event-based, no spin) until the host sends an output report to the virtual DS4 device, then writes the raw 64-byte buffer to the provided `DS4_OUTPUT_BUFFER`. Each call delivers one packet in arrival order. Recommended usage is a dedicated thread loop. Returns `VIGEM_ERROR_TARGET_NOT_PLUGGED_IN` if the device is removed while waiting. ### Method `vigem_target_ds4_await_output_report(client, ds4, buffer)` ### Parameters #### Path Parameters - **client** (PVIGEMUX_CLIENT) - Required - Handle to the ViGEmBus client. - **ds4** (PVIGEM_TARGET) - Required - Handle to the virtual DS4 device. - **buffer** (PDS4_OUTPUT_BUFFER) - Required - Pointer to a buffer to store the output report. ### Request Example ```cpp #include std::thread outputThread([&]() { DS4_OUTPUT_BUFFER buffer; while (true) { const VIGEM_ERROR ret = vigem_target_ds4_await_output_report( client, ds4, &buffer); if (!VIGEM_SUCCESS(ret)) { // Device was likely removed break; } // buffer.Buffer[0..63] contains the raw HID output report // Byte 4 = large motor, Byte 5 = small motor // Bytes 6-8 = lightbar R, G, B printf("Motor L: %u Motor R: %u LED R:%u G:%u B:%u\n", buffer.Buffer[4], buffer.Buffer[5], buffer.Buffer[6], buffer.Buffer[7], buffer.Buffer[8]); } }); outputThread.detach(); ``` ``` -------------------------------- ### vigem_target_ds4_await_output_report_timeout Source: https://context7.com/nefarius/vigemclient/llms.txt Similar to `vigem_target_ds4_await_output_report`, but includes a timeout. Returns `VIGEM_ERROR_TIMED_OUT` if no report arrives within the specified milliseconds. Useful for graceful loop exits. ```APIDOC ## vigem_target_ds4_await_output_report_timeout ### Description Identical to `vigem_target_ds4_await_output_report` but returns `VIGEM_ERROR_TIMED_OUT` after `milliseconds` if no report arrives. Useful for graceful loop exit without excessive CPU usage. Pass `INFINITE` to replicate the non-timeout variant. ### Method `vigem_target_ds4_await_output_report_timeout(client, ds4, milliseconds, buffer)` ### Parameters #### Path Parameters - **client** (PVIGEMUX_CLIENT) - Required - Handle to the ViGEmBus client. - **ds4** (PVIGEM_TARGET) - Required - Handle to the virtual DS4 device. - **milliseconds** (ULONG) - Required - The timeout duration in milliseconds. Use `INFINITE` for no timeout. - **buffer** (PDS4_OUTPUT_BUFFER) - Required - Pointer to a buffer to store the output report. ### Request Example ```cpp DS4_OUTPUT_BUFFER buffer; while (running) { const VIGEM_ERROR ret = vigem_target_ds4_await_output_report_timeout( client, ds4, 500, // 500 ms timeout allows checking `running` flag periodically &buffer); if (ret == VIGEM_ERROR_TIMED_OUT) continue; // no new data, loop again if (!VIGEM_SUCCESS(ret)) break; // device removed or fatal error // Process buffer.Buffer ... } ``` ``` -------------------------------- ### Free ViGEm Client Handle Source: https://context7.com/nefarius/vigemclient/llms.txt Releases all memory associated with a PVIGEM_CLIENT object. This function should be called after vigem_disconnect. It does not affect any associated target device objects. ```cpp PVIGEM_CLIENT client = vigem_alloc(); // ... use client ... vigem_disconnect(client); vigem_free(client); // client is invalid after this ``` -------------------------------- ### Convert XUSB_REPORT to DS4_REPORT Source: https://context7.com/nefarius/vigemclient/llms.txt This utility function maps an XUSB_REPORT to a DS4_REPORT, translating buttons, triggers, D-pad directions, and analog stick axes. Useful for proxying XInput devices to a virtual DS4. Ensure DS4_REPORT is initialized before calling. ```cpp #include #include XINPUT_STATE state; XInputGetState(0, &state); XUSB_REPORT xReport = *reinterpret_cast(&state.Gamepad); DS4_REPORT ds4Report; DS4_REPORT_INIT(&ds4Report); // sets thumbsticks to center (0x80) and clears D-pad XUSB_TO_DS4_REPORT(&xReport, &ds4Report); vigem_target_ds4_update(client, ds4, ds4Report); ``` -------------------------------- ### Await DS4 Output Report (Event-Based) Source: https://context7.com/nefarius/vigemclient/llms.txt Waits for a DS4 output report without blocking the CPU. Recommended for use in a dedicated thread. Handles device removal during the wait. ```cpp #include std::thread outputThread([&]() { DS4_OUTPUT_BUFFER buffer; while (true) { const VIGEM_ERROR ret = vigem_target_ds4_await_output_report( client, ds4, &buffer); if (!VIGEM_SUCCESS(ret)) { // Device was likely removed break; } // buffer.Buffer[0..63] contains the raw HID output report // Byte 4 = large motor, Byte 5 = small motor // Bytes 6-8 = lightbar R, G, B printf("Motor L: %u Motor R: %u LED R:%u G:%u B:%u\n", buffer.Buffer[4], buffer.Buffer[5], buffer.Buffer[6], buffer.Buffer[7], buffer.Buffer[8]); } }); outputThread.detach(); ``` -------------------------------- ### vigem_target_is_waitable_add_supported Source: https://context7.com/nefarius/vigemclient/llms.txt Determines if the connected ViGEmBus driver supports the waitable add IOCTL (version 1.17+). This is useful for choosing between blocking and asynchronous `vigem_target_add`. ```APIDOC ## vigem_target_is_waitable_add_supported ### Description Returns `TRUE` if the connected ViGEmBus driver supports the waitable add IOCTL (version 1.17+). Useful for branching between blocking `vigem_target_add` and the async variant on older drivers. ### Method `vigem_target_is_waitable_add_supported(target)` ### Parameters #### Path Parameters - **target** (PVIGEM_TARGET) - Required - Handle to the virtual device. ### Request Example ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); vigem_target_add(client, pad); // must be plugged in first if (vigem_target_is_waitable_add_supported(pad)) printf("Driver >= 1.17: waitable add is supported\n"); else printf("Driver <= 1.16: use async add with callback\n"); ``` ``` -------------------------------- ### vigem_target_x360_get_output Source: https://context7.com/nefarius/vigemclient/llms.txt Polls the current output state (motor and LED values) for a virtual Xbox 360 device without blocking. This retrieves data from the most recent host output report. ```APIDOC ## vigem_target_x360_get_output ### Description Reads the current output data (motor and LED values) set by the most recent host output report for the virtual Xbox 360 device without blocking. ### Method `vigem_target_x360_get_output(client, pad, output)` ### Parameters #### Path Parameters - **client** (PVIGEMUX_CLIENT) - Required - Handle to the ViGEmBus client. - **pad** (PVIGEM_TARGET) - Required - Handle to the virtual Xbox 360 device. - **output** (PXUSB_OUTPUT_DATA) - Required - Pointer to a structure to store the output data. ### Request Example ```cpp XUSB_OUTPUT_DATA output; const VIGEM_ERROR ret = vigem_target_x360_get_output(client, pad, &output); if (VIGEM_SUCCESS(ret)) { printf("Large motor: %u Small motor: %u LED: %u\n", output.LargeMotor, output.SmallMotor, output.LedNumber); } ``` ``` -------------------------------- ### Unplug a virtual device Source: https://context7.com/nefarius/vigemclient/llms.txt Use `vigem_target_remove` to remove a virtual device from the bus. This is equivalent to a physical unplug event. The target object can be reused after this call. ```cpp const VIGEM_ERROR ret = vigem_target_remove(client, pad); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "Failed to remove target: 0x%08X\n", ret); ``` -------------------------------- ### vigem_target_ds4_alloc Source: https://context7.com/nefarius/vigemclient/llms.txt Allocates a PVIGEM_TARGET handle representing a Sony DualShock 4 wired controller. Must be plugged in with vigem_target_add before any reports can be submitted. ```APIDOC ## vigem_target_ds4_alloc ### Description Allocates a `PVIGEM_TARGET` handle representing a Sony DualShock 4 wired controller. Must be plugged in with `vigem_target_add` before any reports can be submitted. ### Method (Implicitly C function call) ### Parameters None ### Request Example ```cpp PVIGEM_TARGET ds4 = vigem_target_ds4_alloc(); if (ds4 == nullptr) { fprintf(stderr, "Failed to allocate DS4 target\n"); return -1; } ``` ### Response #### Success Response - **ds4** (PVIGEM_TARGET) - A pointer to the allocated target object for a DualShock 4 controller. #### Response Example (See Request Example for usage) ``` -------------------------------- ### vigem_free Source: https://context7.com/nefarius/vigemclient/llms.txt Releases all memory used by the PVIGEM_CLIENT object. Must be called after vigem_disconnect. Does not free any associated target device objects. ```APIDOC ## vigem_free ### Description Releases all memory used by the `PVIGEM_CLIENT` object. Must be called after `vigem_disconnect`. Does not free any associated target device objects. ### Method (Implicitly C function call) ### Parameters - **client** (PVIGEM_CLIENT) - The client handle to free. ### Request Example ```cpp PVIGEM_CLIENT client = vigem_alloc(); // ... use client ... vigem_disconnect(client); vigem_free(client); // client is invalid after this ``` ### Response (No explicit return value, indicates memory release) ### Response Example (See Request Example for usage) ``` -------------------------------- ### vigem_target_x360_update Source: https://context7.com/nefarius/vigemclient/llms.txt Sends an input report to a virtual Xbox 360 controller. This function updates the state of the virtual device, allowing it to reflect gamepad inputs. ```APIDOC ## vigem_target_x360_update ### Description Sends a new `XUSB_REPORT` state to the virtual Xbox 360 device. The `XUSB_REPORT` structure is binary-compatible with `XINPUT_GAMEPAD`, allowing direct casting. Call this in your input loop whenever state changes. ### Method ```cpp const VIGEM_ERROR ret = vigem_target_x360_update( client, pad, *reinterpret_cast(&state.Gamepad) ); ``` ### Parameters - `client`: A pointer to the `VIGEM_CLIENT` instance. - `pad`: A pointer to the `VIGEM_TARGET` representing the virtual Xbox 360 controller. - `report`: A pointer to an `XUSB_REPORT` structure containing the new state of the controller. ### Return Value - `VIGEM_ERROR`: Indicates success or failure of sending the update. `VIGEM_SUCCESS` on success, or an error code on failure. ### Request Example ```cpp #include #include // Forward physical XInput pad 0 to the virtual pad XINPUT_STATE state; ZeroMemory(&state, sizeof(state)); XInputGetState(0, &state); // XINPUT_GAMEPAD is layout-compatible with XUSB_REPORT const VIGEM_ERROR ret = vigem_target_x360_update( client, pad, *reinterpret_cast(&state.Gamepad) ); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "X360 update failed: 0x%08X\n", ret); ``` ``` -------------------------------- ### vigem_target_x360_register_notification Source: https://context7.com/nefarius/vigemclient/llms.txt Registers a callback function to receive output reports from the host for a virtual Xbox 360 controller. This is typically used to handle rumble and LED feedback. ```APIDOC ## vigem_target_x360_register_notification ### Description Registers a callback that is invoked every time the host sends an output report to the virtual Xbox 360 device — i.e., rumble motor values (`LargeMotor`, `SmallMotor`) or LED ring index changes (`LedNumber`). The callback runs on a dedicated thread in arrival order. ### Method ```cpp const VIGEM_ERROR ret = vigem_target_x360_register_notification( client, pad, &X360Notification, nullptr /* UserData */ ); ``` ### Parameters - `client`: A pointer to the `VIGEM_CLIENT` instance. - `pad`: A pointer to the `VIGEM_TARGET` representing the virtual Xbox 360 controller. - `X360Notification`: A pointer to the callback function to be registered. - `UserData`: Optional user-defined data to be passed to the callback. ### Return Value - `VIGEM_ERROR`: Indicates success or failure of registering the notification. `VIGEM_SUCCESS` on success, or an error code on failure. ### Callback Signature ```cpp VOID CALLBACK X360Notification( PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber, LPVOID UserData) { // Handle output report data } ``` ### Request Example ```cpp VOID CALLBACK X360Notification( PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber, LPVOID UserData) { printf("Rumble — Large: %u Small: %u LED: %u\n", LargeMotor, SmallMotor, LedNumber); } const VIGEM_ERROR ret = vigem_target_x360_register_notification( client, pad, &X360Notification, nullptr /* UserData */); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "Notification registration failed: 0x%08X\n", ret); // Later: remove the callback vigem_target_x360_unregister_notification(pad); ``` ``` -------------------------------- ### vigem_target_ds4_get_output Source: https://context7.com/nefarius/vigemclient/llms.txt Polls the current output state (motor and lightbar values) for a virtual DS4 device without blocking. This retrieves data from the most recent host output report. ```APIDOC ## vigem_target_ds4_get_output ### Description Reads the current output data (motor and lightbar values) set by the most recent host output report for the virtual DS4 device without blocking. ### Method `vigem_target_ds4_get_output(client, ds4, output)` ### Parameters #### Path Parameters - **client** (PVIGEMUX_CLIENT) - Required - Handle to the ViGEmBus client. - **ds4** (PVIGEM_TARGET) - Required - Handle to the virtual DS4 device. - **output** (PDS4_OUTPUT_DATA) - Required - Pointer to a structure to store the output data. ### Request Example ```cpp DS4_OUTPUT_DATA output; const VIGEM_ERROR ret = vigem_target_ds4_get_output(client, ds4, &output); if (VIGEM_SUCCESS(ret)) { printf("Large motor: %u Small motor: %u Lightbar: R=%u G=%u B=%u\n", output.LargeMotor, output.SmallMotor, output.LightbarColor.Red, output.LightbarColor.Green, output.LightbarColor.Blue); } ``` ``` -------------------------------- ### Await DS4 Output Report with Timeout Source: https://context7.com/nefarius/vigemclient/llms.txt Waits for a DS4 output report with a specified timeout. Returns VIGEM_ERROR_TIMED_OUT if no report arrives within the duration. Useful for periodic checks. ```cpp DS4_OUTPUT_BUFFER buffer; while (running) { const VIGEM_ERROR ret = vigem_target_ds4_await_output_report_timeout( client, ds4, 500, // 500 ms timeout allows checking `running` flag periodically &buffer); if (ret == VIGEM_ERROR_TIMED_OUT) continue; // no new data, loop again if (!VIGEM_SUCCESS(ret)) break; // device removed or fatal error // Process buffer.Buffer ... ``` -------------------------------- ### Send full input report to DualShock 4 controller Source: https://context7.com/nefarius/vigemclient/llms.txt Use `vigem_target_ds4_update_ex` to send a complete `DS4_REPORT_EX` to a virtual DS4 device. This function supports advanced features like gyroscope, accelerometer, and touchpad data. ```cpp DS4_REPORT_EX report; ZeroMemory(&report, sizeof(report)); // Center thumbsticks report.Report.bThumbLX = 0x80; report.Report.bThumbLY = 0x80; report.Report.bThumbRX = 0x80; report.Report.bThumbRY = 0x80; // Press Cross button and hold left trigger report.Report.wButtons |= DS4_BUTTON_CROSS; report.Report.bTriggerL = 0xFF; // Supply gyro/accel data (neutral) report.Report.wGyroX = 0; report.Report.wGyroY = 0; report.Report.wGyroZ = 0; report.Report.wAccelX = 0; report.Report.wAccelY = 0; report.Report.wAccelZ = 0; const VIGEM_ERROR ret = vigem_target_ds4_update_ex(client, ds4, report); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "DS4 update failed: 0x%08X\n", ret); ``` -------------------------------- ### Disconnect and Free ViGEmClient Source: https://github.com/nefarius/vigemclient/blob/master/README.md Disconnects from the ViGEm driver and frees the client resources. The client handle becomes invalid after this operation. ```cpp vigem_disconnect(client); vigem_free(client); ``` -------------------------------- ### Allocate Virtual Xbox 360 Controller Source: https://context7.com/nefarius/vigemclient/llms.txt Allocates a PVIGEM_TARGET handle for an Xbox 360 wired controller. The device becomes active on the bus only after vigem_target_add is called. Uses default VID/PID for a standard Xbox 360 controller. ```cpp PVIGEM_TARGET pad = vigem_target_x360_alloc(); if (pad == nullptr) { fprintf(stderr, "Failed to allocate X360 target\n"); return -1; } ``` -------------------------------- ### Check if Target Device is Attached Source: https://context7.com/nefarius/vigemclient/llms.txt Determines if a virtual target device is currently connected to the ViGEmBus. Returns TRUE if attached, FALSE otherwise. ```cpp if (vigem_target_is_attached(pad)) printf("Virtual controller is active\n"); else printf("Virtual controller is not connected\n"); ``` -------------------------------- ### vigem_disconnect Source: https://context7.com/nefarius/vigemclient/llms.txt Disconnects from the bus and resets the driver object state. All currently connected virtual targets are automatically removed from the bus. Allocated target objects are not freed automatically; callers must still call vigem_target_free on each. The client handle may be reused after this call. ```APIDOC ## vigem_disconnect ### Description Disconnects from the bus and resets the driver object state. All currently connected virtual targets are automatically removed from the bus. Allocated target objects are **not** freed automatically; callers must still call `vigem_target_free` on each. The `client` handle may be reused after this call. ### Method (Implicitly C function call) ### Parameters - **client** (PVIGEM_CLIENT) - The client handle to disconnect. ### Request Example ```cpp // Cleanup sequence at application shutdown vigem_disconnect(client); vigem_free(client); // client handle is now invalid and must not be used ``` ### Response (No explicit return value, indicates disconnection) ### Response Example (See Request Example for usage) ``` -------------------------------- ### Free Target Device Object Source: https://context7.com/nefarius/vigemclient/llms.txt Frees the memory occupied by a PVIGEM_TARGET object. This action does not remove the device from the bus. It is crucial to call vigem_target_remove before freeing the target to prevent orphaned devices. ```cpp vigem_target_remove(client, pad); vigem_target_free(pad); // safe to free after removal pad = nullptr; ``` -------------------------------- ### Allocate Virtual DualShock 4 Controller Source: https://context7.com/nefarius/vigemclient/llms.txt Allocates a PVIGEM_TARGET handle for a Sony DualShock 4 wired controller. The controller must be connected to the bus using vigem_target_add before input reports can be submitted. ```cpp PVIGEM_TARGET ds4 = vigem_target_ds4_alloc(); if (ds4 == nullptr) { fprintf(stderr, "Failed to allocate DS4 target\n"); return -1; } ``` -------------------------------- ### vigem_target_ds4_update_ex Source: https://context7.com/nefarius/vigemclient/llms.txt Sends a full input report to a virtual DualShock 4 controller, including advanced features like gyroscope and touchpad data. This is the recommended method for updating DS4 state. ```APIDOC ## vigem_target_ds4_update_ex ### Description Sends a complete `DS4_REPORT_EX` to the virtual DS4 device. Preferred over the deprecated `vigem_target_ds4_update` because it supports gyroscope, accelerometer, touchpad, battery level, and timestamp fields. ### Method ```cpp const VIGEM_ERROR ret = vigem_target_ds4_update_ex(client, ds4, report); ``` ### Parameters - `client`: A pointer to the `VIGEM_CLIENT` instance. - `ds4`: A pointer to the `VIGEM_TARGET` representing the virtual DualShock 4 controller. - `report`: A `DS4_REPORT_EX` structure containing the full state of the controller, including advanced features. ### Return Value - `VIGEM_ERROR`: Indicates success or failure of sending the update. `VIGEM_SUCCESS` on success, or an error code on failure. ### Request Example ```cpp DS4_REPORT_EX report; ZeroMemory(&report, sizeof(report)); // Center thumbsticks report.Report.bThumbLX = 0x80; report.Report.bThumbLY = 0x80; report.Report.bThumbRX = 0x80; report.Report.bThumbRY = 0x80; // Press Cross button and hold left trigger report.Report.wButtons |= DS4_BUTTON_CROSS; report.Report.bTriggerL = 0xFF; // Supply gyro/accel data (neutral) report.Report.wGyroX = 0; report.Report.wGyroY = 0; report.Report.wGyroZ = 0; report.Report.wAccelX = 0; report.Report.wAccelY = 0; report.Report.wAccelZ = 0; const VIGEM_ERROR ret = vigem_target_ds4_update_ex(client, ds4, report); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "DS4 update failed: 0x%08X\n", ret); ``` ``` -------------------------------- ### vigem_free Source: https://github.com/nefarius/vigemclient/wiki/vigem_free Frees up memory used by the driver connection object. Call `vigem_free` on the object returned by `vigem_alloc` when no longer required. ```APIDOC ## vigem_free ### Description Frees up memory used by the driver connection object. ### Parameters - **vigem** (PVIGEM_CLIENT) - A previously allocated PVIGEM_CLIENT object to free. ### Return Value None. ### Remarks Call `vigem_free` on the object returned by [`vigem_alloc`](vigem_alloc.md) when no longer required. ``` -------------------------------- ### Disconnect from ViGEmBus Driver Source: https://context7.com/nefarius/vigemclient/llms.txt Resets the driver connection and cleans up resources. All active virtual targets are automatically removed. Note that allocated target objects are not freed and must be managed separately using vigem_target_free. ```cpp // Cleanup sequence at application shutdown vigem_disconnect(client); vigem_free(client); // client handle is now invalid and must not be used ``` -------------------------------- ### vigem_target_remove Source: https://context7.com/nefarius/vigemclient/llms.txt Removes a virtual target device from the bus, simulating a physical unplug event. The target object can be reused after this call. If not explicitly called, the device is removed when the process terminates. ```APIDOC ## vigem_target_remove ### Description Removes the target device from the bus, equivalent to a physical unplug event. The target object may be reused after this call. If this is never called, the device is automatically removed when the owning process terminates. ### Method ```cpp const VIGEM_ERROR ret = vigem_target_remove(client, pad); ``` ### Parameters - `client`: A pointer to the `VIGEM_CLIENT` instance. - `pad`: A pointer to the `VIGEM_TARGET` representing the virtual device to remove. ### Return Value - `VIGEM_ERROR`: Indicates success or failure of the removal operation. `VIGEM_SUCCESS` on success, or an error code on failure. ### Request Example ```cpp const VIGEM_ERROR ret = vigem_target_remove(client, pad); if (!VIGEM_SUCCESS(ret)) fprintf(stderr, "Failed to remove target: 0x%08X\n", ret); ``` ```