aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2020-05-24 00:37:25 +0200
committercbdev <cb@cbcdn.com>2020-05-24 00:37:25 +0200
commit5b4fedbafd476f5d08b55d5d30dc928407304312 (patch)
treefd92782a644920bb62253b2fa7ff584a60bce70b
parent013718121c768507cef62ec03afa91d715a5ef38 (diff)
downloadmidimonster-5b4fedbafd476f5d08b55d5d30dc928407304312.tar.gz
midimonster-5b4fedbafd476f5d08b55d5d30dc928407304312.tar.bz2
midimonster-5b4fedbafd476f5d08b55d5d30dc928407304312.zip
Implement joystick channel specification, fix normalization
-rw-r--r--backends/wininput.c56
1 files changed, 51 insertions, 5 deletions
diff --git a/backends/wininput.c b/backends/wininput.c
index f044a7c..3175171 100644
--- a/backends/wininput.c
+++ b/backends/wininput.c
@@ -59,7 +59,7 @@ static key_info keys[] = {
static struct {
int virtual_x, virtual_y, virtual_width, virtual_height;
- uint16_t mouse_x, mouse_y;
+ long mouse_x, mouse_y;
size_t requests;
wininput_request* request;
uint32_t interval;
@@ -236,6 +236,48 @@ static uint64_t wininput_channel_key(instance* inst, char* spec, uint8_t flags){
return 0;
}
+static uint64_t wininput_channel_joystick(instance* inst, char* spec, uint8_t flags){
+ char* token = NULL, *axes = "xyzruvp";
+ uint16_t controller = strtoul(spec, &token, 0);
+ wininput_channel_ident ident = {
+ .fields.type = joystick
+ };
+
+ if(flags & mmchannel_output){
+ LOG("Joystick channels can only be mapped as inputs on Windows");
+ return 0;
+ }
+
+ if(!controller || !token || *token != '.'){
+ LOGPF("Invalid joystick specification %s", spec);
+ return 0;
+ }
+
+ if(strlen(token) == 1 || !strcmp(token, "pov")){
+ if(strchr(axes, token[0])){
+ ident.fields.channel = position;
+ ident.fields.control = (controller << 8) | token[0];
+ return ident.label;
+ }
+
+ LOGPF("Unknown joystick axis specification %s", token);
+ return 0;
+ }
+
+ if(!strncmp(token, "button", 6)){
+ ident.fields.control = strtoul(token + 6, NULL, 10);
+ if(!ident.fields.control || ident.fields.control > 32){
+ LOGPF("Button index out of range for specification %s", token);
+ return 0;
+ }
+ ident.fields.control |= (controller << 8);
+ return ident.label;
+ }
+
+ printf("Invalid joystick control %s", spec);
+ return 0;
+}
+
static channel* wininput_channel(instance* inst, char* spec, uint8_t flags){
channel* chan = NULL;
uint64_t label = 0;
@@ -246,6 +288,9 @@ static channel* wininput_channel(instance* inst, char* spec, uint8_t flags){
else if(!strncmp(spec, "key.", 4)){
label = wininput_channel_key(inst, spec + 4, flags);
}
+ else if(!strncmp(spec, "joy", 3)){
+ label = wininput_channel_joystick(inst, spec + 3, flags);
+ }
else{
LOGPF("Unknown channel spec type %s", spec);
}
@@ -262,8 +307,8 @@ static channel* wininput_channel(instance* inst, char* spec, uint8_t flags){
//for some reason, sendinput only takes "normalized absolute coordinates", which are never again used in the API
static void wininput_mouse_normalize(long* x, long* y){
- long normalized_x = (double) (*x + cfg.virtual_x) * (65535.0f / (double) cfg.virtual_width);
- long normalized_y = (double) (*y + cfg.virtual_y) * (65535.0f / (double) cfg.virtual_height);
+ long normalized_x = (double) (*x - cfg.virtual_x) * (65535.0f / (double) cfg.virtual_width);
+ long normalized_y = (double) (*y - cfg.virtual_y) * (65535.0f / (double) cfg.virtual_height);
*x = normalized_x;
*y = normalized_y;
@@ -411,7 +456,8 @@ static int wininput_handle(size_t num, managed_fd* fds){
push_event = 1;
}
}
- else{
+ else if(cfg.request[u].ident.fields.type == keyboard
+ || cfg.request[u].ident.fields.type == mouse){
//check key state
key_state = GetAsyncKeyState(cfg.request[u].ident.fields.control);
if(key_state == 1){
@@ -463,7 +509,7 @@ static int wininput_start(size_t n, instance** inst){
joy_info.dwSize = sizeof(joy_info);
joy_info.dwFlags = 0;
if(joyGetPosEx(u, &joy_info) == JOYERR_NOERROR){
- LOGPF("Joystick %" PRIsize_t " is available for input", u);
+ LOGPF("Joystick %" PRIsize_t " is available for input", u + 1);
}
}