Subversion Repositories eduke32

Rev

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