Subversion Repositories eduke32

Rev

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