Subversion Repositories eduke32

Rev

Rev 8550 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 Plagman 1
/*
2
 * control.c
3
 * MACT library controller handling
809 terminx 4
 *
5 Plagman 5
 * Derived from MACT386.LIB disassembly by Jonathon Fowler
6
 *
7
 */
8
 
7214 terminx 9
#include "_control.h"
10
#include "baselayer.h"
434 Plagman 11
#include "compat.h"
7214 terminx 12
#include "control.h"
13
#include "joystick.h"
5 Plagman 14
#include "keyboard.h"
15
#include "mouse.h"
855 terminx 16
#include "osd.h"
5 Plagman 17
#include "pragmas.h"
18
 
4386 terminx 19
#ifdef __ANDROID__
20
#include "android.h"
21
#endif
22
 
7181 terminx 23
bool CONTROL_Started         = false;
7214 terminx 24
bool CONTROL_MouseEnabled    = false;
25
bool CONTROL_MousePresent    = false;
7181 terminx 26
bool CONTROL_JoyPresent      = false;
27
bool CONTROL_JoystickEnabled = false;
28
 
6334 terminx 29
uint64_t CONTROL_ButtonState     = 0;
30
uint64_t CONTROL_ButtonHeldState = 0;
5 Plagman 31
 
7992 hendricks2 32
LastSeenInput CONTROL_LastSeenInput;
33
 
6334 terminx 34
float          CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY;
35
static int32_t CONTROL_NumMouseButtons  = 0;
36
static int32_t CONTROL_NumJoyButtons    = 0;
37
static int32_t CONTROL_NumJoyAxes       = 0;
38
 
39
static controlflags      CONTROL_Flags[CONTROL_NUM_FLAGS];
40
 
8303 hendricks2 41
static controlkeymaptype  CONTROL_KeyMapping[CONTROL_NUM_FLAGS];
7214 terminx 42
 
8776 terminx 43
int32_t                   CONTROL_MouseAxesScale[2];
7214 terminx 44
 
6334 terminx 45
static controlaxismaptype CONTROL_JoyAxesMap[MAXJOYAXES];
7214 terminx 46
static controlaxistype    CONTROL_JoyAxes[MAXJOYAXES];
47
static controlaxistype    CONTROL_LastJoyAxes[MAXJOYAXES];
48
static int32_t            CONTROL_JoyAxesScale[MAXJOYAXES];
7986 hendricks2 49
static int8_t             CONTROL_JoyAxesInvert[MAXJOYAXES];
6334 terminx 50
 
7214 terminx 51
static controlbuttontype CONTROL_MouseButtonMapping[MAXMOUSEBUTTONS];
6334 terminx 52
 
7214 terminx 53
static int32_t CONTROL_MouseButtonClicked[MAXMOUSEBUTTONS];
54
static int32_t CONTROL_MouseButtonClickedState[MAXMOUSEBUTTONS];
55
static int32_t CONTROL_MouseButtonClickedTime[MAXMOUSEBUTTONS];
6334 terminx 56
static int32_t CONTROL_MouseButtonState[MAXMOUSEBUTTONS];
57
static uint8_t CONTROL_MouseButtonClickedCount[MAXMOUSEBUTTONS];
58
 
7214 terminx 59
static controlbuttontype CONTROL_JoyButtonMapping[MAXJOYBUTTONS];
60
 
61
static int32_t CONTROL_JoyButtonClicked[MAXJOYBUTTONS];
62
static int32_t CONTROL_JoyButtonClickedState[MAXJOYBUTTONS];
63
static int32_t CONTROL_JoyButtonClickedTime[MAXJOYBUTTONS];
6334 terminx 64
static int32_t CONTROL_JoyButtonState[MAXJOYBUTTONS];
65
static uint8_t CONTROL_JoyButtonClickedCount[MAXJOYBUTTONS];
66
 
4558 hendricks2 67
static int32_t(*ExtGetTime)(void);
2940 helixhorne 68
//static int32_t ticrate;
7181 terminx 69
static uint8_t CONTROL_DoubleClickSpeed;
5 Plagman 70
 
7181 terminx 71
int32_t CONTROL_ButtonFlags[CONTROL_NUM_FLAGS];
72
consolekeybind_t CONTROL_KeyBinds[MAXBOUNDKEYS + MAXMOUSEBUTTONS];
73
bool CONTROL_BindsEnabled = 0;
5 Plagman 74
 
6334 terminx 75
#define CONTROL_CheckRange(which) ((unsigned)which >= (unsigned)CONTROL_NUM_FLAGS)
7705 terminx 76
#define BIND(x, s, r, k) do { Xfree(x.cmdstr); x.cmdstr = s; x.repeat = r; x.key = k; } while (0)
3214 terminx 77
 
3209 helixhorne 78
void CONTROL_ClearAllBinds(void)
79
{
7181 terminx 80
    for (int i=0; i<MAXBOUNDKEYS; i++)
3209 helixhorne 81
        CONTROL_FreeKeyBind(i);
7181 terminx 82
    for (int i=0; i<MAXMOUSEBUTTONS; i++)
3209 helixhorne 83
        CONTROL_FreeMouseBind(i);
84
}
85
 
6334 terminx 86
void CONTROL_BindKey(int i, char const * const cmd, int repeat, char const * const keyname)
3209 helixhorne 87
{
7079 terminx 88
    BIND(CONTROL_KeyBinds[i], Xstrdup(cmd), repeat, keyname);
3209 helixhorne 89
}
90
 
6334 terminx 91
void CONTROL_BindMouse(int i, char const * const cmd, int repeat, char const * const keyname)
3209 helixhorne 92
{
7079 terminx 93
    BIND(CONTROL_KeyBinds[MAXBOUNDKEYS + i], Xstrdup(cmd), repeat, keyname);
3209 helixhorne 94
}
95
 
