From 5e4c3fe5a81f548243aab01a42973333b559004f Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 11 Jun 2020 12:27:57 +0200 Subject: Query joystick buttons --- backends/wininput.c | 87 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 12 deletions(-) (limited to 'backends/wininput.c') diff --git a/backends/wininput.c b/backends/wininput.c index 71e9855..627891e 100644 --- a/backends/wininput.c +++ b/backends/wininput.c @@ -1,5 +1,5 @@ #define BACKEND_NAME "wininput" -#define DEBUG +//#define DEBUG #include #include "wininput.h" @@ -7,6 +7,7 @@ #include //TODO check whether feedback elimination is required +//TODO might want to store virtual desktop extents in request->limit static key_info keys[] = { {VK_LBUTTON, "lmb", button}, {VK_RBUTTON, "rmb", button}, {VK_MBUTTON, "mmb", button}, @@ -57,6 +58,17 @@ static key_info keys[] = { {VK_ZOOM, "zoom"} }; +//this monstrosity is necessary because not only are the buttons not a simple bitmask, the bits are also partially reused. +//i get why they replaced this heap of trash API, but the replacement would require me to jump through even more hoops. +static uint32_t button_masks[32] = {JOY_BUTTON1, JOY_BUTTON2, JOY_BUTTON3, JOY_BUTTON4, + JOY_BUTTON5, JOY_BUTTON6, JOY_BUTTON7, JOY_BUTTON8, + JOY_BUTTON9, JOY_BUTTON10, JOY_BUTTON11, JOY_BUTTON12, + JOY_BUTTON13, JOY_BUTTON14, JOY_BUTTON15, JOY_BUTTON16, + JOY_BUTTON17, JOY_BUTTON18, JOY_BUTTON19, JOY_BUTTON20, + JOY_BUTTON21, JOY_BUTTON22, JOY_BUTTON23, JOY_BUTTON24, + JOY_BUTTON25, JOY_BUTTON26, JOY_BUTTON27, JOY_BUTTON28, + JOY_BUTTON29, JOY_BUTTON30, JOY_BUTTON31, JOY_BUTTON32}; + static struct { int virtual_x, virtual_y, virtual_width, virtual_height; long mouse_x, mouse_y; @@ -159,7 +171,7 @@ static int wininput_subscribe(uint64_t ident, channel* chan){ cfg.request[u].ident.label = ident; cfg.request[u].channels = 0; cfg.request[u].channel = NULL; - cfg.request[u].state = 0; + cfg.request[u].state = cfg.request[u].min = cfg.request[u].max = 0; cfg.requests++; } @@ -276,7 +288,7 @@ static uint64_t wininput_channel_joystick(instance* inst, char* spec, uint8_t fl if(strlen(token) == 1 || !strcmp(token, "pov")){ if(strchr(axes, token[0])){ ident.fields.channel = position; - ident.fields.control = (controller << 8) | token[0]; + ident.fields.control = ((controller - 1) << 8) | token[0]; return ident.label; } @@ -511,13 +523,25 @@ static int wininput_handle(size_t num, managed_fd* fds){ if(cfg.request[u].ident.fields.channel == button){ //button query if(joy_info.dwFlags & JOY_RETURNBUTTONS){ - //TODO handle button requests + key_state = (joy_info.dwButtons & button_masks[(cfg.request[u].ident.fields.control & 0xFF)]) > 0 ? 1 : 0; + if(key_state != cfg.request[u].state){ + if(key_state){ + val.normalised = 1.0; + } + cfg.request[u].state = key_state; + push_event = 1; + DBGPF("Joystick %d button %d: %d", + cfg.request[u].ident.fields.control >> 8, + cfg.request[u].ident.fields.control & 0xFF, + key_state); + } } else{ LOGPF("No button data received for joystick %d", cfg.request[u].ident.fields.control >> 8); } } else{ + //TODO handle axis requests } } @@ -542,17 +566,11 @@ static int wininput_handle(size_t num, managed_fd* fds){ return 0; } -static int wininput_start(size_t n, instance** inst){ - size_t u; - POINT cursor_position; +static void wininput_start_joystick(){ + size_t u, p; JOYINFOEX joy_info; JOYCAPS joy_caps; - //if no input requested, don't request polling - if(!cfg.requests){ - cfg.interval = 0; - } - DBGPF("This system supports a maximum of %u joysticks", joyGetNumDevs()); for(u = 0; u < joyGetNumDevs(); u++){ joy_info.dwSize = sizeof(joy_info); @@ -560,12 +578,57 @@ static int wininput_start(size_t n, instance** inst){ if(joyGetPosEx(u, &joy_info) == JOYERR_NOERROR){ if(joyGetDevCaps(u, &joy_caps, sizeof(joy_caps)) == JOYERR_NOERROR){ LOGPF("Joystick %" PRIsize_t " (%s) is available for input", u + 1, joy_caps.szPname ? joy_caps.szPname : "unknown model"); + for(p = 0; p < cfg.requests; p++){ + if(cfg.request[p].ident.fields.type == joystick + && cfg.request[p].ident.fields.channel == position + && (cfg.request[p].ident.fields.control >> 8) == u){ + //this looks really dumb, but the structure is defined in a way that prevents us from doing anything clever here + switch(cfg.request[p].ident.fields.control & 0xFF){ + case 'x': + cfg.request[p].min = joy_caps.wXmin; + cfg.request[p].max = joy_caps.wXmax; + break; + case 'y': + cfg.request[p].min = joy_caps.wYmin; + cfg.request[p].max = joy_caps.wYmax; + break; + case 'z': + cfg.request[p].min = joy_caps.wZmin; + cfg.request[p].max = joy_caps.wZmax; + break; + case 'r': + cfg.request[p].min = joy_caps.wRmin; + cfg.request[p].max = joy_caps.wRmax; + break; + case 'u': + cfg.request[p].min = joy_caps.wUmin; + cfg.request[p].max = joy_caps.wUmax; + break; + case 'v': + cfg.request[p].min = joy_caps.wVmin; + cfg.request[p].max = joy_caps.wVmax; + break; + } + DBGPF("Updated limits on request %" PRIsize_t " to %" PRIu32 " / %" PRIu32, p, cfg.request[p].min, cfg.request[p].max); + } + } } else{ LOGPF("Joystick %" PRIsize_t " available for input, but no capabilities reported", u + 1); } } } +} + +static int wininput_start(size_t n, instance** inst){ + POINT cursor_position; + + //if no input requested, don't request polling + if(!cfg.requests){ + cfg.interval = 0; + } + + wininput_start_joystick(); //read virtual desktop extents for later normalization cfg.virtual_width = GetSystemMetrics(SM_CXVIRTUALSCREEN); -- cgit v1.2.3