mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-17 19:19:16 +01:00
vigem-sdvxio: Add implementation
This commit is contained in:
parent
1712f10f66
commit
164d56b6eb
66
Module.mk
66
Module.mk
@ -149,6 +149,8 @@ include src/main/security/Module.mk
|
||||
include src/main/unicorntail/Module.mk
|
||||
include src/main/util/Module.mk
|
||||
include src/main/vefxio/Module.mk
|
||||
include src/main/vigem-sdvxio/Module.mk
|
||||
include src/main/vigemstub/Module.mk
|
||||
|
||||
include src/test/cconfig/Module.mk
|
||||
include src/test/d3d9hook/Module.mk
|
||||
@ -202,11 +204,8 @@ $(zipdir)/iidx-09-to-12.zip: \
|
||||
build/bin/indep-32/iidxhook1.dll \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/iidx/config.bat \
|
||||
@ -230,11 +229,8 @@ $(zipdir)/iidx-13.zip: \
|
||||
build/bin/avs2_0-32/iidxhook2.dll \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/iidx/config.bat \
|
||||
@ -249,11 +245,8 @@ $(zipdir)/iidx-14-to-17.zip: \
|
||||
build/bin/avs2_0-32/iidxhook3.dll \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/iidx/config.bat \
|
||||
@ -275,11 +268,8 @@ $(zipdir)/iidx-18.zip: \
|
||||
build/bin/avs2_1101-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-18.bat \
|
||||
@ -294,11 +284,8 @@ $(zipdir)/iidx-19.zip: \
|
||||
build/bin/avs2_1304-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-19.bat \
|
||||
@ -313,11 +300,8 @@ $(zipdir)/iidx-20.zip: \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-20.bat \
|
||||
@ -332,11 +316,8 @@ $(zipdir)/iidx-21-to-24.zip: \
|
||||
build/bin/avs2_1601-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-21.bat \
|
||||
@ -357,11 +338,8 @@ $(zipdir)/iidx-25-to-26.zip: \
|
||||
build/bin/avs2_1700-64/launcher.exe \
|
||||
build/bin/indep-64/config.exe \
|
||||
build/bin/indep-64/eamio.dll \
|
||||
build/bin/indep-64/eamio-icca.dll \
|
||||
build/bin/indep-64/geninput.dll \
|
||||
build/bin/indep-64/iidxio.dll \
|
||||
build/bin/indep-64/iidxio-ezusb.dll \
|
||||
build/bin/indep-64/iidxio-ezusb2.dll \
|
||||
build/bin/indep-64/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-25.bat \
|
||||
@ -373,6 +351,22 @@ $(zipdir)/iidx-25-to-26.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/iidx-hwio-x86.zip: \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/iidx-hwio-x64.zip: \
|
||||
build/bin/indep-64/eamio-icca.dll \
|
||||
build/bin/indep-64/iidxio-ezusb.dll \
|
||||
build/bin/indep-64/iidxio-ezusb2.dll \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-01.zip: \
|
||||
build/bin/avs2_803-32/jbhook1.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
@ -420,8 +414,6 @@ $(zipdir)/sdvx-01-to-04.zip: \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/sdvxio.dll \
|
||||
build/bin/indep-32/sdvxio-kfca.dll \
|
||||
build/bin/indep-32/sdvxio-bio2.dll \
|
||||
dist/sdvx/config.bat \
|
||||
dist/sdvx/gamestart.bat \
|
||||
| $(zipdir)/
|
||||
@ -435,8 +427,6 @@ $(zipdir)/sdvx-05.zip: \
|
||||
build/bin/indep-64/eamio.dll \
|
||||
build/bin/indep-64/geninput.dll \
|
||||
build/bin/indep-64/sdvxio.dll \
|
||||
build/bin/indep-64/sdvxio-kfca.dll \
|
||||
build/bin/indep-64/sdvxio-bio2.dll \
|
||||
dist/sdvx5/config.bat \
|
||||
dist/sdvx5/gamestart.bat \
|
||||
dist/sdvx5/sdvxhook2.conf \
|
||||
@ -458,6 +448,22 @@ $(zipdir)/sdvx-05-cn.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/sdvx-hwio-x86.zip: \
|
||||
build/bin/indep-32/sdvxio-kfca.dll \
|
||||
build/bin/indep-32/sdvxio-bio2.dll \
|
||||
build/bin/indep-32/vigem-sdvxio.exe \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/sdvx-hwio-x64.zip: \
|
||||
build/bin/indep-64/sdvxio-kfca.dll \
|
||||
build/bin/indep-64/sdvxio-bio2.dll \
|
||||
build/bin/indep-64/vigem-sdvxio.exe \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/ddr-12-to-16.zip: \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/avs2_1508-32/ddrhook.dll \
|
||||
@ -556,12 +562,16 @@ $(BUILDDIR)/bemanitools.zip: \
|
||||
$(zipdir)/iidx-20.zip \
|
||||
$(zipdir)/iidx-21-to-24.zip \
|
||||
$(zipdir)/iidx-25-to-26.zip \
|
||||
$(zipdir)/iidx-hwio-x86.zip \
|
||||
$(zipdir)/iidx-hwio-x64.zip \
|
||||
$(zipdir)/jb-01.zip \
|
||||
$(zipdir)/jb-05-to-07.zip \
|
||||
$(zipdir)/jb-08.zip \
|
||||
$(zipdir)/sdvx-01-to-04.zip \
|
||||
$(zipdir)/sdvx-05.zip \
|
||||
$(zipdir)/sdvx-05-cn.zip \
|
||||
$(zipdir)/sdvx-hwio-x86.zip \
|
||||
$(zipdir)/sdvx-hwio-x64.zip \
|
||||
$(zipdir)/tools.zip \
|
||||
$(zipdir)/tools-x64.zip \
|
||||
CHANGELOG.md \
|
||||
|
519
src/imports/ViGEm/Client.h
Normal file
519
src/imports/ViGEm/Client.h
Normal file
@ -0,0 +1,519 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ViGEmClient_h__
|
||||
#define ViGEmClient_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ViGEm/Common.h"
|
||||
|
||||
#ifdef VIGEM_DYNAMIC
|
||||
#ifdef VIGEM_EXPORTS
|
||||
#define VIGEM_API __declspec(dllexport)
|
||||
#else
|
||||
#define VIGEM_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define VIGEM_API
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \typedef enum _VIGEM_ERRORS
|
||||
*
|
||||
* \brief Defines an alias representing the ViGEm errors.
|
||||
*/
|
||||
typedef enum _VIGEM_ERRORS {
|
||||
VIGEM_ERROR_NONE = 0x20000000,
|
||||
VIGEM_ERROR_BUS_NOT_FOUND = 0xE0000001,
|
||||
VIGEM_ERROR_NO_FREE_SLOT = 0xE0000002,
|
||||
VIGEM_ERROR_INVALID_TARGET = 0xE0000003,
|
||||
VIGEM_ERROR_REMOVAL_FAILED = 0xE0000004,
|
||||
VIGEM_ERROR_ALREADY_CONNECTED = 0xE0000005,
|
||||
VIGEM_ERROR_TARGET_UNINITIALIZED = 0xE0000006,
|
||||
VIGEM_ERROR_TARGET_NOT_PLUGGED_IN = 0xE0000007,
|
||||
VIGEM_ERROR_BUS_VERSION_MISMATCH = 0xE0000008,
|
||||
VIGEM_ERROR_BUS_ACCESS_FAILED = 0xE0000009,
|
||||
VIGEM_ERROR_CALLBACK_ALREADY_REGISTERED = 0xE0000010,
|
||||
VIGEM_ERROR_CALLBACK_NOT_FOUND = 0xE0000011,
|
||||
VIGEM_ERROR_BUS_ALREADY_CONNECTED = 0xE0000012,
|
||||
VIGEM_ERROR_BUS_INVALID_HANDLE = 0xE0000013,
|
||||
VIGEM_ERROR_XUSB_USERINDEX_OUT_OF_RANGE = 0xE0000014,
|
||||
VIGEM_ERROR_INVALID_PARAMETER = 0xE0000015
|
||||
|
||||
} VIGEM_ERROR;
|
||||
|
||||
/**
|
||||
* \def VIGEM_SUCCESS(_val_) (_val_ == VIGEM_ERROR_NONE);
|
||||
*
|
||||
* \brief A macro that defines success.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param _val_ The VIGEM_ERROR value.
|
||||
*/
|
||||
#define VIGEM_SUCCESS(_val_) (_val_ == VIGEM_ERROR_NONE)
|
||||
|
||||
/**
|
||||
* \typedef struct _VIGEM_CLIENT_T *PVIGEM_CLIENT
|
||||
*
|
||||
* \brief Defines an alias representing a driver connection object.
|
||||
*/
|
||||
typedef struct _VIGEM_CLIENT_T *PVIGEM_CLIENT;
|
||||
|
||||
/**
|
||||
* \typedef struct _VIGEM_TARGET_T *PVIGEM_TARGET
|
||||
*
|
||||
* \brief Defines an alias representing a target device object.
|
||||
*/
|
||||
typedef struct _VIGEM_TARGET_T *PVIGEM_TARGET;
|
||||
|
||||
typedef _Function_class_(EVT_VIGEM_TARGET_ADD_RESULT) VOID CALLBACK
|
||||
EVT_VIGEM_TARGET_ADD_RESULT(
|
||||
PVIGEM_CLIENT Client, PVIGEM_TARGET Target, VIGEM_ERROR Result);
|
||||
|
||||
typedef EVT_VIGEM_TARGET_ADD_RESULT *PFN_VIGEM_TARGET_ADD_RESULT;
|
||||
|
||||
typedef _Function_class_(EVT_VIGEM_X360_NOTIFICATION) VOID CALLBACK
|
||||
EVT_VIGEM_X360_NOTIFICATION(
|
||||
PVIGEM_CLIENT Client,
|
||||
PVIGEM_TARGET Target,
|
||||
UCHAR LargeMotor,
|
||||
UCHAR SmallMotor,
|
||||
UCHAR LedNumber,
|
||||
LPVOID UserData);
|
||||
|
||||
typedef EVT_VIGEM_X360_NOTIFICATION *PFN_VIGEM_X360_NOTIFICATION;
|
||||
|
||||
typedef _Function_class_(EVT_VIGEM_DS4_NOTIFICATION) VOID CALLBACK
|
||||
EVT_VIGEM_DS4_NOTIFICATION(
|
||||
PVIGEM_CLIENT Client,
|
||||
PVIGEM_TARGET Target,
|
||||
UCHAR LargeMotor,
|
||||
UCHAR SmallMotor,
|
||||
DS4_LIGHTBAR_COLOR LightbarColor,
|
||||
LPVOID UserData);
|
||||
|
||||
typedef EVT_VIGEM_DS4_NOTIFICATION *PFN_VIGEM_DS4_NOTIFICATION;
|
||||
|
||||
/**
|
||||
* \fn PVIGEM_CLIENT vigem_alloc(void);
|
||||
*
|
||||
* \brief Allocates an object representing a driver connection.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \return A new driver connection object.
|
||||
*/
|
||||
VIGEM_API PVIGEM_CLIENT vigem_alloc(void);
|
||||
|
||||
/**
|
||||
* \fn void vigem_free(PVIGEM_CLIENT vigem);
|
||||
*
|
||||
* \brief Frees up memory used by the driver connection object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
*/
|
||||
VIGEM_API void vigem_free(PVIGEM_CLIENT vigem);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_connect(PVIGEM_CLIENT vigem);
|
||||
*
|
||||
* \brief Initializes the driver object and establishes a connection to the
|
||||
* emulation bus driver. Returns an error if no compatible bus device has been
|
||||
* found.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_connect(PVIGEM_CLIENT vigem);
|
||||
|
||||
/**
|
||||
* \fn void vigem_disconnect(PVIGEM_CLIENT vigem);
|
||||
*
|
||||
* \brief Disconnects from the bus device and resets the driver object state.
|
||||
* The driver object may be reused again after calling this function. When
|
||||
* called, all targets which may still be connected will be destroyed
|
||||
* automatically. Be aware, that allocated target objects won't be automatically
|
||||
* freed, this has to be taken care of by the caller.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
*/
|
||||
VIGEM_API void vigem_disconnect(PVIGEM_CLIENT vigem);
|
||||
|
||||
/**
|
||||
* \fn PVIGEM_TARGET vigem_target_x360_alloc(void);
|
||||
*
|
||||
* \brief Allocates an object representing an Xbox 360 Controller device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \return A PVIGEM_TARGET representing an Xbox 360 Controller device.
|
||||
*/
|
||||
VIGEM_API PVIGEM_TARGET vigem_target_x360_alloc(void);
|
||||
|
||||
/**
|
||||
* \fn PVIGEM_TARGET vigem_target_ds4_alloc(void);
|
||||
*
|
||||
* \brief Allocates an object representing a DualShock 4 Controller device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \return A PVIGEM_TARGET representing a DualShock 4 Controller device.
|
||||
*/
|
||||
VIGEM_API PVIGEM_TARGET vigem_target_ds4_alloc(void);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_free(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Frees up memory used by the target device object. This does not
|
||||
* automatically remove the associated device from the bus, if present. If the
|
||||
* target device doesn't get removed before this call, the device becomes
|
||||
* orphaned until the owning process is terminated.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*/
|
||||
VIGEM_API void vigem_target_free(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_add(PVIGEM_CLIENT vigem, PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Adds a provided target device to the bus driver, which is equal to a
|
||||
* device plug-in event of a physical hardware device. This function blocks
|
||||
* until the target device is in full operational mode.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR
|
||||
vigem_target_add(PVIGEM_CLIENT vigem, PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_add_async(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target, PVIGEM_TARGET_ADD_RESULT result);
|
||||
*
|
||||
* \brief Adds a provided target device to the bus driver, which is equal to a
|
||||
* device plug-in event of a physical hardware device. This function immediately
|
||||
* returns. An optional callback may be registered which gets called on error or
|
||||
* if the target device has become fully operational.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param result An optional function getting called when the target device
|
||||
* becomes available.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_add_async(
|
||||
PVIGEM_CLIENT vigem,
|
||||
PVIGEM_TARGET target,
|
||||
PFN_VIGEM_TARGET_ADD_RESULT result);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_remove(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target);
|
||||
*
|
||||
* \brief Removes a provided target device from the bus driver, which is equal
|
||||
* to a device unplug event of a physical hardware device. The target device
|
||||
* object may be reused after this function is called. If this function is never
|
||||
* called on target device objects, they will be removed from the bus when the
|
||||
* owning process terminates.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR
|
||||
vigem_target_remove(PVIGEM_CLIENT vigem, PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_x360_register_notification(PVIGEM_CLIENT vigem,
|
||||
* PVIGEM_TARGET target, PVIGEM_X360_NOTIFICATION notification);
|
||||
*
|
||||
* \brief Registers a function which gets called, when LED index or vibration
|
||||
* state changes occur on the provided target device. This function fails if the
|
||||
* provided target device isn't fully operational or in an erroneous state.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param notification The notification callback.
|
||||
* \param userData The user data passed to the notification callback.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_x360_register_notification(
|
||||
PVIGEM_CLIENT vigem,
|
||||
PVIGEM_TARGET target,
|
||||
PFN_VIGEM_X360_NOTIFICATION notification,
|
||||
LPVOID userData);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_ds4_register_notification(PVIGEM_CLIENT vigem,
|
||||
* PVIGEM_TARGET target, PVIGEM_DS4_NOTIFICATION notification);
|
||||
*
|
||||
* \brief Registers a function which gets called, when LightBar or vibration
|
||||
* state changes occur on the provided target device. This function fails if the
|
||||
* provided target device isn't fully operational or in an erroneous state.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param notification The notification callback.
|
||||
* \param userData The user data passed to the notification callback.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_ds4_register_notification(
|
||||
PVIGEM_CLIENT vigem,
|
||||
PVIGEM_TARGET target,
|
||||
PFN_VIGEM_DS4_NOTIFICATION notification,
|
||||
LPVOID userData);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_x360_unregister_notification(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Removes a previously registered callback function from the provided
|
||||
* target object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*/
|
||||
VIGEM_API void vigem_target_x360_unregister_notification(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_ds4_unregister_notification(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Removes a previously registered callback function from the provided
|
||||
* target object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*/
|
||||
VIGEM_API void vigem_target_ds4_unregister_notification(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_set_vid(PVIGEM_TARGET target, USHORT vid);
|
||||
*
|
||||
* \brief Overrides the default Vendor ID value with the provided one.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
* \param vid The Vendor ID to set.
|
||||
*/
|
||||
VIGEM_API void vigem_target_set_vid(PVIGEM_TARGET target, USHORT vid);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_set_pid(PVIGEM_TARGET target, USHORT pid);
|
||||
*
|
||||
* \brief Overrides the default Product ID value with the provided one.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
* \param pid The Product ID to set.
|
||||
*/
|
||||
VIGEM_API void vigem_target_set_pid(PVIGEM_TARGET target, USHORT pid);
|
||||
|
||||
/**
|
||||
* \fn USHORT vigem_target_get_vid(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the Vendor ID of the provided target device object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return The Vendor ID.
|
||||
*/
|
||||
VIGEM_API USHORT vigem_target_get_vid(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn USHORT vigem_target_get_pid(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the Product ID of the provided target device object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return The Product ID.
|
||||
*/
|
||||
VIGEM_API USHORT vigem_target_get_pid(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_x360_update(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target, XUSB_REPORT report);
|
||||
*
|
||||
* \brief Sends a state report to the provided target device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param report The report to send to the target device.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_x360_update(
|
||||
PVIGEM_CLIENT vigem, PVIGEM_TARGET target, XUSB_REPORT report);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_ds4_update(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target, DS4_REPORT report);
|
||||
*
|
||||
* \brief Sends a state report to the provided target device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param report The report to send to the target device.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_ds4_update(
|
||||
PVIGEM_CLIENT vigem, PVIGEM_TARGET target, DS4_REPORT report);
|
||||
|
||||
/**
|
||||
* \fn ULONG vigem_target_get_index(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the internal index (serial number) the bus driver assigned
|
||||
* to the provided target device object. Note that this value is specific to the
|
||||
* inner workings of the bus driver, it does not reflect related values like
|
||||
* player index or device arrival order experienced by other APIs. It may be
|
||||
* used to identify the target device object for its lifetime. This value
|
||||
* becomes invalid once the target device is removed from the bus and may change
|
||||
* on the next addition of the device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return The internally used index of the target device.
|
||||
*/
|
||||
VIGEM_API ULONG vigem_target_get_index(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_TARGET_TYPE vigem_target_get_type(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the type of the provided target device object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return A VIGEM_TARGET_TYPE.
|
||||
*/
|
||||
VIGEM_API VIGEM_TARGET_TYPE vigem_target_get_type(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn BOOL vigem_target_is_attached(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns TRUE if the provided target device object is currently
|
||||
* attached to the bus, FALSE otherwise.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 30.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return TRUE if device is attached to the bus, FALSE otherwise.
|
||||
*/
|
||||
VIGEM_API BOOL vigem_target_is_attached(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_API VIGEM_ERROR vigem_target_x360_get_user_index(PVIGEM_CLIENT
|
||||
* vigem, PVIGEM_TARGET target, PULONG index);
|
||||
*
|
||||
* \brief Returns the user index of the emulated Xenon device. This value
|
||||
* correspondents to the (zero-based) index number representing the player
|
||||
* number via LED present on a physical controller and is compatible to the
|
||||
* dwUserIndex propery of the XInput* APIs.
|
||||
*
|
||||
* \author Benjamin "Nefarius" Höglinger
|
||||
* \date 10.05.2018
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param index The (zero-based) user index of the Xenon device.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_x360_get_user_index(
|
||||
PVIGEM_CLIENT vigem, PVIGEM_TARGET target, PULONG index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ViGEmClient_h__
|
191
src/imports/ViGEm/Common.h
Normal file
191
src/imports/ViGEm/Common.h
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Represents the desired target type for the emulated device.
|
||||
//
|
||||
typedef enum _VIGEM_TARGET_TYPE {
|
||||
//
|
||||
// Microsoft Xbox 360 Controller (wired)
|
||||
//
|
||||
Xbox360Wired = 0,
|
||||
//
|
||||
// Sony DualShock 4 (wired)
|
||||
//
|
||||
DualShock4Wired = 2 // NOTE: 1 skipped on purpose to maintain compatibility
|
||||
|
||||
} VIGEM_TARGET_TYPE,
|
||||
*PVIGEM_TARGET_TYPE;
|
||||
|
||||
//
|
||||
// Possible XUSB report buttons.
|
||||
//
|
||||
typedef enum _XUSB_BUTTON {
|
||||
XUSB_GAMEPAD_DPAD_UP = 0x0001,
|
||||
XUSB_GAMEPAD_DPAD_DOWN = 0x0002,
|
||||
XUSB_GAMEPAD_DPAD_LEFT = 0x0004,
|
||||
XUSB_GAMEPAD_DPAD_RIGHT = 0x0008,
|
||||
XUSB_GAMEPAD_START = 0x0010,
|
||||
XUSB_GAMEPAD_BACK = 0x0020,
|
||||
XUSB_GAMEPAD_LEFT_THUMB = 0x0040,
|
||||
XUSB_GAMEPAD_RIGHT_THUMB = 0x0080,
|
||||
XUSB_GAMEPAD_LEFT_SHOULDER = 0x0100,
|
||||
XUSB_GAMEPAD_RIGHT_SHOULDER = 0x0200,
|
||||
XUSB_GAMEPAD_GUIDE = 0x0400,
|
||||
XUSB_GAMEPAD_A = 0x1000,
|
||||
XUSB_GAMEPAD_B = 0x2000,
|
||||
XUSB_GAMEPAD_X = 0x4000,
|
||||
XUSB_GAMEPAD_Y = 0x8000
|
||||
|
||||
} XUSB_BUTTON,
|
||||
*PXUSB_BUTTON;
|
||||
|
||||
//
|
||||
// Represents an XINPUT_GAMEPAD-compatible report structure.
|
||||
//
|
||||
typedef struct _XUSB_REPORT {
|
||||
USHORT wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
|
||||
} XUSB_REPORT, *PXUSB_REPORT;
|
||||
|
||||
//
|
||||
// Initializes a _XUSB_REPORT structure.
|
||||
//
|
||||
VOID FORCEINLINE XUSB_REPORT_INIT(_Out_ PXUSB_REPORT Report)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(XUSB_REPORT));
|
||||
}
|
||||
|
||||
//
|
||||
// The color value (RGB) of a DualShock 4 Lightbar
|
||||
//
|
||||
typedef struct _DS4_LIGHTBAR_COLOR {
|
||||
//
|
||||
// Red part of the Lightbar (0-255).
|
||||
//
|
||||
UCHAR Red;
|
||||
|
||||
//
|
||||
// Green part of the Lightbar (0-255).
|
||||
//
|
||||
UCHAR Green;
|
||||
|
||||
//
|
||||
// Blue part of the Lightbar (0-255).
|
||||
//
|
||||
UCHAR Blue;
|
||||
|
||||
} DS4_LIGHTBAR_COLOR, *PDS4_LIGHTBAR_COLOR;
|
||||
|
||||
//
|
||||
// DualShock 4 digital buttons
|
||||
//
|
||||
typedef enum _DS4_BUTTONS {
|
||||
DS4_BUTTON_THUMB_RIGHT = 1 << 15,
|
||||
DS4_BUTTON_THUMB_LEFT = 1 << 14,
|
||||
DS4_BUTTON_OPTIONS = 1 << 13,
|
||||
DS4_BUTTON_SHARE = 1 << 12,
|
||||
DS4_BUTTON_TRIGGER_RIGHT = 1 << 11,
|
||||
DS4_BUTTON_TRIGGER_LEFT = 1 << 10,
|
||||
DS4_BUTTON_SHOULDER_RIGHT = 1 << 9,
|
||||
DS4_BUTTON_SHOULDER_LEFT = 1 << 8,
|
||||
DS4_BUTTON_TRIANGLE = 1 << 7,
|
||||
DS4_BUTTON_CIRCLE = 1 << 6,
|
||||
DS4_BUTTON_CROSS = 1 << 5,
|
||||
DS4_BUTTON_SQUARE = 1 << 4
|
||||
|
||||
} DS4_BUTTONS,
|
||||
*PDS4_BUTTONS;
|
||||
|
||||
//
|
||||
// DualShock 4 special buttons
|
||||
//
|
||||
typedef enum _DS4_SPECIAL_BUTTONS {
|
||||
DS4_SPECIAL_BUTTON_PS = 1 << 0,
|
||||
DS4_SPECIAL_BUTTON_TOUCHPAD = 1 << 1
|
||||
|
||||
} DS4_SPECIAL_BUTTONS,
|
||||
*PDS4_SPECIAL_BUTTONS;
|
||||
|
||||
//
|
||||
// DualShock 4 directional pad (HAT) values
|
||||
//
|
||||
typedef enum _DS4_DPAD_DIRECTIONS {
|
||||
DS4_BUTTON_DPAD_NONE = 0x8,
|
||||
DS4_BUTTON_DPAD_NORTHWEST = 0x7,
|
||||
DS4_BUTTON_DPAD_WEST = 0x6,
|
||||
DS4_BUTTON_DPAD_SOUTHWEST = 0x5,
|
||||
DS4_BUTTON_DPAD_SOUTH = 0x4,
|
||||
DS4_BUTTON_DPAD_SOUTHEAST = 0x3,
|
||||
DS4_BUTTON_DPAD_EAST = 0x2,
|
||||
DS4_BUTTON_DPAD_NORTHEAST = 0x1,
|
||||
DS4_BUTTON_DPAD_NORTH = 0x0
|
||||
|
||||
} DS4_DPAD_DIRECTIONS,
|
||||
*PDS4_DPAD_DIRECTIONS;
|
||||
|
||||
//
|
||||
// DualShock 4 HID Input report
|
||||
//
|
||||
typedef struct _DS4_REPORT {
|
||||
BYTE bThumbLX;
|
||||
BYTE bThumbLY;
|
||||
BYTE bThumbRX;
|
||||
BYTE bThumbRY;
|
||||
USHORT wButtons;
|
||||
BYTE bSpecial;
|
||||
BYTE bTriggerL;
|
||||
BYTE bTriggerR;
|
||||
|
||||
} DS4_REPORT, *PDS4_REPORT;
|
||||
|
||||
//
|
||||
// Sets the current state of the D-PAD on a DualShock 4 report.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
DS4_SET_DPAD(_Out_ PDS4_REPORT Report, _In_ DS4_DPAD_DIRECTIONS Dpad)
|
||||
{
|
||||
Report->wButtons &= ~0xF;
|
||||
Report->wButtons |= (USHORT) Dpad;
|
||||
}
|
||||
|
||||
VOID FORCEINLINE DS4_REPORT_INIT(_Out_ PDS4_REPORT Report)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(DS4_REPORT));
|
||||
|
||||
Report->bThumbLX = 0x80;
|
||||
Report->bThumbLY = 0x80;
|
||||
Report->bThumbRX = 0x80;
|
||||
Report->bThumbRY = 0x80;
|
||||
|
||||
DS4_SET_DPAD(Report, DS4_BUTTON_DPAD_NONE);
|
||||
}
|
68
src/imports/ViGEm/Util.h
Normal file
68
src/imports/ViGEm/Util.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "ViGEm/Common.h"
|
||||
#include <limits.h>
|
||||
|
||||
VOID FORCEINLINE
|
||||
XUSB_TO_DS4_REPORT(_Out_ PXUSB_REPORT Input, _Out_ PDS4_REPORT Output)
|
||||
{
|
||||
if (Input->wButtons & XUSB_GAMEPAD_BACK)
|
||||
Output->wButtons |= DS4_BUTTON_SHARE;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_START)
|
||||
Output->wButtons |= DS4_BUTTON_OPTIONS;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_LEFT_THUMB)
|
||||
Output->wButtons |= DS4_BUTTON_THUMB_LEFT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_RIGHT_THUMB)
|
||||
Output->wButtons |= DS4_BUTTON_THUMB_RIGHT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_LEFT_SHOULDER)
|
||||
Output->wButtons |= DS4_BUTTON_SHOULDER_LEFT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_RIGHT_SHOULDER)
|
||||
Output->wButtons |= DS4_BUTTON_SHOULDER_RIGHT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_GUIDE)
|
||||
Output->bSpecial |= DS4_SPECIAL_BUTTON_PS;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_A)
|
||||
Output->wButtons |= DS4_BUTTON_CROSS;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_B)
|
||||
Output->wButtons |= DS4_BUTTON_CIRCLE;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_X)
|
||||
Output->wButtons |= DS4_BUTTON_SQUARE;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_Y)
|
||||
Output->wButtons |= DS4_BUTTON_TRIANGLE;
|
||||
|
||||
Output->bTriggerL = Input->bLeftTrigger;
|
||||
Output->bTriggerR = Input->bRightTrigger;
|
||||
|
||||
if (Input->bLeftTrigger > 0)
|
||||
Output->wButtons |= DS4_BUTTON_TRIGGER_LEFT;
|
||||
if (Input->bRightTrigger > 0)
|
||||
Output->wButtons |= DS4_BUTTON_TRIGGER_RIGHT;
|
||||
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_UP)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_NORTH);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_RIGHT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_EAST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_DOWN)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_SOUTH);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_LEFT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_WEST);
|
||||
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_UP &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_RIGHT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_NORTHEAST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_RIGHT &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_DOWN)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_SOUTHEAST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_DOWN &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_LEFT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_SOUTHWEST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_LEFT &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_UP)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_NORTHWEST);
|
||||
|
||||
Output->bThumbLX = ((Input->sThumbLX + ((USHRT_MAX / 2) + 1)) / 257);
|
||||
Output->bThumbLY = (-(Input->sThumbLY + ((USHRT_MAX / 2) - 1)) / 257);
|
||||
Output->bThumbLY = (Output->bThumbLY == 0) ? 0xFF : Output->bThumbLY;
|
||||
Output->bThumbRX = ((Input->sThumbRX + ((USHRT_MAX / 2) + 1)) / 257);
|
||||
Output->bThumbRY = (-(Input->sThumbRY + ((USHRT_MAX / 2) + 1)) / 257);
|
||||
Output->bThumbRY = (Output->bThumbRY == 0) ? 0xFF : Output->bThumbRY;
|
||||
}
|
399
src/imports/ViGEm/km/BusShared.h
Normal file
399
src/imports/ViGEm/km/BusShared.h
Normal file
@ -0,0 +1,399 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// GUID identifying the bus device. Used by client library to detect and
|
||||
// communicate.
|
||||
//
|
||||
// IMPORTANT: make sure to change this value if you fork it or introduce
|
||||
// breaking changes!
|
||||
//
|
||||
// {96E42B22-F5E9-42F8-B043-ED0F932F014F}
|
||||
DEFINE_GUID(
|
||||
GUID_DEVINTERFACE_BUSENUM_VIGEM,
|
||||
0x96E42B22,
|
||||
0xF5E9,
|
||||
0x42F8,
|
||||
0xB0,
|
||||
0x43,
|
||||
0xED,
|
||||
0x0F,
|
||||
0x93,
|
||||
0x2F,
|
||||
0x01,
|
||||
0x4F);
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ViGEm/Common.h"
|
||||
|
||||
//
|
||||
// Common version for user-mode library and driver compatibility
|
||||
//
|
||||
// On initialization, the user-mode library has this number embedded
|
||||
// and sends it to the bus on its enumeration. The bus compares this
|
||||
// number to the one it was compiled with. If they match, the bus
|
||||
// access is permitted and success reported. If they mismatch, an
|
||||
// error is reported and the user-mode library skips this instance.
|
||||
//
|
||||
#define VIGEM_COMMON_VERSION 0x0001
|
||||
|
||||
#define FILE_DEVICE_BUSENUM FILE_DEVICE_BUS_EXTENDER
|
||||
#define BUSENUM_IOCTL(_index_) \
|
||||
CTL_CODE(FILE_DEVICE_BUSENUM, _index_, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
#define BUSENUM_W_IOCTL(_index_) \
|
||||
CTL_CODE(FILE_DEVICE_BUSENUM, _index_, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
#define BUSENUM_R_IOCTL(_index_) \
|
||||
CTL_CODE(FILE_DEVICE_BUSENUM, _index_, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
#define BUSENUM_RW_IOCTL(_index_) \
|
||||
CTL_CODE( \
|
||||
FILE_DEVICE_BUSENUM, \
|
||||
_index_, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_WRITE_DATA | FILE_READ_DATA)
|
||||
|
||||
#define IOCTL_VIGEM_BASE 0x801
|
||||
|
||||
//
|
||||
// IO control codes
|
||||
//
|
||||
#define IOCTL_VIGEM_PLUGIN_TARGET BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x000)
|
||||
#define IOCTL_VIGEM_UNPLUG_TARGET BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x001)
|
||||
#define IOCTL_VIGEM_CHECK_VERSION BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x002)
|
||||
|
||||
#define IOCTL_XUSB_REQUEST_NOTIFICATION \
|
||||
BUSENUM_RW_IOCTL(IOCTL_VIGEM_BASE + 0x200)
|
||||
#define IOCTL_XUSB_SUBMIT_REPORT BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x201)
|
||||
#define IOCTL_DS4_SUBMIT_REPORT BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x202)
|
||||
#define IOCTL_DS4_REQUEST_NOTIFICATION BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x203)
|
||||
//#define IOCTL_XGIP_SUBMIT_REPORT BUSENUM_W_IOCTL (IOCTL_VIGEM_BASE +
|
||||
//0x204) #define IOCTL_XGIP_SUBMIT_INTERRUPT BUSENUM_W_IOCTL
|
||||
//(IOCTL_VIGEM_BASE + 0x205)
|
||||
#define IOCTL_XUSB_GET_USER_INDEX BUSENUM_RW_IOCTL(IOCTL_VIGEM_BASE + 0x206)
|
||||
|
||||
//
|
||||
// Data structure used in PlugIn and UnPlug ioctls
|
||||
//
|
||||
|
||||
#pragma region Plugin
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_VIGEM_PLUGIN_TARGET requests.
|
||||
//
|
||||
typedef struct _VIGEM_PLUGIN_TARGET {
|
||||
//
|
||||
// sizeof (struct _BUSENUM_HARDWARE)
|
||||
//
|
||||
IN ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
IN ULONG SerialNo;
|
||||
|
||||
//
|
||||
// Type of the target device to emulate.
|
||||
//
|
||||
VIGEM_TARGET_TYPE TargetType;
|
||||
|
||||
//
|
||||
// If set, the vendor ID the emulated device is reporting
|
||||
//
|
||||
USHORT VendorId;
|
||||
|
||||
//
|
||||
// If set, the product ID the emulated device is reporting
|
||||
//
|
||||
USHORT ProductId;
|
||||
|
||||
} VIGEM_PLUGIN_TARGET, *PVIGEM_PLUGIN_TARGET;
|
||||
|
||||
//
|
||||
// Initializes a VIGEM_PLUGIN_TARGET structure.
|
||||
//
|
||||
VOID FORCEINLINE VIGEM_PLUGIN_TARGET_INIT(
|
||||
_Out_ PVIGEM_PLUGIN_TARGET PlugIn,
|
||||
_In_ ULONG SerialNo,
|
||||
_In_ VIGEM_TARGET_TYPE TargetType)
|
||||
{
|
||||
RtlZeroMemory(PlugIn, sizeof(VIGEM_PLUGIN_TARGET));
|
||||
|
||||
PlugIn->Size = sizeof(VIGEM_PLUGIN_TARGET);
|
||||
PlugIn->SerialNo = SerialNo;
|
||||
PlugIn->TargetType = TargetType;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Unplug
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_VIGEM_UNPLUG_TARGET requests.
|
||||
//
|
||||
typedef struct _VIGEM_UNPLUG_TARGET {
|
||||
//
|
||||
// sizeof (struct _REMOVE_HARDWARE)
|
||||
//
|
||||
IN ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
} VIGEM_UNPLUG_TARGET, *PVIGEM_UNPLUG_TARGET;
|
||||
|
||||
//
|
||||
// Initializes a VIGEM_UNPLUG_TARGET structure.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
VIGEM_UNPLUG_TARGET_INIT(_Out_ PVIGEM_UNPLUG_TARGET UnPlug, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(UnPlug, sizeof(VIGEM_UNPLUG_TARGET));
|
||||
|
||||
UnPlug->Size = sizeof(VIGEM_UNPLUG_TARGET);
|
||||
UnPlug->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Check version
|
||||
|
||||
typedef struct _VIGEM_CHECK_VERSION {
|
||||
IN ULONG Size;
|
||||
|
||||
IN ULONG Version;
|
||||
|
||||
} VIGEM_CHECK_VERSION, *PVIGEM_CHECK_VERSION;
|
||||
|
||||
VOID FORCEINLINE VIGEM_CHECK_VERSION_INIT(
|
||||
_Out_ PVIGEM_CHECK_VERSION CheckVersion, _In_ ULONG Version)
|
||||
{
|
||||
RtlZeroMemory(CheckVersion, sizeof(VIGEM_CHECK_VERSION));
|
||||
|
||||
CheckVersion->Size = sizeof(VIGEM_CHECK_VERSION);
|
||||
CheckVersion->Version = Version;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region XUSB(aka Xbox 360 device) section
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_XUSB_REQUEST_NOTIFICATION requests.
|
||||
//
|
||||
typedef struct _XUSB_REQUEST_NOTIFICATION {
|
||||
//
|
||||
// sizeof(struct _XUSB_REQUEST_NOTIFICATION)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// Vibration intensity value of the large motor (0-255).
|
||||
//
|
||||
UCHAR LargeMotor;
|
||||
|
||||
//
|
||||
// Vibration intensity value of the small motor (0-255).
|
||||
//
|
||||
UCHAR SmallMotor;
|
||||
|
||||
//
|
||||
// Index number of the slot/LED that XUSB.sys has assigned.
|
||||
//
|
||||
UCHAR LedNumber;
|
||||
|
||||
} XUSB_REQUEST_NOTIFICATION, *PXUSB_REQUEST_NOTIFICATION;
|
||||
|
||||
//
|
||||
// Initializes a XUSB_REQUEST_NOTIFICATION structure.
|
||||
//
|
||||
VOID FORCEINLINE XUSB_REQUEST_NOTIFICATION_INIT(
|
||||
_Out_ PXUSB_REQUEST_NOTIFICATION Request, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Request, sizeof(XUSB_REQUEST_NOTIFICATION));
|
||||
|
||||
Request->Size = sizeof(XUSB_REQUEST_NOTIFICATION);
|
||||
Request->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_XUSB_SUBMIT_REPORT requests.
|
||||
//
|
||||
typedef struct _XUSB_SUBMIT_REPORT {
|
||||
//
|
||||
// sizeof(struct _XUSB_SUBMIT_REPORT)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// Report to submit to the target device.
|
||||
//
|
||||
XUSB_REPORT Report;
|
||||
|
||||
} XUSB_SUBMIT_REPORT, *PXUSB_SUBMIT_REPORT;
|
||||
|
||||
//
|
||||
// Initializes an XUSB report.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
XUSB_SUBMIT_REPORT_INIT(_Out_ PXUSB_SUBMIT_REPORT Report, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(XUSB_SUBMIT_REPORT));
|
||||
|
||||
Report->Size = sizeof(XUSB_SUBMIT_REPORT);
|
||||
Report->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
typedef struct _XUSB_GET_USER_INDEX {
|
||||
//
|
||||
// sizeof(struct _XUSB_GET_USER_INDEX)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// User index of target device.
|
||||
//
|
||||
OUT ULONG UserIndex;
|
||||
|
||||
} XUSB_GET_USER_INDEX, *PXUSB_GET_USER_INDEX;
|
||||
|
||||
//
|
||||
// Initializes XUSB_GET_USER_INDEX structure.
|
||||
//
|
||||
VOID FORCEINLINE XUSB_GET_USER_INDEX_INIT(
|
||||
_Out_ PXUSB_GET_USER_INDEX GetRequest, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(GetRequest, sizeof(XUSB_GET_USER_INDEX));
|
||||
|
||||
GetRequest->Size = sizeof(XUSB_GET_USER_INDEX);
|
||||
GetRequest->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region DualShock 4 section
|
||||
|
||||
typedef struct _DS4_OUTPUT_REPORT {
|
||||
//
|
||||
// Vibration intensity value of the small motor (0-255).
|
||||
//
|
||||
UCHAR SmallMotor;
|
||||
|
||||
//
|
||||
// Vibration intensity value of the large motor (0-255).
|
||||
//
|
||||
UCHAR LargeMotor;
|
||||
|
||||
//
|
||||
// Color values of the Lightbar.
|
||||
//
|
||||
DS4_LIGHTBAR_COLOR LightbarColor;
|
||||
|
||||
} DS4_OUTPUT_REPORT, *PDS4_OUTPUT_REPORT;
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_DS4_REQUEST_NOTIFICATION requests.
|
||||
//
|
||||
typedef struct _DS4_REQUEST_NOTIFICATION {
|
||||
//
|
||||
// sizeof(struct _XUSB_REQUEST_NOTIFICATION)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// The HID output report
|
||||
//
|
||||
DS4_OUTPUT_REPORT Report;
|
||||
|
||||
} DS4_REQUEST_NOTIFICATION, *PDS4_REQUEST_NOTIFICATION;
|
||||
|
||||
//
|
||||
// Initializes a DS4_REQUEST_NOTIFICATION structure.
|
||||
//
|
||||
VOID FORCEINLINE DS4_REQUEST_NOTIFICATION_INIT(
|
||||
_Out_ PDS4_REQUEST_NOTIFICATION Request, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Request, sizeof(DS4_REQUEST_NOTIFICATION));
|
||||
|
||||
Request->Size = sizeof(DS4_REQUEST_NOTIFICATION);
|
||||
Request->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
//
|
||||
// DualShock 4 request data
|
||||
//
|
||||
typedef struct _DS4_SUBMIT_REPORT {
|
||||
//
|
||||
// sizeof(struct _DS4_SUBMIT_REPORT)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// HID Input report
|
||||
//
|
||||
DS4_REPORT Report;
|
||||
|
||||
} DS4_SUBMIT_REPORT, *PDS4_SUBMIT_REPORT;
|
||||
|
||||
//
|
||||
// Initializes a DualShock 4 report.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
DS4_SUBMIT_REPORT_INIT(_Out_ PDS4_SUBMIT_REPORT Report, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(DS4_SUBMIT_REPORT));
|
||||
|
||||
Report->Size = sizeof(DS4_SUBMIT_REPORT);
|
||||
Report->SerialNo = SerialNo;
|
||||
|
||||
DS4_REPORT_INIT(&Report->Report);
|
||||
}
|
||||
|
||||
#pragma endregion
|
27
src/imports/import_32_indep_ViGEmClient.def
Normal file
27
src/imports/import_32_indep_ViGEmClient.def
Normal file
@ -0,0 +1,27 @@
|
||||
LIBRARY ViGEmClient
|
||||
|
||||
EXPORTS
|
||||
vigem_alloc
|
||||
vigem_connect
|
||||
vigem_disconnect
|
||||
vigem_free
|
||||
vigem_target_add
|
||||
vigem_target_add_async
|
||||
vigem_target_ds4_alloc
|
||||
vigem_target_ds4_register_notification
|
||||
vigem_target_ds4_unregister_notification
|
||||
vigem_target_ds4_update
|
||||
vigem_target_free
|
||||
vigem_target_get_index
|
||||
vigem_target_get_pid
|
||||
vigem_target_get_type
|
||||
vigem_target_get_vid
|
||||
vigem_target_is_attached
|
||||
vigem_target_remove
|
||||
vigem_target_set_pid
|
||||
vigem_target_set_vid
|
||||
vigem_target_x360_alloc
|
||||
vigem_target_x360_get_user_index
|
||||
vigem_target_x360_register_notification
|
||||
vigem_target_x360_unregister_notification
|
||||
vigem_target_x360_update
|
27
src/imports/import_64_indep_ViGEmClient.def
Normal file
27
src/imports/import_64_indep_ViGEmClient.def
Normal file
@ -0,0 +1,27 @@
|
||||
LIBRARY ViGEmClient
|
||||
|
||||
EXPORTS
|
||||
vigem_alloc
|
||||
vigem_connect
|
||||
vigem_disconnect
|
||||
vigem_free
|
||||
vigem_target_add
|
||||
vigem_target_add_async
|
||||
vigem_target_ds4_alloc
|
||||
vigem_target_ds4_register_notification
|
||||
vigem_target_ds4_unregister_notification
|
||||
vigem_target_ds4_update
|
||||
vigem_target_free
|
||||
vigem_target_get_index
|
||||
vigem_target_get_pid
|
||||
vigem_target_get_type
|
||||
vigem_target_get_vid
|
||||
vigem_target_is_attached
|
||||
vigem_target_remove
|
||||
vigem_target_set_pid
|
||||
vigem_target_set_vid
|
||||
vigem_target_x360_alloc
|
||||
vigem_target_x360_get_user_index
|
||||
vigem_target_x360_register_notification
|
||||
vigem_target_x360_unregister_notification
|
||||
vigem_target_x360_update
|
20
src/main/vigem-sdvxio/Module.mk
Normal file
20
src/main/vigem-sdvxio/Module.mk
Normal file
@ -0,0 +1,20 @@
|
||||
exes += vigem-sdvxio
|
||||
|
||||
deplibs_vigem-sdvxio := \
|
||||
ViGEmClient \
|
||||
|
||||
cppflags_vigem-sdvxio := \
|
||||
-I src/imports \
|
||||
|
||||
ldflags_vigem-sdvxio := \
|
||||
-lsetupapi \
|
||||
|
||||
libs_vigem-sdvxio := \
|
||||
cconfig \
|
||||
sdvxio \
|
||||
util \
|
||||
vigemstub \
|
||||
|
||||
src_vigem-sdvxio := \
|
||||
main.c \
|
||||
config-vigem-sdvxio.c \
|
128
src/main/vigem-sdvxio/config-vigem-sdvxio.c
Normal file
128
src/main/vigem-sdvxio/config-vigem-sdvxio.c
Normal file
@ -0,0 +1,128 @@
|
||||
#include "cconfig/cconfig-main.h"
|
||||
#include "cconfig/cconfig-util.h"
|
||||
|
||||
#include "vigem-sdvxio/config-vigem-sdvxio.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#define VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY "sdvxio.enable_keylight"
|
||||
#define VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY "sdvxio.pwm_wings"
|
||||
#define VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY "sdvxio.pwm_controller"
|
||||
#define VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY "sdvxio.amp_volume"
|
||||
|
||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE true
|
||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE 128
|
||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE 64
|
||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE 48
|
||||
|
||||
void vigem_sdvxio_config_init(struct cconfig *config)
|
||||
{
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE,
|
||||
"Enable input based key lighting");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE,
|
||||
"Brightness to set wings to (0-255)");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE,
|
||||
"Brightness to set control deck to (0-255)");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE,
|
||||
"SDVXIO digital amp volume (0-96) 0 is high, 96 is low.");
|
||||
}
|
||||
|
||||
void vigem_sdvxio_config_get(
|
||||
struct vigem_sdvxio_config *vigem_config, struct cconfig *config)
|
||||
{
|
||||
if (!cconfig_util_get_bool(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
&vigem_config->enable_keylight,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
||||
&vigem_config->pwm_wings,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY,
|
||||
&vigem_config->pwm_controller,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY,
|
||||
&vigem_config->amp_volume,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out)
|
||||
{
|
||||
struct cconfig *config;
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
vigem_sdvxio_config_init(config);
|
||||
|
||||
if (!cconfig_main_config_init(
|
||||
config,
|
||||
"--config",
|
||||
"vigem-sdvxio.conf",
|
||||
"--help",
|
||||
"-h",
|
||||
"vigem-sdvxio",
|
||||
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
|
||||
cconfig_finit(config);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
vigem_sdvxio_config_get(config_out, config);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
if (config_out->pwm_controller > 255) {
|
||||
config_out->pwm_controller = 255;
|
||||
}
|
||||
|
||||
if (config_out->pwm_wings > 255) {
|
||||
config_out->pwm_wings = 255;
|
||||
}
|
||||
}
|
17
src/main/vigem-sdvxio/config-vigem-sdvxio.h
Normal file
17
src/main/vigem-sdvxio/config-vigem-sdvxio.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef VIGEM_SDVXIO_CONFIG_H
|
||||
#define VIGEM_SDVXIO_CONFIG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "cconfig/cconfig.h"
|
||||
|
||||
struct vigem_sdvxio_config {
|
||||
bool enable_keylight;
|
||||
int32_t pwm_wings;
|
||||
int32_t pwm_controller;
|
||||
int32_t amp_volume;
|
||||
};
|
||||
|
||||
void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out);
|
||||
|
||||
#endif
|
183
src/main/vigem-sdvxio/main.c
Normal file
183
src/main/vigem-sdvxio/main.c
Normal file
@ -0,0 +1,183 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Xinput.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "ViGEm/Client.h"
|
||||
|
||||
#include "bemanitools/sdvxio.h"
|
||||
#include "util/log.h"
|
||||
#include "util/thread.h"
|
||||
#include "vigemstub/helper.h"
|
||||
|
||||
#include "vigem-sdvxio/config-vigem-sdvxio.h"
|
||||
|
||||
int64_t convert_analog_to_s16(uint16_t val)
|
||||
{
|
||||
// val is 10 bit
|
||||
return (int64_t)(val * 64);
|
||||
}
|
||||
|
||||
bool check_key(uint16_t input, size_t idx_in)
|
||||
{
|
||||
if ((input >> idx_in) & 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t check_assign_key(uint16_t input, size_t idx_in, size_t bit_out)
|
||||
{
|
||||
if (check_key(input, idx_in)) {
|
||||
return bit_out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t check_assign_gpio(uint16_t input, size_t idx_in, size_t gpio_out)
|
||||
{
|
||||
if (check_key(input, idx_in)) {
|
||||
return 1 << gpio_out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_keylight(uint16_t gpio0, uint16_t gpio1)
|
||||
{
|
||||
uint16_t gpio_lights = 0;
|
||||
|
||||
gpio_lights |= check_assign_gpio(
|
||||
gpio0, SDVX_IO_IN_GPIO_0_START, SDVX_IO_OUT_GPIO_START);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio0, SDVX_IO_IN_GPIO_0_A, SDVX_IO_OUT_GPIO_A);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio0, SDVX_IO_IN_GPIO_0_B, SDVX_IO_OUT_GPIO_B);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio0, SDVX_IO_IN_GPIO_0_C, SDVX_IO_OUT_GPIO_C);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio1, SDVX_IO_IN_GPIO_1_D, SDVX_IO_OUT_GPIO_D);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio1, SDVX_IO_IN_GPIO_1_FX_L, SDVX_IO_OUT_GPIO_FX_L);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio1, SDVX_IO_IN_GPIO_1_FX_R, SDVX_IO_OUT_GPIO_FX_R);
|
||||
|
||||
sdvx_io_set_gpio_lights(gpio_lights);
|
||||
}
|
||||
|
||||
void set_pwm_brightness(uint8_t wing_pwm, uint8_t controller_pwm)
|
||||
{
|
||||
// 0-11 are the 4 wings
|
||||
for (size_t i = 0; i < 12; ++i) {
|
||||
sdvx_io_set_pwm_light(i, wing_pwm);
|
||||
}
|
||||
// 12-17 are the woofer / control deck
|
||||
for (size_t i = 12; i < 18; ++i) {
|
||||
sdvx_io_set_pwm_light(i, controller_pwm);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
log_to_writer(log_writer_stdout, NULL);
|
||||
|
||||
struct vigem_sdvxio_config config;
|
||||
get_vigem_sdvxio_config(&config);
|
||||
|
||||
sdvx_io_set_loggers(
|
||||
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
|
||||
|
||||
if (!sdvx_io_init(crt_thread_create, crt_thread_join, crt_thread_destroy)) {
|
||||
log_warning("Initializing sdvxio failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdvx_io_set_amp_volume(config.amp_volume, config.amp_volume, config.amp_volume);
|
||||
|
||||
PVIGEM_CLIENT client = vigem_helper_setup();
|
||||
if (!client) {
|
||||
log_warning("client failed to connect failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PVIGEM_TARGET pad = vigem_helper_add_pad(client);
|
||||
if (!pad) {
|
||||
log_warning("vigem_alloc pad 1 failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool loop = true;
|
||||
|
||||
uint8_t sys;
|
||||
uint16_t gpio0;
|
||||
uint16_t gpio1;
|
||||
uint16_t vol[2] = {0, 0};
|
||||
|
||||
XUSB_REPORT state;
|
||||
|
||||
log_info("vigem init succeeded, beginnning poll loop");
|
||||
while (loop) {
|
||||
sdvx_io_read_input();
|
||||
|
||||
sys = sdvx_io_get_input_gpio_sys();
|
||||
gpio0 = sdvx_io_get_input_gpio(0);
|
||||
gpio1 = sdvx_io_get_input_gpio(1);
|
||||
|
||||
vol[0] = sdvx_io_get_spinner_pos(0);
|
||||
vol[1] = sdvx_io_get_spinner_pos(1);
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
|
||||
state.sThumbLX = convert_analog_to_s16(vol[0]);
|
||||
state.sThumbRX = convert_analog_to_s16(vol[1]);
|
||||
|
||||
state.wButtons |= check_assign_key(
|
||||
gpio0, SDVX_IO_IN_GPIO_0_START, XUSB_GAMEPAD_START);
|
||||
state.wButtons |=
|
||||
check_assign_key(sys, SDVX_IO_IN_GPIO_SYS_TEST, XUSB_GAMEPAD_BACK);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio0, SDVX_IO_IN_GPIO_0_A, XUSB_GAMEPAD_A);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio0, SDVX_IO_IN_GPIO_0_B, XUSB_GAMEPAD_B);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio0, SDVX_IO_IN_GPIO_0_C, XUSB_GAMEPAD_X);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio1, SDVX_IO_IN_GPIO_1_D, XUSB_GAMEPAD_Y);
|
||||
state.wButtons |= check_assign_key(
|
||||
gpio1, SDVX_IO_IN_GPIO_1_FX_L, XUSB_GAMEPAD_LEFT_SHOULDER);
|
||||
state.wButtons |= check_assign_key(
|
||||
gpio1, SDVX_IO_IN_GPIO_1_FX_R, XUSB_GAMEPAD_RIGHT_SHOULDER);
|
||||
|
||||
vigem_target_x360_update(client, pad, state);
|
||||
|
||||
if (config.enable_keylight) {
|
||||
gpio_keylight(gpio0, gpio1);
|
||||
}
|
||||
|
||||
set_pwm_brightness(config.pwm_wings, config.pwm_controller);
|
||||
sdvx_io_write_output();
|
||||
|
||||
if (check_key(sys, SDVX_IO_IN_GPIO_SYS_TEST) &&
|
||||
check_key(sys, SDVX_IO_IN_GPIO_SYS_SERVICE)) {
|
||||
loop = false;
|
||||
}
|
||||
|
||||
// avoid banging
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
vigem_target_remove(client, pad);
|
||||
vigem_target_free(pad);
|
||||
|
||||
sdvx_io_set_amp_volume(96, 96, 96);
|
||||
Sleep(1000);
|
||||
|
||||
sdvx_io_fini();
|
||||
|
||||
return 0;
|
||||
}
|
12
src/main/vigemstub/Module.mk
Normal file
12
src/main/vigemstub/Module.mk
Normal file
@ -0,0 +1,12 @@
|
||||
libs += vigemstub
|
||||
imps += ViGEmClient
|
||||
|
||||
cppflags_vigemstub := \
|
||||
-I src/imports \
|
||||
|
||||
libs_vigemstub := \
|
||||
|
||||
src_vigemstub := \
|
||||
helper.c \
|
||||
|
||||
# This is a dummy module so that the client only gets import libraries generated once
|
45
src/main/vigemstub/helper.c
Normal file
45
src/main/vigemstub/helper.c
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "ViGEm/Client.h"
|
||||
|
||||
#include "vigemstub/helper.h"
|
||||
|
||||
PVIGEM_CLIENT vigem_helper_setup(void)
|
||||
{
|
||||
PVIGEM_CLIENT client = vigem_alloc();
|
||||
|
||||
if (client == NULL) {
|
||||
printf("vigem_alloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VIGEM_ERROR retval = vigem_connect(client);
|
||||
|
||||
if (!VIGEM_SUCCESS(retval)) {
|
||||
printf("ViGEm Bus connection failed with error code: 0x%x\n", retval);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
PVIGEM_TARGET vigem_helper_add_pad(PVIGEM_CLIENT client)
|
||||
{
|
||||
PVIGEM_TARGET pad = vigem_target_x360_alloc();
|
||||
|
||||
if (pad == NULL) {
|
||||
printf("vigem_target_x360_alloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VIGEM_ERROR pir = vigem_target_add(client, pad);
|
||||
|
||||
if (!VIGEM_SUCCESS(pir)) {
|
||||
printf("Target plugin failed with error code: 0x%x\n", pir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pad;
|
||||
}
|
9
src/main/vigemstub/helper.h
Normal file
9
src/main/vigemstub/helper.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef VIGEMSTUB_HELPER_H
|
||||
#define VIGEMSTUB_HELPER_H
|
||||
|
||||
#include "ViGEm/Client.h"
|
||||
|
||||
PVIGEM_CLIENT vigem_helper_setup();
|
||||
PVIGEM_TARGET vigem_helper_add_pad(PVIGEM_CLIENT client);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user