6334 terminx 96
void CONTROL_FreeKeyBind(int i)
3209 helixhorne 97
{
3214 terminx 98
    BIND(CONTROL_KeyBinds[i], NULL, 0, NULL);
3209 helixhorne 99
}
100
 
6334 terminx 101
void CONTROL_FreeMouseBind(int i)
3209 helixhorne 102
{
6328 terminx 103
    BIND(CONTROL_KeyBinds[MAXBOUNDKEYS + i], NULL, 0, NULL);
3209 helixhorne 104
}
105
 
7947 hendricks2 106
static void CONTROL_GetMouseDelta(ControlInfo * info)
5 Plagman 107
{
7142 terminx 108
    vec2_t input;
109
    mouseReadPos(&input.x, &input.y);
5 Plagman 110
 
7142 terminx 111
    vec2f_t finput = { float(input.x), float(input.y) };
5 Plagman 112
 
8126 terminx 113
    info->mousex = mulscale16(Blrintf(finput.x * 4.f * CONTROL_MouseSensitivity), CONTROL_MouseAxesScale[0]);
114
    info->mousey = mulscale16(Blrintf(finput.y * 4.f * CONTROL_MouseSensitivity), CONTROL_MouseAxesScale[1]);
5 Plagman 115
}
116
 
2940 helixhorne 117
static int32_t CONTROL_GetTime(void)
5 Plagman 118
{
1346 terminx 119
    static int32_t t = 0;
289 terminx 120
    t += 5;
121
    return t;
5 Plagman 122
}
123
 
7181 terminx 124
static void CONTROL_SetFlag(int which, int active)
5 Plagman 125
{
289 terminx 126
    if (CONTROL_CheckRange(which)) return;
5 Plagman 127
 
6334 terminx 128
    controlflags &flags = CONTROL_Flags[which];
129
 
130
    if (flags.toggle == INSTANT_ONOFF)
131
        flags.active = active;
132
    else if (active)
133
        flags.buttonheld = FALSE;
134
    else if (flags.buttonheld == FALSE)
809 terminx 135
    {
6334 terminx 136
        flags.buttonheld = TRUE;
137
        flags.active = (flags.active ? FALSE : TRUE);
809 terminx 138
    }
5 Plagman 139
}
140
 
1346 terminx 141
int32_t CONTROL_KeyboardFunctionPressed(int32_t which)
5 Plagman 142
{
8550 terminx 143
    if (CONTROL_CheckRange(which) || !CONTROL_Flags[which].used)
144
        return FALSE;
5 Plagman 145
 
8550 terminx 146
    int r = 0;
147
    auto &mapped = CONTROL_KeyMapping[which];
5 Plagman 148
 
8550 terminx 149
    if (mapped.keyPrimary != KEYUNDEFINED && !CONTROL_KeyBinds[mapped.keyPrimary].cmdstr)
150
        r = !!KB_KeyDown[mapped.keyPrimary];
5 Plagman 151
 
8550 terminx 152
    if (mapped.keySecondary != KEYUNDEFINED && !CONTROL_KeyBinds[mapped.keySecondary].cmdstr)
153
        r |= !!KB_KeyDown[mapped.keySecondary];
5 Plagman 154
 
8550 terminx 155
    return r;
5 Plagman 156
}
157
 
8550 terminx 158
#if 0
1346 terminx 159
void CONTROL_ClearKeyboardFunction(int32_t which)
5 Plagman 160
{
8550 terminx 161
    if (CONTROL_CheckRange(which) || !CONTROL_Flags[which].used)
162
        return;
5 Plagman 163
 
8550 terminx 164
    auto &mapped = CONTROL_KeyMapping[which];
5 Plagman 165
 
8550 terminx 166
    if (mapped.key1 != KEYUNDEFINED)
167
        KB_KeyDown[mapped.key1] = 0;
5 Plagman 168
 
8550 terminx 169
    if (mapped.key2 != KEYUNDEFINED)
170
        KB_KeyDown[mapped.key2] = 0;
5 Plagman 171
}
8550 terminx 172
#endif
5 Plagman 173
 
6334 terminx 174
void CONTROL_DefineFlag(int which, int toggle)
5 Plagman 175
{
289 terminx 176
    if (CONTROL_CheckRange(which)) return;
5 Plagman 177
 
6334 terminx 178
    controlflags &flags = CONTROL_Flags[which];
179
 
180
    flags.active     = FALSE;
181
    flags.buttonheld = FALSE;
182
    flags.cleared    = 0;
7181 terminx 183
    flags.toggle     = toggle;
184
    flags.used       = TRUE;
5 Plagman 185
}
186
 
6334 terminx 187
int CONTROL_FlagActive(int which)
5 Plagman 188
{
1346 terminx 189
    if (CONTROL_CheckRange(which)) return FALSE;
5 Plagman 190
 
289 terminx 191
    return CONTROL_Flags[which].used;
5 Plagman 192
}
193
 
1346 terminx 194
void CONTROL_MapKey(int32_t which, kb_scancode key1, kb_scancode key2)
5 Plagman 195
{
289 terminx 196
    if (CONTROL_CheckRange(which)) return;
5 Plagman 197
 
8550 terminx 198
    CONTROL_KeyMapping[which].keyPrimary = key1 ? key1 : KEYUNDEFINED;
199
    CONTROL_KeyMapping[which].keySecondary = key2 ? key2 : KEYUNDEFINED;
5 Plagman 200
}
201
 
8303 hendricks2 202
#if 0
5 Plagman 203
void CONTROL_PrintKeyMap(void)
204
{
1346 terminx 205
    int32_t i;
5 Plagman 206
 
1346 terminx 207
    for (i=0; i<CONTROL_NUM_FLAGS; i++)
809 terminx 208
    {
1740 helixhorne 209
        initprintf("function %2d key1=%3x key2=%3x\n",
289 terminx 210
                   i, CONTROL_KeyMapping[i].key1, CONTROL_KeyMapping[i].key2);
211
    }
5 Plagman 212
}
213
 
