Created
November 25, 2020 02:24
-
-
Save osnr/3b8bd2c4a278bf554dc009da21362c14 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- based on https://www.reddit.com/r/gamedev/comments/jumvi5/dualsense_haptics_leds_and_more_hid_output_report/gcemle4/ | |
-- requires hidapi + run with LuaJIT | |
local ffi = require('ffi') | |
ffi.cdef[[ | |
typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ | |
int hid_init(void); | |
hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); | |
int hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen); | |
int hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen); | |
int hid_read(hid_device *dev, unsigned char *data, size_t length); | |
int hid_write(hid_device *dev, const unsigned char *data, size_t length); | |
]] | |
local hidapi = ffi.load('hidapi') | |
local res = hidapi.hid_init() | |
if handle then return nil end | |
handle = hidapi.hid_open(0x054c, 0x0ce6, nil) | |
ffi.cdef[[ size_t wcstombs (char* dest, const wchar_t* src, size_t max); ]] | |
function wprint(prefix, ws) | |
local s = ffi.new('char[255]', 1) | |
ffi.C.wcstombs(s, ws, 255) | |
print(prefix, ffi.string(s)) | |
end | |
local wstr = ffi.new('wchar_t[255]', 1) | |
hidapi.hid_get_manufacturer_string(handle, wstr, 255) | |
wprint('Manufacturer String:', wstr) -- Sony Interactive Entertainment | |
hidapi.hid_get_product_string(handle, wstr, 255) | |
wprint('Product String:', wstr) -- Wireless Controller | |
local output_report = ffi.new('char[48]') | |
local data = ffi.new('char[64]') | |
local fun = 0 | |
local player = 1 | |
while true do | |
hidapi.hid_read(handle, data, 64) -- get input report | |
fun = fun + 1 | |
if fun == 256 then fun = 0 player = (player + 1) % 0x20 end | |
output_report[0] = 0x02 | |
-- allow us to set everything (not necessarily the best idea, but can be good for testing) | |
output_report[1] = 0xff | |
output_report[2] = 0xff-8 | |
-- briefly alternate the main motors with gaps inbetween | |
output_report[3] = (fun > 128 and fun < 192 and 255) or 0 | |
output_report[4] = (fun < 64 and 255) or 0 | |
-- pulsating Mic LED | |
output_report[9] = 0x02 | |
-- right trigger motor at linear resistance starting part of the way | |
output_report[11] = 1 | |
output_report[12] = 0x5f | |
output_report[13] = 0xff | |
-- left trigger with similar effect as the PS5 demo | |
if fun % 32 < 16 then output_report[22] = 0 else output_report[22] = 2 end | |
output_report[23] = 0x00 | |
output_report[24] = 0xff | |
output_report[25] = 0xff | |
-- cycling LEDs | |
output_report[44] = player | |
output_report[45] = fun | |
output_report[47] = fun+128 | |
hidapi.hid_write(handle, output_report, 48) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment