79
79
#include < mmsystem.h>
80
80
#include < process.h>
81
81
#include < dinput.h>
82
+ #include < utility>
82
83
83
84
/* We need XInput detection if we actually compile the XInput driver in.
84
85
*/
@@ -146,6 +147,7 @@ ALLEGRO_JOYSTICK_DRIVER _al_joydrv_directx =
146
147
#define DEFINE_PRIVATE_GUID (name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8 ) \
147
148
static const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
148
149
150
+ DEFINE_PRIVATE_GUID (__al_GUID_None, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
149
151
DEFINE_PRIVATE_GUID (__al_GUID_XAxis, 0xA36D02E0 ,0xC9F3 ,0x11CF ,0xBF ,0xC7 ,0x44 ,0x45 ,0x53 ,0x54 ,0x00 ,0x00 );
150
152
DEFINE_PRIVATE_GUID (__al_GUID_YAxis, 0xA36D02E1 ,0xC9F3 ,0x11CF ,0xBF ,0xC7 ,0x44 ,0x45 ,0x53 ,0x54 ,0x00 ,0x00 );
151
153
DEFINE_PRIVATE_GUID (__al_GUID_ZAxis, 0xA36D02E2 ,0xC9F3 ,0x11CF ,0xBF ,0xC7 ,0x44 ,0x45 ,0x53 ,0x54 ,0x00 ,0x00 );
@@ -503,6 +505,7 @@ static BOOL CALLBACK object_enum_callback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVO
503
505
#define GUIDTYPE_EQ (x ) GUID_EQUAL(lpddoi->guidType, x)
504
506
505
507
CAPS_AND_NAMES *can = (CAPS_AND_NAMES *)pvRef;
508
+ DWORD j = 0 ;
506
509
507
510
if (GUIDTYPE_EQ (__al_GUID_XAxis)) {
508
511
can->have_x = true ;
@@ -515,18 +518,22 @@ static BOOL CALLBACK object_enum_callback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVO
515
518
else if (GUIDTYPE_EQ (__al_GUID_ZAxis)) {
516
519
can->have_z = true ;
517
520
_tcsncpy (can->name_z , lpddoi->tszName , NAME_LEN);
521
+ j = DIJOFS_Z;
518
522
}
519
523
else if (GUIDTYPE_EQ (__al_GUID_RxAxis)) {
520
524
can->have_rx = true ;
521
525
_tcsncpy (can->name_rx , lpddoi->tszName , NAME_LEN);
526
+ j = DIJOFS_RX;
522
527
}
523
528
else if (GUIDTYPE_EQ (__al_GUID_RyAxis)) {
524
529
can->have_ry = true ;
525
530
_tcsncpy (can->name_ry , lpddoi->tszName , NAME_LEN);
531
+ j = DIJOFS_RY;
526
532
}
527
533
else if (GUIDTYPE_EQ (__al_GUID_RzAxis)) {
528
534
can->have_rz = true ;
529
535
_tcsncpy (can->name_rz , lpddoi->tszName , NAME_LEN);
536
+ j = DIJOFS_RZ;
530
537
}
531
538
else if (GUIDTYPE_EQ (__al_GUID_Slider)) {
532
539
if (can->num_sliders < MAX_SLIDERS) {
@@ -550,6 +557,38 @@ static BOOL CALLBACK object_enum_callback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVO
550
557
}
551
558
}
552
559
560
+ // The first two axis (not X or Y) are stored and used as the secondary stick.
561
+ // The order of the enumeration is assumed to give us the X followed by the Y axis. However,
562
+ // an override is provided in the case that the second axis seen here is for Z, in which case that
563
+ // will be used as the X axis. This is to fit behaviors seen on specific controllers:
564
+ // - PS4 DualShock
565
+ // - Stadia
566
+ // ...it may be that using `Z` really is common for some input devices.
567
+ //
568
+ // Solution came from https://www.gamedev.net/forums/topic/613913-directinput-identifying-second-thumbstick/
569
+ if (j)
570
+ {
571
+ if (can->secondary_stick_axis_one == 0 )
572
+ {
573
+ can->secondary_stick_axis_one = j;
574
+ _tcsncpy (can->name_rx , lpddoi->tszName , NAME_LEN);
575
+ }
576
+ else if (can->secondary_stick_axis_two == 0 )
577
+ {
578
+ can->secondary_stick_axis_two = j;
579
+ _tcsncpy (can->name_ry , lpddoi->tszName , NAME_LEN);
580
+
581
+ if (j == DIJOFS_Z)
582
+ {
583
+ std::swap (can->secondary_stick_axis_one , can->secondary_stick_axis_two );
584
+ std::swap (can->name_rx , can->name_ry );
585
+ }
586
+
587
+ can->have_rx = true ;
588
+ can->have_ry = true ;
589
+ }
590
+ }
591
+
553
592
return DIENUM_CONTINUE;
554
593
555
594
#undef GUIDTYPE_EQ
@@ -640,6 +679,7 @@ static void fill_joystick_info_using_caps_and_names(ALLEGRO_JOYSTICK_DIRECTX *jo
640
679
info->stick [N_STICK].axis [N_AXIS].name = ADD_STRING (can->name_rx , default_name_rx);
641
680
joy->rx_mapping .stick = N_STICK;
642
681
joy->rx_mapping .axis = N_AXIS;
682
+ joy->rx_mapping .j = can->secondary_stick_axis_one ;
643
683
N_AXIS++;
644
684
}
645
685
@@ -648,6 +688,7 @@ static void fill_joystick_info_using_caps_and_names(ALLEGRO_JOYSTICK_DIRECTX *jo
648
688
info->stick [N_STICK].axis [N_AXIS].name = ADD_STRING (can->name_ry , default_name_ry);
649
689
joy->ry_mapping .stick = N_STICK;
650
690
joy->ry_mapping .axis = N_AXIS;
691
+ joy->ry_mapping .j = can->secondary_stick_axis_two ;
651
692
N_AXIS++;
652
693
}
653
694
@@ -1491,7 +1532,11 @@ static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy)
1491
1532
const int dwOfs = item->dwOfs ;
1492
1533
const DWORD dwData = item->dwData ;
1493
1534
1494
- if (dwOfs == DIJOFS_X)
1535
+ if (joy->rx_mapping .j && joy->rx_mapping .j == dwOfs)
1536
+ handle_axis_event (joy, &joy->rx_mapping , dwData);
1537
+ else if (joy->ry_mapping .j && joy->ry_mapping .j == dwOfs)
1538
+ handle_axis_event (joy, &joy->ry_mapping , dwData);
1539
+ else if (dwOfs == DIJOFS_X)
1495
1540
handle_axis_event (joy, &joy->x_mapping , dwData);
1496
1541
else if (dwOfs == DIJOFS_Y)
1497
1542
handle_axis_event (joy, &joy->y_mapping , dwData);
0 commit comments