1346 terminx 214
void CONTROL_PrintControlFlag(int32_t which)
5 Plagman 215
{
1740 helixhorne 216
    initprintf("function %2d active=%d used=%d toggle=%d buttonheld=%d cleared=%d\n",
289 terminx 217
               which, CONTROL_Flags[which].active, CONTROL_Flags[which].used,
218
               CONTROL_Flags[which].toggle, CONTROL_Flags[which].buttonheld,
219
               CONTROL_Flags[which].cleared);
5 Plagman 220
}
221
 
222
void CONTROL_PrintAxes(void)
223
{
1346 terminx 224
    int32_t i;
5 Plagman 225
 
584 terminx 226
    initprintf("numjoyaxes=%d\n", CONTROL_NumJoyAxes);
1346 terminx 227
    for (i=0; i<CONTROL_NumJoyAxes; i++)
809 terminx 228
    {
584 terminx 229
        initprintf("axis=%d analog=%d digital1=%d digital2=%d\n",
289 terminx 230
                   i, CONTROL_JoyAxesMap[i].analogmap,
231
                   CONTROL_JoyAxesMap[i].minmap, CONTROL_JoyAxesMap[i].maxmap);
232
    }
5 Plagman 233
}
3209 helixhorne 234
#endif
5 Plagman 235
 
6334 terminx 236
void CONTROL_MapButton(int whichfunction, int whichbutton, int doubleclicked, controldevice device)
5 Plagman 237
{
289 terminx 238
    controlbuttontype *set;
5 Plagman 239
 
289 terminx 240
    if (CONTROL_CheckRange(whichfunction)) whichfunction = BUTTONUNDEFINED;
5 Plagman 241
 
809 terminx 242
    switch (device)
243
    {
289 terminx 244
    case controldevice_mouse:
6334 terminx 245
        if ((unsigned)whichbutton >= (unsigned)MAXMOUSEBUTTONS)
809 terminx 246
        {
289 terminx 247
            //Error("CONTROL_MapButton: button %d out of valid range for %d mouse buttons.",
248
            //          whichbutton, CONTROL_NumMouseButtons);
249
            return;
250
        }
251
        set = CONTROL_MouseButtonMapping;
252
        break;
5 Plagman 253
 
289 terminx 254
    case controldevice_joystick:
6334 terminx 255
        if ((unsigned)whichbutton >= (unsigned)MAXJOYBUTTONS)
809 terminx 256
        {
289 terminx 257
            //Error("CONTROL_MapButton: button %d out of valid range for %d joystick buttons.",
258
            //          whichbutton, CONTROL_NumJoyButtons);
259
            return;
260
        }
261
        set = CONTROL_JoyButtonMapping;
262
        break;
263
 
264
    default:
265
        //Error("CONTROL_MapButton: invalid controller device type");
266
        return;
267
    }
268
 
269
    if (doubleclicked)
270
        set[whichbutton].doubleclicked = whichfunction;
271
    else
272
        set[whichbutton].singleclicked = whichfunction;
5 Plagman 273
}
274
 
6334 terminx 275
void CONTROL_MapAnalogAxis(int whichaxis, int whichanalog, controldevice device)
5 Plagman 276
{
289 terminx 277
    controlaxismaptype *set;
5 Plagman 278
 
7943 hendricks2 279
    if ((unsigned)whichanalog >= (unsigned)analog_maxtype && whichanalog != -1)
809 terminx 280
    {
289 terminx 281
        //Error("CONTROL_MapAnalogAxis: analog function %d out of valid range for %d analog functions.",
282
        //              whichanalog, analog_maxtype);
283
        return;
284
    }
5 Plagman 285
 
809 terminx 286
    switch (device)
287
    {
289 terminx 288
    case controldevice_joystick:
6334 terminx 289
        if ((unsigned)whichaxis >= (unsigned)MAXJOYAXES)
809 terminx 290
        {
289 terminx 291
            //Error("CONTROL_MapAnalogAxis: axis %d out of valid range for %d joystick axes.",
292
            //          whichaxis, MAXJOYAXES);
293
            return;
294
        }
5 Plagman 295
 
289 terminx 296
        set = CONTROL_JoyAxesMap;
297
        break;
5 Plagman 298
 
289 terminx 299
    default:
300
        //Error("CONTROL_MapAnalogAxis: invalid controller device type");
301
        return;
302
    }
5 Plagman 303
 
289 terminx 304
    set[whichaxis].analogmap = whichanalog;
5 Plagman 305
}
306
 
1346 terminx 307
void CONTROL_SetAnalogAxisScale(int32_t whichaxis, int32_t axisscale, controldevice device)
5 Plagman 308
{
1346 terminx 309
    int32_t *set;
5 Plagman 310
 
809 terminx 311
    switch (device)
312
    {
289 terminx 313
    case controldevice_mouse:
8127 terminx 314
        if ((unsigned) whichaxis >= ARRAY_SIZE(CONTROL_MouseAxesScale))
809 terminx 315
        {
289 terminx 316
            //Error("CONTROL_SetAnalogAxisScale: axis %d out of valid range for %d mouse axes.",
317
            //          whichaxis, MAXMOUSEAXES);
318
            return;
319
        }
5 Plagman 320
 
289 terminx 321
        set = CONTROL_MouseAxesScale;
322
        break;
5 Plagman 323
 
289 terminx 324
    case controldevice_joystick:
6334 terminx 325
        if ((unsigned) whichaxis >= (unsigned) MAXJOYAXES)
809 terminx 326
        {
289 terminx 327
            //Error("CONTROL_SetAnalogAxisScale: axis %d out of valid range for %d joystick axes.",
328
            //          whichaxis, MAXJOYAXES);
329
            return;
330
        }
5 Plagman 331
 
289 terminx 332
        set = CONTROL_JoyAxesScale;
333
        break;
5 Plagman 334
 
289 terminx 335
    default:
336
        //Error("CONTROL_SetAnalogAxisScale: invalid controller device type");
337
        return;
338
    }
339
 
340
    set[whichaxis] = axisscale;
5 Plagman 341
}
342
 
