Subversion Repositories eduke32

Rev

Rev 8776 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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