1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
inputdev.h
Input devices, items and device classes.
***************************************************************************/
#ifndef MAME_EMU_INPUTDEV_H
#define MAME_EMU_INPUTDEV_H
#pragma once
//**************************************************************************
// CONSTANTS
//**************************************************************************
// relative devices return ~512 units per onscreen pixel
constexpr s32 INPUT_RELATIVE_PER_PIXEL = 512;
// absolute devices return values between -65536 and +65536
constexpr s32 INPUT_ABSOLUTE_MIN = -65536;
constexpr s32 INPUT_ABSOLUTE_MAX = 65536;
// invalid memory value for axis polling
constexpr s32 INVALID_AXIS_VALUE = 0x7fffffff;
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// callback for getting the value of an item on a device
typedef s32 (*item_get_state_func)(void *device_internal, void *item_internal);
// ======================> joystick_map
// a 9x9 joystick map
class joystick_map
{
public:
// construction/destruction
joystick_map();
joystick_map(const joystick_map &src) { copy(src); }
// operators
joystick_map &operator=(const joystick_map &src) { if (this != &src) copy(src); return *this; }
// parse from a string
bool parse(const char *mapstring);
// create a friendly string
std::string to_string() const;
// update the state of a live map
u8 update(s32 xaxisval, s32 yaxisval);
// joystick mapping codes
static constexpr u8 JOYSTICK_MAP_NEUTRAL = 0x00;
static constexpr u8 JOYSTICK_MAP_LEFT = 0x01;
static constexpr u8 JOYSTICK_MAP_RIGHT = 0x02;
static constexpr u8 JOYSTICK_MAP_UP = 0x04;
static constexpr u8 JOYSTICK_MAP_DOWN = 0x08;
static constexpr u8 JOYSTICK_MAP_STICKY = 0x0f;
private:
// internal helpers
void copy(const joystick_map &src)
{
memcpy(m_map, src.m_map, sizeof(m_map));
m_lastmap = JOYSTICK_MAP_NEUTRAL;
m_origstring = src.m_origstring;
}
// internal state
u8 m_map[9][9]; // 9x9 grid
u8 m_lastmap; // last value returned (for sticky tracking)
std::string m_origstring; // originally parsed string
};
// ======================> input_device_item
// a single item on an input device
class input_device_item
{
protected:
// construction/destruction
input_device_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate, input_item_class itemclass);
public:
virtual ~input_device_item();
// getters
input_device &device() const { return m_device; }
input_manager &manager() const;
running_machine &machine() const;
const char *name() const { return m_name.c_str(); }
void *internal() const { return m_internal; }
input_item_id itemid() const { return m_itemid; }
input_item_class itemclass() const { return m_itemclass; }
input_code code() const;
const char *token() const { return m_token.c_str(); }
s32 current() const { return m_current; }
s32 memory() const { return m_memory; }
// helpers
s32 update_value();
void set_memory(s32 value) { m_memory = value; }
bool check_axis(input_item_modifier modifier);
// readers
virtual s32 read_as_switch(input_item_modifier modifier) = 0;
virtual s32 read_as_relative(input_item_modifier modifier) = 0;
virtual s32 read_as_absolute(input_item_modifier modifier) = 0;
virtual bool item_check_axis(input_item_modifier modifier) = 0;
protected:
// internal state
input_device & m_device; // reference to our owning device
std::string m_name; // string name of item
void * m_internal; // internal callback pointer
input_item_id m_itemid; // originally specified item id
input_item_class m_itemclass; // class of the item
item_get_state_func m_getstate; // get state callback
std::string m_token; // tokenized name for non-standard items
// live state
s32 m_current; // current raw value
s32 m_memory; // "memory" value, to remember where we started during polling
};
// ======================> input_device
// a logical device of a given class that can provide input
class input_device
{
friend class input_class;
public:
// construction/destruction
input_device(input_manager &manager, const char *_name, const char *_id, void *_internal);
virtual ~input_device();
// getters
input_manager &manager() const { return m_manager; }
running_machine &machine() const { return m_manager.machine(); }
input_device_class devclass() const { return device_class(); }
const char *name() const { return m_name.c_str(); }
const char *id() const { return m_id.c_str(); }
int devindex() const { return m_devindex; }
input_device_item *item(input_item_id index) const { return m_item[index].get(); }
input_item_id maxitem() const { return m_maxitem; }
void *internal() const { return m_internal; }
bool steadykey_enabled() const { return m_steadykey_enabled; }
bool lightgun_reload_button() const { return m_lightgun_reload_button; }
// setters
void set_devindex(int devindex) { m_devindex = devindex; }
// item management
input_item_id add_item(const char *name, input_item_id itemid, item_get_state_func getstate, void *internal = nullptr);
// helpers
s32 adjust_absolute(s32 value) const { return adjust_absolute_value(value); }
bool match_device_id(const char *deviceid);
protected:
// specific overrides
virtual input_device_class device_class() const = 0;
virtual s32 adjust_absolute_value(s32 value) const { return value; }
private:
// internal state
input_manager & m_manager; // reference to input manager
std::string m_name; // string name of device
std::string m_id; // id of device
int m_devindex; // device index of this device
std::unique_ptr<input_device_item> m_item[ITEM_ID_ABSOLUTE_MAXIMUM+1]; // array of pointers to items
input_item_id m_maxitem; // maximum item index
void * m_internal; // internal callback pointer
bool m_steadykey_enabled; // steadykey enabled for keyboards
bool m_lightgun_reload_button; // lightgun reload hack
};
// ======================> input_device_keyboard
class input_device_keyboard : public input_device
{
public:
// construction/destruction
input_device_keyboard(input_manager &manager, const char *_name, const char *_id, void *_internal);
// helpers
void apply_steadykey() const;
protected:
// specific overrides
virtual input_device_class device_class() const override { return DEVICE_CLASS_KEYBOARD; }
};
// ======================> input_device_mouse
class input_device_mouse : public input_device
{
public:
// construction/destruction
input_device_mouse(input_manager &manager, const char *_name, const char *_id, void *_internal);
protected:
// specific overrides
virtual input_device_class device_class() const override { return DEVICE_CLASS_MOUSE; }
};
// ======================> input_device_lightgun
class input_device_lightgun : public input_device
{
public:
// construction/destruction
input_device_lightgun(input_manager &manager, const char *_name, const char *_id, void *_internal);
protected:
// specific overrides
virtual input_device_class device_class() const override { return DEVICE_CLASS_LIGHTGUN; }
};
// ======================> input_device_joystick
// a logical device of a given class that can provide input
class input_device_joystick : public input_device
{
public:
// construction/destruction
input_device_joystick(input_manager &manager, const char *_name, const char *_id, void *_internal);
// getters
joystick_map &joymap() { return m_joymap; }
// item management
void set_joystick_map(const joystick_map &map) { m_joymap = map; }
protected:
// specific overrides
virtual input_device_class device_class() const override { return DEVICE_CLASS_JOYSTICK; }
virtual s32 adjust_absolute_value(s32 value) const override;
private:
// joystick information
joystick_map m_joymap; // joystick map for this device
s32 m_joystick_deadzone; // deadzone for joystick
s32 m_joystick_saturation; // saturation position for joystick
};
// ======================> input_class
// a class of device that provides input
class input_class
{
public:
// construction/destruction
input_class(input_manager &manager, input_device_class devclass, const char *name, bool enabled = false, bool multi = false);
virtual ~input_class();
// getters
input_manager &manager() const { return m_manager; }
running_machine &machine() const { return m_manager.machine(); }
input_device *device(int index) const { return (index <= m_maxindex) ? m_device[index].get() : nullptr; }
input_device_class devclass() const { return m_devclass; }
const char *name() const { return m_name; }
int maxindex() const { return m_maxindex; }
bool enabled() const { return m_enabled; }
bool multi() const { return m_multi; }
// setters
void enable(bool state = true) { m_enabled = state; }
void set_multi(bool multi = true) { m_multi = multi; }
// device management
input_device *add_device(const char *name, const char *id, void *internal = nullptr);
input_device *add_device(std::unique_ptr<input_device> &&new_device);
// misc helpers
input_item_class standard_item_class(input_item_id itemid) const;
void remap_device_index(int oldindex, int newindex);
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) = 0;
private:
// indexing helpers
int newindex(input_device &device);
// internal state
input_manager & m_manager; // reference to our manager
std::unique_ptr<input_device> m_device[DEVICE_INDEX_MAXIMUM]; // array of devices in this class
input_device_class m_devclass; // our device class
const char * m_name; // name of class (used for option settings)
int m_maxindex; // maximum populated index
bool m_enabled; // is this class enabled?
bool m_multi; // are multiple instances of this class allowed?
};
// ======================> input_class_keyboard
// class of device that provides keyboard input
class input_class_keyboard : public input_class
{
public:
// construction/destruction
input_class_keyboard(input_manager &manager);
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
{
return std::make_unique<input_device_keyboard>(manager(), name, id, internal);
}
private:
// internal helpers
void frame_callback();
};
// ======================> input_class_mouse
// class of device that provides mouse input
class input_class_mouse : public input_class
{
public:
// construction/destruction
input_class_mouse(input_manager &manager);
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
{
return std::make_unique<input_device_mouse>(manager(), name, id, internal);
}
};
// ======================> input_class_lightgun
// class of device that provides lightgun input
class input_class_lightgun : public input_class
{
public:
// construction/destruction
input_class_lightgun(input_manager &manager);
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
{
return std::make_unique<input_device_lightgun>(manager(), name, id, internal);
}
};
// ======================> input_class_joystick
// class of device that provides joystick input
class input_class_joystick : public input_class
{
public:
// construction/destruction
input_class_joystick(input_manager &manager);
// misc
bool set_global_joystick_map(const char *mapstring);
// standard joystick maps
static const char map_8way[];
static const char map_4way_diagonal[];
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
{
return std::make_unique<input_device_joystick>(manager(), name, id, internal);
}
};
//**************************************************************************
// INLINE FUNCTIONS
//**************************************************************************
// input_device_item helpers
inline input_manager &input_device_item::manager() const { return m_device.manager(); }
inline running_machine &input_device_item::machine() const { return m_device.machine(); }
inline input_code input_device_item::code() const { return input_code(m_device.devclass(), m_device.devindex(), m_itemclass, ITEM_MODIFIER_NONE, m_itemid); }
inline s32 input_device_item::update_value() { return m_current = (*m_getstate)(m_device.internal(), m_internal); }
#endif // MAME_EMU_INPUTDEV_H
|