7986 hendricks2 343
void CONTROL_SetAnalogAxisInvert(int32_t whichaxis, int32_t invert, controldevice device)
344
{
345
    int8_t * set;
346
 
347
    switch (device)
348
    {
349
    case controldevice_joystick:
350
        if ((unsigned) whichaxis >= (unsigned) MAXJOYAXES)
351
        {
352
            //Error("CONTROL_SetAnalogAxisInvert: axis %d out of valid range for %d joystick axes.",
353
            //          whichaxis, MAXJOYAXES);
354
            return;
355
        }
356
 
357
        set = CONTROL_JoyAxesInvert;
358
        break;
359
 
360
    default:
361
        //Error("CONTROL_SetAnalogAxisInvert: invalid controller device type");
362
        return;
363
    }
364
 
365
    set[whichaxis] = invert;
366
}
367
 
1346 terminx 368
void CONTROL_MapDigitalAxis(int32_t whichaxis, int32_t whichfunction, int32_t direction, controldevice device)
5 Plagman 369
{
289 terminx 370
    controlaxismaptype *set;
5 Plagman 371
 
289 terminx 372
    if (CONTROL_CheckRange(whichfunction)) whichfunction = AXISUNDEFINED;
5 Plagman 373
 
809 terminx 374
    switch (device)
375
    {
289 terminx 376
    case controldevice_joystick:
6334 terminx 377
        if ((unsigned) whichaxis >= (unsigned) MAXJOYAXES)
809 terminx 378
        {
289 terminx 379
            //Error("CONTROL_MapDigitalAxis: axis %d out of valid range for %d joystick axes.",
380
            //          whichaxis, MAXJOYAXES);
381
            return;
382
        }
5 Plagman 383
 
289 terminx 384
        set = CONTROL_JoyAxesMap;
385
        break;
5 Plagman 386
 
289 terminx 387
    default:
388
        //Error("CONTROL_MapDigitalAxis: invalid controller device type");
389
        return;
390
    }
391
 
809 terminx 392
    switch (direction)          // JBF: this is all very much a guess. The ASM puzzles me.
393
    {
289 terminx 394
    case axis_up:
395
    case axis_left:
396
        set[whichaxis].minmap = whichfunction;
397
        break;
398
    case axis_down:
399
    case axis_right:
400
        set[whichaxis].maxmap = whichfunction;
401
        break;
402
    default:
403
        break;
404
    }
5 Plagman 405
}
406
 
809 terminx 407
void CONTROL_ClearAssignments(void)
5 Plagman 408
{
7181 terminx 409
    memset(CONTROL_JoyAxes,             0,               sizeof(CONTROL_JoyAxes));
7986 hendricks2 410
    memset(CONTROL_JoyAxesInvert,       0,               sizeof(CONTROL_JoyAxesInvert));
7181 terminx 411
    memset(CONTROL_JoyAxesMap,          AXISUNDEFINED,   sizeof(CONTROL_JoyAxesMap));
289 terminx 412
    memset(CONTROL_JoyButtonMapping,    BUTTONUNDEFINED, sizeof(CONTROL_JoyButtonMapping));
8549 terminx 413
    memset(CONTROL_KeyMapping,          KEYUNDEFINED,    sizeof(CONTROL_KeyMapping));
7181 terminx 414
    memset(CONTROL_LastJoyAxes,         0,               sizeof(CONTROL_LastJoyAxes));
415
    memset(CONTROL_MouseButtonMapping,  BUTTONUNDEFINED, sizeof(CONTROL_MouseButtonMapping));
416
 
417
    for (int & i : CONTROL_MouseAxesScale)
418
        i = NORMALAXISSCALE;
419
 
420
    for (int & i : CONTROL_JoyAxesScale)
421
        i = NORMALAXISSCALE;
5 Plagman 422
}
423
 
7992 hendricks2 424
static int DoGetDeviceButtons(
1346 terminx 425
    int32_t buttons, int32_t tm,
426
    int32_t NumButtons,
427
    int32_t *DeviceButtonState,
428
    int32_t *ButtonClickedTime,
429
    int32_t *ButtonClickedState,
430
    int32_t *ButtonClicked,
431
    uint8_t *ButtonClickedCount
809 terminx 432
)
433
{
2940 helixhorne 434
    int32_t i=NumButtons-1;
7992 hendricks2 435
    int retval = 0;
5 Plagman 436
 
1346 terminx 437
    for (; i>=0; i--)
809 terminx 438
    {
7181 terminx 439
        int const bs = (buttons >> i) & 1;
5 Plagman 440
 
7181 terminx 441
        DeviceButtonState[i]  = bs;
1346 terminx 442
        ButtonClickedState[i] = FALSE;
5 Plagman 443
 
809 terminx 444
        if (bs)
445
        {
7992 hendricks2 446
            retval = 1;
447
 
1346 terminx 448
            if (ButtonClicked[i] == FALSE)
809 terminx 449
            {
1346 terminx 450
                ButtonClicked[i] = TRUE;
5 Plagman 451
 
809 terminx 452
                if (ButtonClickedCount[i] == 0 || tm > ButtonClickedTime[i])
453
                {
7181 terminx 454
                    ButtonClickedTime[i]  = tm + CONTROL_DoubleClickSpeed;
289 terminx 455
                    ButtonClickedCount[i] = 1;
456
                }
809 terminx 457
                else if (tm < ButtonClickedTime[i])
458
                {
1346 terminx 459
                    ButtonClickedState[i] = TRUE;
289 terminx 460
                    ButtonClickedTime[i]  = 0;
461
                    ButtonClickedCount[i] = 2;
462
                }
463
            }
809 terminx 464
            else if (ButtonClickedCount[i] == 2)
465
            {
1346 terminx 466
                ButtonClickedState[i] = TRUE;
289 terminx 467
            }
2940 helixhorne 468
 
1015 terminx 469
            continue;
809 terminx 470
        }
2940 helixhorne 471
 
1015 terminx 472
        if (ButtonClickedCount[i] == 2)
473
            ButtonClickedCount[i] = 0;
5 Plagman 474
 
1346 terminx 475
        ButtonClicked[i] = FALSE;
289 terminx 476
    }
7992 hendricks2 477
 
478
    return retval;
5 Plagman 479
}
480
 
3124 helixhorne 481
static void CONTROL_GetDeviceButtons(void)
5 Plagman 482
{
7181 terminx 483
    int32_t const t = ExtGetTime();
5 Plagman 484
 
809 terminx 485
    if (CONTROL_MouseEnabled)
486
    {
289 terminx 487
        DoGetDeviceButtons(
488
            MOUSE_GetButtons(), t,
489
            CONTROL_NumMouseButtons,
490
            CONTROL_MouseButtonState,
491
            CONTROL_MouseButtonClickedTime,
492
            CONTROL_MouseButtonClickedState,
493
            CONTROL_MouseButtonClicked,
494
            CONTROL_MouseButtonClickedCount
495
        );
496
    }
5 Plagman 497
 
809 terminx 498
    if (CONTROL_JoystickEnabled)
499
    {
7992 hendricks2 500
        int retval = DoGetDeviceButtons(
6334 terminx 501
            JOYSTICK_GetButtons(), t,
289 terminx 502
            CONTROL_NumJoyButtons,
503
            CONTROL_JoyButtonState,
504
            CONTROL_JoyButtonClickedTime,
505
            CONTROL_JoyButtonClickedState,
506
            CONTROL_JoyButtonClicked,
507
            CONTROL_JoyButtonClickedCount
508
        );
7992 hendricks2 509
        if (retval)
510
            CONTROL_LastSeenInput = LastSeenInput::Joystick;
289 terminx 511
    }
5 Plagman 512
}
513
 
7992 hendricks2 514
static int CONTROL_DigitizeAxis(int axis, controldevice device)
5 Plagman 515
{
289 terminx 516
    controlaxistype *set, *lastset;
5 Plagman 517
 
809 terminx 518
    switch (device)
519
    {
289 terminx 520
    case controldevice_joystick:
521
        set = CONTROL_JoyAxes;
522
        lastset = CONTROL_LastJoyAxes;
523
        break;
524
 
7992 hendricks2 525
    default: return 0;
289 terminx 526
    }
527
 
7970 hendricks2 528
    set[axis].digitalClearedN = lastset[axis].digitalClearedN;
529
    set[axis].digitalClearedP = lastset[axis].digitalClearedP;
530
 
809 terminx 531
    if (set[axis].analog > 0)
532
    {
7970 hendricks2 533
        set[axis].digitalClearedN = 0;
534
 
1018 terminx 535
        if (set[axis].analog > THRESHOLD || (set[axis].analog > MINTHRESHOLD && lastset[axis].digital == 1))
536
            set[axis].digital = 1;
7970 hendricks2 537
        else
538
            set[axis].digitalClearedP = 0;
7992 hendricks2 539
 
540
        return 1;
809 terminx 541
    }
7970 hendricks2 542
    else if (set[axis].analog < 0)
809 terminx 543
    {
7970 hendricks2 544
        set[axis].digitalClearedP = 0;
545
 
1018 terminx 546
        if (set[axis].analog < -THRESHOLD || (set[axis].analog < -MINTHRESHOLD && lastset[axis].digital == -1))
289 terminx 547
            set[axis].digital = -1;
7970 hendricks2 548
        else
549
            set[axis].digitalClearedN = 0;
7992 hendricks2 550
 
551
        return 1;
289 terminx 552
    }
7970 hendricks2 553
    else
554
    {
555
        set[axis].digitalClearedN = 0;
556
        set[axis].digitalClearedP = 0;
557
    }
7992 hendricks2 558
 
559
    return 0;
5 Plagman 560
}
561
 
7181 terminx 562
static void CONTROL_ScaleAxis(int axis, controldevice device)
5 Plagman 563
{
289 terminx 564
    controlaxistype *set;
1346 terminx 565
    int32_t *scale;
7986 hendricks2 566
    int8_t * invert;
5 Plagman 567
 
809 terminx 568
    switch (device)
569
    {
289 terminx 570
    case controldevice_joystick:
571
        set = CONTROL_JoyAxes;
572
        scale = CONTROL_JoyAxesScale;
7986 hendricks2 573
        invert = CONTROL_JoyAxesInvert;
289 terminx 574
        break;
5 Plagman 575
 
289 terminx 576
    default: return;
577
    }
578
 
7986 hendricks2 579
    int const invertResult = !!invert[axis];
580
    set[axis].analog = (mulscale16(set[axis].analog, scale[axis]) ^ -invertResult) + invertResult;
5 Plagman 581
}
582
 
7181 terminx 583
static void CONTROL_ApplyAxis(int axis, ControlInfo *info, controldevice device)
5 Plagman 584
{
289 terminx 585
    controlaxistype *set;
586
    controlaxismaptype *map;
5 Plagman 587
 
809 terminx 588
    switch (device)
589
    {
289 terminx 590
    case controldevice_joystick:
591
        set = CONTROL_JoyAxes;
592
        map = CONTROL_JoyAxesMap;
593
        break;
5 Plagman 594
 
289 terminx 595
    default: return;
596
    }
597
 
809 terminx 598
    switch (map[axis].analogmap)
599
    {
289 terminx 600
    case analog_turning:          info->dyaw   += set[axis].analog; break;
601
    case analog_strafing:         info->dx     += set[axis].analog; break;
602
    case analog_lookingupanddown: info->dpitch += set[axis].analog; break;
603
    case analog_elevation:        info->dy     += set[axis].analog; break;
604
    case analog_rolling:          info->droll  += set[axis].analog; break;
605
    case analog_moving:           info->dz     += set[axis].analog; break;
606
    default: break;
607
    }
5 Plagman 608
}
609
 
2940 helixhorne 610
static void CONTROL_PollDevices(ControlInfo *info)
5 Plagman 611
{
289 terminx 612
    memset(info, 0, sizeof(ControlInfo));
5 Plagman 613
 
4386 terminx 614
#ifdef __ANDROID__
615
    CONTROL_Android_PollDevices(info);
616
#endif
617
 
809 terminx 618
    if (CONTROL_MouseEnabled)
7947 hendricks2 619
        CONTROL_GetMouseDelta(info);
1014 terminx 620
 
809 terminx 621
    if (CONTROL_JoystickEnabled)
622
    {
3200 terminx 623
        Bmemcpy(CONTROL_LastJoyAxes,   CONTROL_JoyAxes,   sizeof(CONTROL_JoyAxes));
624
        memset(CONTROL_JoyAxes,   0, sizeof(CONTROL_JoyAxes));
625
 
7181 terminx 626
        for (int i=joystick.numAxes-1; i>=0; i--)
809 terminx 627
        {
6827 terminx 628
            CONTROL_JoyAxes[i].analog = joystick.pAxis[i];
3196 terminx 629
 
7992 hendricks2 630
            if (CONTROL_DigitizeAxis(i, controldevice_joystick))
631
                CONTROL_LastSeenInput = LastSeenInput::Joystick;
289 terminx 632
            CONTROL_ScaleAxis(i, controldevice_joystick);
633
            LIMITCONTROL(&CONTROL_JoyAxes[i].analog);
634
            CONTROL_ApplyAxis(i, info, controldevice_joystick);
1017 terminx 635
        }
289 terminx 636
    }
637
 
638
    CONTROL_GetDeviceButtons();
5 Plagman 639
}
640
 
7992 hendricks2 641
static int CONTROL_HandleAxisFunction(int32_t *p1, controlaxistype *axes, controlaxismaptype *axismap, int numAxes)
5 Plagman 642
{
7181 terminx 643
    int axis = numAxes - 1;
7992 hendricks2 644
    int retval = 0;
7181 terminx 645
 
646
    do
809 terminx 647
    {
7181 terminx 648
        if (!axes[axis].digital)
649
            continue;
5 Plagman 650
 
7181 terminx 651
        int const j = (axes[axis].digital < 0) ? axismap[axis].minmap : axismap[axis].maxmap;
5 Plagman 652
 
7181 terminx 653
        if (j != AXISUNDEFINED)
7992 hendricks2 654
        {
7181 terminx 655
            p1[j] = 1;
7992 hendricks2 656
            retval = 1;
657
        }
1016 terminx 658
    }
7181 terminx 659
    while (axis--);
7992 hendricks2 660
 
661
    return retval;
7181 terminx 662
}
1014 terminx 663
 
7181 terminx 664
static void CONTROL_AxisFunctionState(int32_t *p1)
665
{
1016 terminx 666
    if (CONTROL_NumJoyAxes)
7992 hendricks2 667
    {
668
        if (CONTROL_HandleAxisFunction(p1, CONTROL_JoyAxes, CONTROL_JoyAxesMap, CONTROL_NumJoyAxes))
669
            CONTROL_LastSeenInput = LastSeenInput::Joystick;
670
    }
5 Plagman 671
}
672
 
3124 helixhorne 673
static void CONTROL_ButtonFunctionState(int32_t *p1)
5 Plagman 674
{
1018 terminx 675
    if (CONTROL_NumMouseButtons)
676
    {
7181 terminx 677
        int i = CONTROL_NumMouseButtons-1, j;
5 Plagman 678
 
1018 terminx 679
        do
826 terminx 680
        {
6328 terminx 681
            if (!CONTROL_KeyBinds[MAXBOUNDKEYS + i].cmdstr)
1018 terminx 682
            {
683
                j = CONTROL_MouseButtonMapping[i].doubleclicked;
684
                if (j != KEYUNDEFINED)
685
                    p1[j] |= CONTROL_MouseButtonClickedState[i];
826 terminx 686
 
1018 terminx 687
                j = CONTROL_MouseButtonMapping[i].singleclicked;
688
                if (j != KEYUNDEFINED)
689
                    p1[j] |= CONTROL_MouseButtonState[i];
690
            }
5 Plagman 691
 
3195 terminx 692
            if (!CONTROL_BindsEnabled)
1018 terminx 693
                continue;
1017 terminx 694
 
6328 terminx 695
            if (CONTROL_KeyBinds[MAXBOUNDKEYS + i].cmdstr && CONTROL_MouseButtonState[i])
1018 terminx 696
            {
6328 terminx 697
                if (CONTROL_KeyBinds[MAXBOUNDKEYS + i].repeat || (CONTROL_KeyBinds[MAXBOUNDKEYS + i].laststate == 0))
698
                    OSD_Dispatch(CONTROL_KeyBinds[MAXBOUNDKEYS + i].cmdstr);
1018 terminx 699
            }
6328 terminx 700
            CONTROL_KeyBinds[MAXBOUNDKEYS + i].laststate = CONTROL_MouseButtonState[i];
1017 terminx 701
        }
1023 terminx 702
        while (i--);
1017 terminx 703
    }
704
 
1018 terminx 705
    if (CONTROL_NumJoyButtons)
809 terminx 706
    {
7181 terminx 707
        int i=CONTROL_NumJoyButtons-1, j;
7992 hendricks2 708
        int retval = 0;
5 Plagman 709
 
1018 terminx 710
        do
711
        {
712
            j = CONTROL_JoyButtonMapping[i].doubleclicked;
713
            if (j != KEYUNDEFINED)
7992 hendricks2 714
            {
715
                auto const state = CONTROL_JoyButtonClickedState[i];
716
                p1[j] |= state;
717
                retval |= state;
718
            }
1018 terminx 719
 
720
            j = CONTROL_JoyButtonMapping[i].singleclicked;
721
            if (j != KEYUNDEFINED)
7992 hendricks2 722
            {
723
                auto const state = CONTROL_JoyButtonState[i];
724
                p1[j] |= state;
725
                retval |= state;
726
            }
1018 terminx 727
        }
1023 terminx 728
        while (i--);
7992 hendricks2 729
 
730
        if (retval)
731
            CONTROL_LastSeenInput = LastSeenInput::Joystick;
1017 terminx 732
    }
5 Plagman 733
}
734
 
7181 terminx 735
void CONTROL_ClearButton(int whichbutton)
5 Plagman 736
{
5625 terminx 737
    if (CONTROL_CheckRange(whichbutton)) return;
4440 terminx 738
 
739
#ifdef __ANDROID__
740
    CONTROL_Android_ClearButton(whichbutton);
5625 terminx 741
#endif
742
 
809 terminx 743
    BUTTONCLEAR(whichbutton);
1346 terminx 744
    CONTROL_Flags[whichbutton].cleared = TRUE;
5 Plagman 745
}
746
 
7898 hendricks2 747
void CONTROL_ClearAllButtons(void)
748
{
749
    CONTROL_ButtonHeldState = 0;
750
    CONTROL_ButtonState = 0;
751
 
752
    for (auto & c : CONTROL_Flags)
753
        c.cleared = TRUE;
754
}
755
 
7970 hendricks2 756
int32_t CONTROL_GetGameControllerDigitalAxisPos(int32_t axis)
757
{
758
    if (!joystick.isGameController)
759
        return 0;
760
 
761
    return CONTROL_JoyAxes[axis].digital > 0 && !CONTROL_JoyAxes[axis].digitalClearedP;
762
}
763
int32_t CONTROL_GetGameControllerDigitalAxisNeg(int32_t axis)
764
{
765
    if (!joystick.isGameController)
766
        return 0;
767
 
768
    return CONTROL_JoyAxes[axis].digital < 0 && !CONTROL_JoyAxes[axis].digitalClearedN;
769
}
770
 
771
void CONTROL_ClearGameControllerDigitalAxisPos(int32_t axis)
772
{
773
    if (!joystick.isGameController)
774
        return;
775
 
776
    CONTROL_JoyAxes[axis].digitalClearedP = 1;
777
}
778
void CONTROL_ClearGameControllerDigitalAxisNeg(int32_t axis)
779
{
780
    if (!joystick.isGameController)
781
        return;
782
 
783
    CONTROL_JoyAxes[axis].digitalClearedN = 1;
784
}
785
 
1632 terminx 786
void CONTROL_ProcessBinds(void)
808 terminx 787
{
3195 terminx 788
    if (!CONTROL_BindsEnabled)
1425 terminx 789
        return;
808 terminx 790
 
7181 terminx 791
    int i = MAXBOUNDKEYS-1;
792
 
1632 terminx 793
    do
808 terminx 794
    {
3197 terminx 795
        if (CONTROL_KeyBinds[i].cmdstr)
808 terminx 796
        {
7992 hendricks2 797
            auto const keyPressed = KB_KeyPressed(i);
798
 
799
            if (keyPressed && (CONTROL_KeyBinds[i].repeat || (CONTROL_KeyBinds[i].laststate == 0)))
800
            {
801
                CONTROL_LastSeenInput = LastSeenInput::Keyboard;
3197 terminx 802
                OSD_Dispatch(CONTROL_KeyBinds[i].cmdstr);
7992 hendricks2 803
            }
3127 helixhorne 804
 
7992 hendricks2 805
            CONTROL_KeyBinds[i].laststate = keyPressed;
808 terminx 806
        }
1017 terminx 807
    }
1632 terminx 808
    while (i--);
808 terminx 809
}
810
 
2940 helixhorne 811
static void CONTROL_GetFunctionInput(void)
5 Plagman 812
{
7181 terminx 813
    CONTROL_ButtonFunctionState(CONTROL_ButtonFlags);
814
    CONTROL_AxisFunctionState(CONTROL_ButtonFlags);
5 Plagman 815
 
1144 terminx 816
    CONTROL_ButtonHeldState = CONTROL_ButtonState;
817
    CONTROL_ButtonState = 0;
5 Plagman 818
 
7181 terminx 819
    int i = CONTROL_NUM_FLAGS-1;
820
 
1632 terminx 821
    do
809 terminx 822
    {
8303 hendricks2 823
        CONTROL_SetFlag(i, CONTROL_KeyboardFunctionPressed(i) | CONTROL_ButtonFlags[i]);
5 Plagman 824
 
1632 terminx 825
        if (CONTROL_Flags[i].cleared == FALSE) BUTTONSET(i, CONTROL_Flags[i].active);
826
        else if (CONTROL_Flags[i].active == FALSE) CONTROL_Flags[i].cleared = 0;
289 terminx 827
    }
1632 terminx 828
    while (i--);
1014 terminx 829
 
7181 terminx 830
    memset(CONTROL_ButtonFlags, 0, sizeof(CONTROL_ButtonFlags));
5 Plagman 831
}
832
 
2728 hendricks2 833
void CONTROL_GetInput(ControlInfo *info)
834
{
4440 terminx 835
#ifdef __ANDROID__
836
    CONTROL_Android_PollDevices(info);
7181 terminx 837
#endif
2728 hendricks2 838
    CONTROL_PollDevices(info);
839
    CONTROL_GetFunctionInput();
4200 hendricks2 840
    inputchecked = 1;
2728 hendricks2 841
}
842
 
7985 hendricks2 843
static void CONTROL_ResetJoystickValues()
844
{
845
    CONTROL_NumJoyAxes      = min(MAXJOYAXES, joystick.numAxes);
846
    CONTROL_NumJoyButtons   = min(MAXJOYBUTTONS, joystick.numButtons + 4 * (joystick.numHats > 0));
847
    CONTROL_JoystickEnabled = CONTROL_JoyPresent = !!((inputdevices & 4) >> 2);
848
}
849
 
850
void CONTROL_ScanForControllers()
851
{
852
    joyScanDevices();
853
    CONTROL_ResetJoystickValues();
854
}
855
 
7181 terminx 856
bool CONTROL_Startup(controltype which, int32_t(*TimeFunction)(void), int32_t ticspersecond)
5 Plagman 857
{
654 terminx 858
    UNREFERENCED_PARAMETER(which);
649 terminx 859
 
7181 terminx 860
    if (CONTROL_Started) return false;
5 Plagman 861
 
7181 terminx 862
    ExtGetTime = TimeFunction ? TimeFunction : CONTROL_GetTime;
5 Plagman 863
 
7181 terminx 864
    // what the fuck???
865
    CONTROL_DoubleClickSpeed = (ticspersecond * 57) / 100;
5 Plagman 866
 
289 terminx 867
    if (CONTROL_DoubleClickSpeed <= 0)
868
        CONTROL_DoubleClickSpeed = 1;
5 Plagman 869
 
8005 terminx 870
    if (initinput())
7181 terminx 871
        return true;
5 Plagman 872
 
289 terminx 873
    KB_Startup();
5 Plagman 874
 
7181 terminx 875
    CONTROL_NumMouseButtons = MAXMOUSEBUTTONS;
876
    CONTROL_MousePresent    = Mouse_Init();
877
    CONTROL_MouseEnabled    = CONTROL_MousePresent;
5 Plagman 878
 
7985 hendricks2 879
    CONTROL_ResetJoystickValues();
5 Plagman 880
 
2624 helixhorne 881
#ifdef GEKKO
289 terminx 882
    if (CONTROL_MousePresent)
883
        initprintf("CONTROL_Startup: Mouse Present\n");
7181 terminx 884
 
289 terminx 885
    if (CONTROL_JoyPresent)
886
        initprintf("CONTROL_Startup: Joystick Present\n");
2334 helixhorne 887
#endif
5 Plagman 888
 
1144 terminx 889
    CONTROL_ButtonState     = 0;
890
    CONTROL_ButtonHeldState = 0;
289 terminx 891
 
7181 terminx 892
    for (auto & CONTROL_Flag : CONTROL_Flags)
893
        CONTROL_Flag.used = FALSE;
289 terminx 894
 
1346 terminx 895
    CONTROL_Started = TRUE;
289 terminx 896
 
7181 terminx 897
    return false;
5 Plagman 898
}
899
 
900
void CONTROL_Shutdown(void)
901
{
3209 helixhorne 902
    if (!CONTROL_Started)
903
        return;
3197 terminx 904
 
3209 helixhorne 905
    CONTROL_ClearAllBinds();
5 Plagman 906
 
289 terminx 907
    MOUSE_Shutdown();
908
    uninitinput();
5 Plagman 909
 
1346 terminx 910
    CONTROL_Started = FALSE;
5 Plagman 911
}
912
 
8293 hendricks2 913
 
914
// temporary hack until input is unified
915
void CONTROL_GetUserInput(UserInput * uinfo)
916
{
917
    if (
918
        KB_KeyPressed(sc_DownArrow)
919
        || KB_KeyPressed(sc_kpad_2)
920
        || (MOUSE_GetButtons()&WHEELDOWN_MOUSE)
921
        )
922
        uinfo->dir = dir_South;
923
    else if (
924
        KB_KeyPressed(sc_UpArrow)
925
        || KB_KeyPressed(sc_kpad_8)
926
        || (MOUSE_GetButtons()&WHEELUP_MOUSE)
927
        )
928
        uinfo->dir = dir_North;
929
    else if (
930
        KB_KeyPressed(sc_LeftArrow)
931
        || KB_KeyPressed(sc_kpad_4)
932
        )
933
        uinfo->dir = dir_West;
934
    else if (
935
        KB_KeyPressed(sc_RightArrow)
936
        || KB_KeyPressed(sc_kpad_6)
937
        )
938
        uinfo->dir = dir_East;
939
 
940
    uinfo->button0 =
941
        KB_KeyPressed(sc_Enter)
942
        || KB_KeyPressed(sc_kpad_Enter)
943
        || (MOUSE_GetButtons()&LEFT_MOUSE)
944
        ;
945
 
946
    uinfo->button1 =
947
        KB_KeyPressed(sc_Escape)
948
        || (MOUSE_GetButtons()&RIGHT_MOUSE)
949
        ;
950
}
951
void CONTROL_ClearUserInput(UserInput * uinfo)
952
{
8486 hendricks2 953
    UNREFERENCED_PARAMETER(uinfo);
954
 
8341 hendricks2 955
    KB_FlushKeyboardQueue();
956
 
957
    KB_ClearKeyDown(sc_UpArrow);
958
    KB_ClearKeyDown(sc_kpad_8);
959
    MOUSE_ClearButton(WHEELUP_MOUSE);
960
 
961
    KB_ClearKeyDown(sc_DownArrow);
962
    KB_ClearKeyDown(sc_kpad_2);
963
    MOUSE_ClearButton(WHEELDOWN_MOUSE);
964
 
965
    KB_ClearKeyDown(sc_LeftArrow);
966
    KB_ClearKeyDown(sc_kpad_4);
967
 
968
    KB_ClearKeyDown(sc_RightArrow);
969
    KB_ClearKeyDown(sc_kpad_6);
970
 
971
    KB_ClearKeyDown(sc_kpad_Enter);
972
    KB_ClearKeyDown(sc_Enter);
973
    MOUSE_ClearButton(LEFT_MOUSE);
974
 
975
    KB_ClearKeyDown(sc_Escape);
976
    MOUSE_ClearButton(RIGHT_MOUSE);
8293 hendricks2 977
}