summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/input.h
blob: 24b6dd062d24822b2e0243c82257f760a2ddddb6 (plain) (blame)
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
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    input.h

    Handle input from the user.

***************************************************************************/

#pragma once

#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif

#ifndef MAME_EMU_INPUT_H
#define MAME_EMU_INPUT_H

#include <algorithm>
#include <array>
#include <iterator>


//**************************************************************************
//  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;

// maximum number of axis/buttons/hats with ITEM_IDs for use by osd layer
constexpr int INPUT_MAX_AXIS = 8;
constexpr int INPUT_MAX_BUTTONS = 32;
constexpr int INPUT_MAX_HATS = 4;
constexpr int INPUT_MAX_ADD_SWITCH = 16;
constexpr int INPUT_MAX_ADD_ABSOLUTE = 16;
constexpr int INPUT_MAX_ADD_RELATIVE = 16;


// device classes
enum input_device_class
{
	DEVICE_CLASS_INVALID,
	DEVICE_CLASS_FIRST_VALID,
	DEVICE_CLASS_KEYBOARD = DEVICE_CLASS_FIRST_VALID,
	DEVICE_CLASS_MOUSE,
	DEVICE_CLASS_LIGHTGUN,
	DEVICE_CLASS_JOYSTICK,
	DEVICE_CLASS_LAST_VALID = DEVICE_CLASS_JOYSTICK,
	DEVICE_CLASS_INTERNAL,
	DEVICE_CLASS_MAXIMUM
};
DECLARE_ENUM_INCDEC_OPERATORS(input_device_class)


// device index
constexpr int DEVICE_INDEX_MAXIMUM = 0xff;


// input item classes
enum input_item_class
{
	ITEM_CLASS_INVALID,
	ITEM_CLASS_SWITCH,
	ITEM_CLASS_ABSOLUTE,
	ITEM_CLASS_RELATIVE,
	ITEM_CLASS_MAXIMUM
};


// input item modifiers
enum input_item_modifier
{
	ITEM_MODIFIER_NONE,
	ITEM_MODIFIER_POS,
	ITEM_MODIFIER_NEG,
	ITEM_MODIFIER_LEFT,
	ITEM_MODIFIER_RIGHT,
	ITEM_MODIFIER_UP,
	ITEM_MODIFIER_DOWN,
	ITEM_MODIFIER_MAXIMUM
};


// standard item IDs
enum input_item_id
{
	ITEM_ID_INVALID,
	ITEM_ID_FIRST_VALID,

	// standard keyboard IDs
	ITEM_ID_A = ITEM_ID_FIRST_VALID,
	ITEM_ID_B,
	ITEM_ID_C,
	ITEM_ID_D,
	ITEM_ID_E,
	ITEM_ID_F,
	ITEM_ID_G,
	ITEM_ID_H,
	ITEM_ID_I,
	ITEM_ID_J,
	ITEM_ID_K,
	ITEM_ID_L,
	ITEM_ID_M,
	ITEM_ID_N,
	ITEM_ID_O,
	ITEM_ID_P,
	ITEM_ID_Q,
	ITEM_ID_R,
	ITEM_ID_S,
	ITEM_ID_T,
	ITEM_ID_U,
	ITEM_ID_V,
	ITEM_ID_W,
	ITEM_ID_X,
	ITEM_ID_Y,
	ITEM_ID_Z,
	ITEM_ID_0,
	ITEM_ID_1,
	ITEM_ID_2,
	ITEM_ID_3,
	ITEM_ID_4,
	ITEM_ID_5,
	ITEM_ID_6,
	ITEM_ID_7,
	ITEM_ID_8,
	ITEM_ID_9,
	ITEM_ID_F1,
	ITEM_ID_F2,
	ITEM_ID_F3,
	ITEM_ID_F4,
	ITEM_ID_F5,
	ITEM_ID_F6,
	ITEM_ID_F7,
	ITEM_ID_F8,
	ITEM_ID_F9,
	ITEM_ID_F10,
	ITEM_ID_F11,
	ITEM_ID_F12,
	ITEM_ID_F13,
	ITEM_ID_F14,
	ITEM_ID_F15,
	ITEM_ID_F16,
	ITEM_ID_F17,
	ITEM_ID_F18,
	ITEM_ID_F19,
	ITEM_ID_F20,
	ITEM_ID_ESC,
	ITEM_ID_TILDE,
	ITEM_ID_MINUS,
	ITEM_ID_EQUALS,
	ITEM_ID_BACKSPACE,
	ITEM_ID_TAB,
	ITEM_ID_OPENBRACE,
	ITEM_ID_CLOSEBRACE,
	ITEM_ID_ENTER,
	ITEM_ID_COLON,
	ITEM_ID_QUOTE,
	ITEM_ID_BACKSLASH,
	ITEM_ID_BACKSLASH2,
	ITEM_ID_COMMA,
	ITEM_ID_STOP,
	ITEM_ID_SLASH,
	ITEM_ID_SPACE,
	ITEM_ID_INSERT,
	ITEM_ID_DEL,
	ITEM_ID_HOME,
	ITEM_ID_END,
	ITEM_ID_PGUP,
	ITEM_ID_PGDN,
	ITEM_ID_LEFT,
	ITEM_ID_RIGHT,
	ITEM_ID_UP,
	ITEM_ID_DOWN,
	ITEM_ID_0_PAD,
	ITEM_ID_1_PAD,
	ITEM_ID_2_PAD,
	ITEM_ID_3_PAD,
	ITEM_ID_4_PAD,
	ITEM_ID_5_PAD,
	ITEM_ID_6_PAD,
	ITEM_ID_7_PAD,
	ITEM_ID_8_PAD,
	ITEM_ID_9_PAD,
	ITEM_ID_SLASH_PAD,
	ITEM_ID_ASTERISK,
	ITEM_ID_MINUS_PAD,
	ITEM_ID_PLUS_PAD,
	ITEM_ID_DEL_PAD,
	ITEM_ID_ENTER_PAD,
	ITEM_ID_BS_PAD,
	ITEM_ID_TAB_PAD,
	ITEM_ID_00_PAD,
	ITEM_ID_000_PAD,
	ITEM_ID_COMMA_PAD,
	ITEM_ID_EQUALS_PAD,
	ITEM_ID_PRTSCR,
	ITEM_ID_PAUSE,
	ITEM_ID_LSHIFT,
	ITEM_ID_RSHIFT,
	ITEM_ID_LCONTROL,
	ITEM_ID_RCONTROL,
	ITEM_ID_LALT,
	ITEM_ID_RALT,
	ITEM_ID_SCRLOCK,
	ITEM_ID_NUMLOCK,
	ITEM_ID_CAPSLOCK,
	ITEM_ID_LWIN,
	ITEM_ID_RWIN,
	ITEM_ID_MENU,
	ITEM_ID_CANCEL,

	// standard mouse/joystick/gun IDs
	ITEM_ID_XAXIS,
	ITEM_ID_YAXIS,
	ITEM_ID_ZAXIS,
	ITEM_ID_RXAXIS,
	ITEM_ID_RYAXIS,
	ITEM_ID_RZAXIS,
	ITEM_ID_SLIDER1,
	ITEM_ID_SLIDER2,
	ITEM_ID_BUTTON1,
	ITEM_ID_BUTTON2,
	ITEM_ID_BUTTON3,
	ITEM_ID_BUTTON4,
	ITEM_ID_BUTTON5,
	ITEM_ID_BUTTON6,
	ITEM_ID_BUTTON7,
	ITEM_ID_BUTTON8,
	ITEM_ID_BUTTON9,
	ITEM_ID_BUTTON10,
	ITEM_ID_BUTTON11,
	ITEM_ID_BUTTON12,
	ITEM_ID_BUTTON13,
	ITEM_ID_BUTTON14,
	ITEM_ID_BUTTON15,
	ITEM_ID_BUTTON16,
	ITEM_ID_BUTTON17,
	ITEM_ID_BUTTON18,
	ITEM_ID_BUTTON19,
	ITEM_ID_BUTTON20,
	ITEM_ID_BUTTON21,
	ITEM_ID_BUTTON22,
	ITEM_ID_BUTTON23,
	ITEM_ID_BUTTON24,
	ITEM_ID_BUTTON25,
	ITEM_ID_BUTTON26,
	ITEM_ID_BUTTON27,
	ITEM_ID_BUTTON28,
	ITEM_ID_BUTTON29,
	ITEM_ID_BUTTON30,
	ITEM_ID_BUTTON31,
	ITEM_ID_BUTTON32,
	ITEM_ID_START,
	ITEM_ID_SELECT,

	// Hats
	ITEM_ID_HAT1UP,
	ITEM_ID_HAT1DOWN,
	ITEM_ID_HAT1LEFT,
	ITEM_ID_HAT1RIGHT,
	ITEM_ID_HAT2UP,
	ITEM_ID_HAT2DOWN,
	ITEM_ID_HAT2LEFT,
	ITEM_ID_HAT2RIGHT,
	ITEM_ID_HAT3UP,
	ITEM_ID_HAT3DOWN,
	ITEM_ID_HAT3LEFT,
	ITEM_ID_HAT3RIGHT,
	ITEM_ID_HAT4UP,
	ITEM_ID_HAT4DOWN,
	ITEM_ID_HAT4LEFT,
	ITEM_ID_HAT4RIGHT,

	// Additional IDs
	ITEM_ID_ADD_SWITCH1,
	ITEM_ID_ADD_SWITCH2,
	ITEM_ID_ADD_SWITCH3,
	ITEM_ID_ADD_SWITCH4,
	ITEM_ID_ADD_SWITCH5,
	ITEM_ID_ADD_SWITCH6,
	ITEM_ID_ADD_SWITCH7,
	ITEM_ID_ADD_SWITCH8,
	ITEM_ID_ADD_SWITCH9,
	ITEM_ID_ADD_SWITCH10,
	ITEM_ID_ADD_SWITCH11,
	ITEM_ID_ADD_SWITCH12,
	ITEM_ID_ADD_SWITCH13,
	ITEM_ID_ADD_SWITCH14,
	ITEM_ID_ADD_SWITCH15,
	ITEM_ID_ADD_SWITCH16,

	ITEM_ID_ADD_ABSOLUTE1,
	ITEM_ID_ADD_ABSOLUTE2,
	ITEM_ID_ADD_ABSOLUTE3,
	ITEM_ID_ADD_ABSOLUTE4,
	ITEM_ID_ADD_ABSOLUTE5,
	ITEM_ID_ADD_ABSOLUTE6,
	ITEM_ID_ADD_ABSOLUTE7,
	ITEM_ID_ADD_ABSOLUTE8,
	ITEM_ID_ADD_ABSOLUTE9,
	ITEM_ID_ADD_ABSOLUTE10,
	ITEM_ID_ADD_ABSOLUTE11,
	ITEM_ID_ADD_ABSOLUTE12,
	ITEM_ID_ADD_ABSOLUTE13,
	ITEM_ID_ADD_ABSOLUTE14,
	ITEM_ID_ADD_ABSOLUTE15,
	ITEM_ID_ADD_ABSOLUTE16,

	ITEM_ID_ADD_RELATIVE1,
	ITEM_ID_ADD_RELATIVE2,
	ITEM_ID_ADD_RELATIVE3,
	ITEM_ID_ADD_RELATIVE4,
	ITEM_ID_ADD_RELATIVE5,
	ITEM_ID_ADD_RELATIVE6,
	ITEM_ID_ADD_RELATIVE7,
	ITEM_ID_ADD_RELATIVE8,
	ITEM_ID_ADD_RELATIVE9,
	ITEM_ID_ADD_RELATIVE10,
	ITEM_ID_ADD_RELATIVE11,
	ITEM_ID_ADD_RELATIVE12,
	ITEM_ID_ADD_RELATIVE13,
	ITEM_ID_ADD_RELATIVE14,
	ITEM_ID_ADD_RELATIVE15,
	ITEM_ID_ADD_RELATIVE16,

	// generic other IDs
	ITEM_ID_OTHER_SWITCH,
	ITEM_ID_OTHER_AXIS_ABSOLUTE,
	ITEM_ID_OTHER_AXIS_RELATIVE,
	ITEM_ID_MAXIMUM,

	// internal codes for sequences
	ITEM_ID_SEQ_END,
	ITEM_ID_SEQ_DEFAULT,
	ITEM_ID_SEQ_NOT,
	ITEM_ID_SEQ_OR,

	// absolute maximum ID
	ITEM_ID_ABSOLUTE_MAXIMUM = 0xfff
};
DECLARE_ENUM_INCDEC_OPERATORS(input_item_id)



//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// controller alias table typedef
typedef std::map<std::string, std::string> devicemap_table_type;

// ======================> input_code

// a combined code that describes a particular input on a particular device
class input_code
{
public:
	// construction/destruction
	constexpr input_code(
			input_device_class devclass = DEVICE_CLASS_INVALID,
			int devindex = 0,
			input_item_class itemclass = ITEM_CLASS_INVALID,
			input_item_modifier modifier = ITEM_MODIFIER_NONE,
			input_item_id itemid = ITEM_ID_INVALID) noexcept
		: m_internal(((devclass & 0xf) << 28) | ((devindex & 0xff) << 20) | ((itemclass & 0xf) << 16) | ((modifier & 0xf) << 12) | (itemid & 0xfff))
	{
		assert(devclass >= 0 && devclass < DEVICE_CLASS_MAXIMUM);
		assert(devindex >= 0 && devindex < DEVICE_INDEX_MAXIMUM);
		assert(itemclass >= 0 && itemclass < ITEM_CLASS_MAXIMUM);
		assert(modifier >= 0 && modifier < ITEM_MODIFIER_MAXIMUM);
		assert(itemid >= 0 && itemid < ITEM_ID_ABSOLUTE_MAXIMUM);
	}
	constexpr input_code(const input_code &src) noexcept = default;

	// operators
	constexpr bool operator==(const input_code &rhs) const noexcept { return m_internal == rhs.m_internal; }
	constexpr bool operator!=(const input_code &rhs) const noexcept { return m_internal != rhs.m_internal; }

	// getters
	constexpr bool internal() const noexcept { return device_class() == DEVICE_CLASS_INTERNAL; }
	constexpr input_device_class device_class() const noexcept { return input_device_class((m_internal >> 28) & 0xf); }
	constexpr int device_index() const noexcept { return ((m_internal >> 20) & 0xff); }
	constexpr input_item_class item_class() const noexcept { return input_item_class((m_internal >> 16) & 0xf); }
	constexpr input_item_modifier item_modifier() const noexcept { return input_item_modifier((m_internal >> 12) & 0xf); }
	constexpr input_item_id item_id() const noexcept { return input_item_id(m_internal & 0xfff); }

	// setters
	void set_device_class(input_device_class devclass) noexcept
	{
		assert(devclass >= 0 && devclass <= 0xf);
		m_internal = (m_internal & ~(0xf << 28)) | ((devclass & 0xf) << 28);
	}
	void set_device_index(int devindex) noexcept
	{
		assert(devindex >= 0 && devindex <= 0xff);
		m_internal = (m_internal & ~(0xff << 20)) | ((devindex & 0xff) << 20);
	}
	void set_item_class(input_item_class itemclass) noexcept
	{
		assert(itemclass >= 0 && itemclass <= 0xf);
		m_internal = (m_internal & ~(0xf << 16)) | ((itemclass & 0xf) << 16);
	}
	void set_item_modifier(input_item_modifier modifier) noexcept
	{
		assert(modifier >= 0 && modifier <= 0xf);
		m_internal = (m_internal & ~(0xf << 12)) | ((modifier & 0xf) << 12);
	}
	void set_item_id(input_item_id itemid) noexcept
	{
		assert(itemid >= 0 && itemid <= 0xfff);
		m_internal = (m_internal & ~0xfff) | (itemid & 0xfff);
	}

private:
	u32 m_internal;
};


// ======================> input_seq

// a sequence of input_codes, supporting AND/OR and inversion
class input_seq
{
public:
	// construction/destruction
	template <typename... T> constexpr input_seq(input_code code_0 = end_code, T... code_n) noexcept
	{
		set(code_0, code_n...);
	}
	constexpr input_seq(const input_seq &rhs) noexcept = default;

	// operators
	bool operator==(const input_seq &rhs) const noexcept { return m_code == rhs.m_code; }
	bool operator!=(const input_seq &rhs) const noexcept { return m_code != rhs.m_code; }
	constexpr input_code operator[](int index) const noexcept { return (index >= 0 && index < m_code.size()) ? m_code[index] : end_code; }
	input_seq &operator+=(input_code code) noexcept;
	input_seq &operator|=(input_code code) noexcept;

	// getters
	constexpr bool empty() const noexcept { return m_code[0] == end_code; }
	constexpr int max_size() const noexcept { return std::tuple_size<decltype(m_code)>::value; }
	int length() const noexcept;
	bool is_valid() const noexcept;
	constexpr bool is_default() const noexcept { return m_code[0] == default_code; }

	// setters
	template <typename... T> void set(input_code code_0, T... code_n) noexcept
	{
		static_assert(sizeof...(T) < std::tuple_size<decltype(m_code)>::value, "too many codes for input_seq");
		set<0>(code_0, code_n...);
	}
	void reset() noexcept { set(end_code); }
	void set_default() noexcept { set(default_code); }
	void backspace() noexcept;
	void replace(input_code oldcode, input_code newcode) noexcept;

	// constant codes used in sequences
	static constexpr input_code end_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_END };
	static constexpr input_code default_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_DEFAULT };
	static constexpr input_code not_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_NOT };
	static constexpr input_code or_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_OR };

	// constant sequences
	static const input_seq empty_seq;

private:
	template <unsigned N> void set() noexcept
	{
		std::fill(std::next(m_code.begin(), N), m_code.end(), end_code);
	}
	template <unsigned N, typename... T> void set(input_code code_0, T... code_n) noexcept
	{
		m_code[N] = code_0;
		set<N + 1>(code_n...);
	}

	// internal state
	std::array<input_code, 16> m_code;
};


// ======================> input_manager

// global machine-level information about devices
class input_manager
{
public:
	// construction/destruction
	input_manager(running_machine &machine);
	~input_manager();

	// getters
	running_machine &machine() const { return m_machine; }
	input_class &device_class(input_device_class devclass) { assert(devclass >= DEVICE_CLASS_FIRST_VALID && devclass <= DEVICE_CLASS_LAST_VALID); return *m_class[devclass]; }

	// input code readers
	s32 code_value(input_code code);
	bool code_pressed(input_code code) { return code_value(code) != 0; }
	bool code_pressed_once(input_code code);

	// input code polling
	void reset_polling();
	input_code poll_axes();
	input_code poll_switches();
	input_code poll_keyboard_switches();

	// input code helpers
	input_device *device_from_code(input_code code) const;
	input_device_item *item_from_code(input_code code) const;
	input_code code_from_itemid(input_item_id itemid) const;
	std::string code_name(input_code code) const;
	std::string code_to_token(input_code code) const;
	input_code code_from_token(const char *_token);
	const char *standard_token(input_item_id itemid) const;

	// input sequence readers
	bool seq_pressed(const input_seq &seq);
	s32 seq_axis_value(const input_seq &seq, input_item_class &itemclass);

	// input sequence helpers
	input_seq seq_clean(const input_seq &seq) const;
	std::string seq_name(const input_seq &seq) const;
	std::string seq_to_tokens(const input_seq &seq) const;
	void seq_from_tokens(input_seq &seq, const char *_token);

	// misc
	bool map_device_to_controller(const devicemap_table_type *devicemap_table = nullptr);

private:
	// internal helpers
	void reset_memory();
	bool code_check_axis(input_device_item &item, input_code code);

	// internal state
	running_machine &   m_machine;
	input_code          m_switch_memory[64];

	// classes
	std::array<std::unique_ptr<input_class>, DEVICE_CLASS_MAXIMUM> m_class;
};



//**************************************************************************
//  MACROS
//**************************************************************************

// invalid codes
#define INPUT_CODE_INVALID input_code()

// keyboard codes
#define KEYCODE_A_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_A)
#define KEYCODE_B_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_B)
#define KEYCODE_C_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_C)
#define KEYCODE_D_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_D)
#define KEYCODE_E_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_E)
#define KEYCODE_F_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F)
#define KEYCODE_G_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_G)
#define KEYCODE_H_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_H)
#define KEYCODE_I_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_I)
#define KEYCODE_J_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_J)
#define KEYCODE_K_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_K)
#define KEYCODE_L_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_L)
#define KEYCODE_M_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_M)
#define KEYCODE_N_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_N)
#define KEYCODE_O_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_O)
#define KEYCODE_P_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_P)
#define KEYCODE_Q_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Q)
#define KEYCODE_R_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_R)
#define KEYCODE_S_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_S)
#define KEYCODE_T_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_T)
#define KEYCODE_U_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_U)
#define KEYCODE_V_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_V)
#define KEYCODE_W_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_W)
#define KEYCODE_X_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_X)
#define KEYCODE_Y_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Y)
#define KEYCODE_Z_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Z)
#define KEYCODE_0_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_0)
#define KEYCODE_1_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_1)
#define KEYCODE_2_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_2)
#define KEYCODE_3_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_3)
#define KEYCODE_4_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_4)
#define KEYCODE_5_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_5)
#define KEYCODE_6_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_6)
#define KEYCODE_7_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_7)
#define KEYCODE_8_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_8)
#define KEYCODE_9_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_9)
#define KEYCODE_F1_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F1)
#define KEYCODE_F2_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F2)
#define KEYCODE_F3_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F3)
#define KEYCODE_F4_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F4)
#define KEYCODE_F5_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F5)
#define KEYCODE_F6_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F6)
#define KEYCODE_F7_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F7)
#define KEYCODE_F8_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F8)
#define KEYCODE_F9_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F9)
#define KEYCODE_F10_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F10)
#define KEYCODE_F11_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F11)
#define KEYCODE_F12_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F12)
#define KEYCODE_F13_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F13)
#define KEYCODE_F14_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F14)
#define KEYCODE_F15_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F15)
#define KEYCODE_F16_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F16)
#define KEYCODE_F17_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F17)
#define KEYCODE_F18_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F18)
#define KEYCODE_F19_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F19)
#define KEYCODE_F20_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F20)
#define KEYCODE_ESC_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ESC)
#define KEYCODE_TILDE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TILDE)
#define KEYCODE_MINUS_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MINUS)
#define KEYCODE_EQUALS_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_EQUALS)
#define KEYCODE_BACKSPACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSPACE)
#define KEYCODE_TAB_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TAB)
#define KEYCODE_OPENBRACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_OPENBRACE)
#define KEYCODE_CLOSEBRACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CLOSEBRACE)
#define KEYCODE_ENTER_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ENTER)
#define KEYCODE_COLON_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COLON)
#define KEYCODE_QUOTE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_QUOTE)
#define KEYCODE_BACKSLASH_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSLASH)
#define KEYCODE_BACKSLASH2_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSLASH2)
#define KEYCODE_COMMA_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COMMA)
#define KEYCODE_STOP_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_STOP)
#define KEYCODE_SLASH_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SLASH)
#define KEYCODE_SPACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SPACE)
#define KEYCODE_INSERT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_INSERT)
#define KEYCODE_DEL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DEL)
#define KEYCODE_HOME_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_HOME)
#define KEYCODE_END_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_END)
#define KEYCODE_PGUP_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PGUP)
#define KEYCODE_PGDN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PGDN)
#define KEYCODE_LEFT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LEFT)
#define KEYCODE_RIGHT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RIGHT)
#define KEYCODE_UP_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_UP)
#define KEYCODE_DOWN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DOWN)
#define KEYCODE_0_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_0_PAD)
#define KEYCODE_1_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_1_PAD)
#define KEYCODE_2_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_2_PAD)
#define KEYCODE_3_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_3_PAD)
#define KEYCODE_4_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_4_PAD)
#define KEYCODE_5_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_5_PAD)
#define KEYCODE_6_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_6_PAD)
#define KEYCODE_7_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_7_PAD)
#define KEYCODE_8_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_8_PAD)
#define KEYCODE_9_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_9_PAD)
#define KEYCODE_SLASH_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SLASH_PAD)
#define KEYCODE_ASTERISK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ASTERISK)
#define KEYCODE_MINUS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MINUS_PAD)
#define KEYCODE_PLUS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PLUS_PAD)
#define KEYCODE_DEL_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DEL_PAD)
#define KEYCODE_ENTER_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ENTER_PAD)
#define KEYCODE_BS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BS_PAD)
#define KEYCODE_TAB_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TAB_PAD)
#define KEYCODE_00_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_00_PAD)
#define KEYCODE_000_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_000_PAD)
#define KEYCODE_COMMA_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COMMA_PAD)
#define KEYCODE_EQUALS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_EQUALS_PAD)
#define KEYCODE_PRTSCR_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PRTSCR)
#define KEYCODE_PAUSE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PAUSE)
#define KEYCODE_LSHIFT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LSHIFT)
#define KEYCODE_RSHIFT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RSHIFT)
#define KEYCODE_LCONTROL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LCONTROL)
#define KEYCODE_RCONTROL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RCONTROL)
#define KEYCODE_LALT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LALT)
#define KEYCODE_RALT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RALT)
#define KEYCODE_SCRLOCK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SCRLOCK)
#define KEYCODE_NUMLOCK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_NUMLOCK)
#define KEYCODE_CAPSLOCK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CAPSLOCK)
#define KEYCODE_LWIN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LWIN)
#define KEYCODE_RWIN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RWIN)
#define KEYCODE_MENU_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MENU)
#define KEYCODE_CANCEL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CANCEL)

#define KEYCODE_A KEYCODE_A_INDEXED(0)
#define KEYCODE_B KEYCODE_B_INDEXED(0)
#define KEYCODE_C KEYCODE_C_INDEXED(0)
#define KEYCODE_D KEYCODE_D_INDEXED(0)
#define KEYCODE_E KEYCODE_E_INDEXED(0)
#define KEYCODE_F KEYCODE_F_INDEXED(0)
#define KEYCODE_G KEYCODE_G_INDEXED(0)
#define KEYCODE_H KEYCODE_H_INDEXED(0)
#define KEYCODE_I KEYCODE_I_INDEXED(0)
#define KEYCODE_J KEYCODE_J_INDEXED(0)
#define KEYCODE_K KEYCODE_K_INDEXED(0)
#define KEYCODE_L KEYCODE_L_INDEXED(0)
#define KEYCODE_M KEYCODE_M_INDEXED(0)
#define KEYCODE_N KEYCODE_N_INDEXED(0)
#define KEYCODE_O KEYCODE_O_INDEXED(0)
#define KEYCODE_P KEYCODE_P_INDEXED(0)
#define KEYCODE_Q KEYCODE_Q_INDEXED(0)
#define KEYCODE_R KEYCODE_R_INDEXED(0)
#define KEYCODE_S KEYCODE_S_INDEXED(0)
#define KEYCODE_T KEYCODE_T_INDEXED(0)
#define KEYCODE_U KEYCODE_U_INDEXED(0)
#define KEYCODE_V KEYCODE_V_INDEXED(0)
#define KEYCODE_W KEYCODE_W_INDEXED(0)
#define KEYCODE_X KEYCODE_X_INDEXED(0)
#define KEYCODE_Y KEYCODE_Y_INDEXED(0)
#define KEYCODE_Z KEYCODE_Z_INDEXED(0)
#define KEYCODE_0 KEYCODE_0_INDEXED(0)
#define KEYCODE_1 KEYCODE_1_INDEXED(0)
#define KEYCODE_2 KEYCODE_2_INDEXED(0)
#define KEYCODE_3 KEYCODE_3_INDEXED(0)
#define KEYCODE_4 KEYCODE_4_INDEXED(0)
#define KEYCODE_5 KEYCODE_5_INDEXED(0)
#define KEYCODE_6 KEYCODE_6_INDEXED(0)
#define KEYCODE_7 KEYCODE_7_INDEXED(0)
#define KEYCODE_8 KEYCODE_8_INDEXED(0)
#define KEYCODE_9 KEYCODE_9_INDEXED(0)
#define KEYCODE_F1 KEYCODE_F1_INDEXED(0)
#define KEYCODE_F2 KEYCODE_F2_INDEXED(0)
#define KEYCODE_F3 KEYCODE_F3_INDEXED(0)
#define KEYCODE_F4 KEYCODE_F4_INDEXED(0)
#define KEYCODE_F5 KEYCODE_F5_INDEXED(0)
#define KEYCODE_F6 KEYCODE_F6_INDEXED(0)
#define KEYCODE_F7 KEYCODE_F7_INDEXED(0)
#define KEYCODE_F8 KEYCODE_F8_INDEXED(0)
#define KEYCODE_F9 KEYCODE_F9_INDEXED(0)
#define KEYCODE_F10 KEYCODE_F10_INDEXED(0)
#define KEYCODE_F11 KEYCODE_F11_INDEXED(0)
#define KEYCODE_F12 KEYCODE_F12_INDEXED(0)
#define KEYCODE_F13 KEYCODE_F13_INDEXED(0)
#define KEYCODE_F14 KEYCODE_F14_INDEXED(0)
#define KEYCODE_F15 KEYCODE_F15_INDEXED(0)
#define KEYCODE_F16 KEYCODE_F16_INDEXED(0)
#define KEYCODE_F17 KEYCODE_F17_INDEXED(0)
#define KEYCODE_F18 KEYCODE_F18_INDEXED(0)
#define KEYCODE_F19 KEYCODE_F19_INDEXED(0)
#define KEYCODE_F20 KEYCODE_F20_INDEXED(0)
#define KEYCODE_ESC KEYCODE_ESC_INDEXED(0)
#define KEYCODE_TILDE KEYCODE_TILDE_INDEXED(0)
#define KEYCODE_MINUS KEYCODE_MINUS_INDEXED(0)
#define KEYCODE_EQUALS KEYCODE_EQUALS_INDEXED(0)
#define KEYCODE_BACKSPACE KEYCODE_BACKSPACE_INDEXED(0)
#define KEYCODE_TAB KEYCODE_TAB_INDEXED(0)
#define KEYCODE_OPENBRACE KEYCODE_OPENBRACE_INDEXED(0)
#define KEYCODE_CLOSEBRACE KEYCODE_CLOSEBRACE_INDEXED(0)
#define KEYCODE_ENTER KEYCODE_ENTER_INDEXED(0)
#define KEYCODE_COLON KEYCODE_COLON_INDEXED(0)
#define KEYCODE_QUOTE KEYCODE_QUOTE_INDEXED(0)
#define KEYCODE_BACKSLASH KEYCODE_BACKSLASH_INDEXED(0)
#define KEYCODE_BACKSLASH2 KEYCODE_BACKSLASH2_INDEXED(0)
#define KEYCODE_COMMA KEYCODE_COMMA_INDEXED(0)
#define KEYCODE_STOP KEYCODE_STOP_INDEXED(0)
#define KEYCODE_SLASH KEYCODE_SLASH_INDEXED(0)
#define KEYCODE_SPACE KEYCODE_SPACE_INDEXED(0)
#define KEYCODE_INSERT KEYCODE_INSERT_INDEXED(0)
#define KEYCODE_DEL KEYCODE_DEL_INDEXED(0)
#define KEYCODE_HOME KEYCODE_HOME_INDEXED(0)
#define KEYCODE_END KEYCODE_END_INDEXED(0)
#define KEYCODE_PGUP KEYCODE_PGUP_INDEXED(0)
#define KEYCODE_PGDN KEYCODE_PGDN_INDEXED(0)
#define KEYCODE_LEFT KEYCODE_LEFT_INDEXED(0)
#define KEYCODE_RIGHT KEYCODE_RIGHT_INDEXED(0)
#define KEYCODE_UP KEYCODE_UP_INDEXED(0)
#define KEYCODE_DOWN KEYCODE_DOWN_INDEXED(0)
#define KEYCODE_0_PAD KEYCODE_0_PAD_INDEXED(0)
#define KEYCODE_1_PAD KEYCODE_1_PAD_INDEXED(0)
#define KEYCODE_2_PAD KEYCODE_2_PAD_INDEXED(0)
#define KEYCODE_3_PAD KEYCODE_3_PAD_INDEXED(0)
#define KEYCODE_4_PAD KEYCODE_4_PAD_INDEXED(0)
#define KEYCODE_5_PAD KEYCODE_5_PAD_INDEXED(0)
#define KEYCODE_6_PAD KEYCODE_6_PAD_INDEXED(0)
#define KEYCODE_7_PAD KEYCODE_7_PAD_INDEXED(0)
#define KEYCODE_8_PAD KEYCODE_8_PAD_INDEXED(0)
#define KEYCODE_9_PAD KEYCODE_9_PAD_INDEXED(0)
#define KEYCODE_SLASH_PAD KEYCODE_SLASH_PAD_INDEXED(0)
#define KEYCODE_ASTERISK KEYCODE_ASTERISK_INDEXED(0)
#define KEYCODE_MINUS_PAD KEYCODE_MINUS_PAD_INDEXED(0)
#define KEYCODE_PLUS_PAD KEYCODE_PLUS_PAD_INDEXED(0)
#define KEYCODE_DEL_PAD KEYCODE_DEL_PAD_INDEXED(0)
#define KEYCODE_ENTER_PAD KEYCODE_ENTER_PAD_INDEXED(0)
#define KEYCODE_BS_PAD KEYCODE_BS_PAD_INDEXED(0)
#define KEYCODE_TAB_PAD KEYCODE_TAB_PAD_INDEXED(0)
#define KEYCODE_00_PAD KEYCODE_00_PAD_INDEXED(0)
#define KEYCODE_000_PAD KEYCODE_000_PAD_INDEXED(0)
#define KEYCODE_COMMA_PAD KEYCODE_COMMA_PAD_INDEXED(0)
#define KEYCODE_EQUALS_PAD KEYCODE_EQUALS_PAD_INDEXED(0)
#define KEYCODE_PRTSCR KEYCODE_PRTSCR_INDEXED(0)
#define KEYCODE_PAUSE KEYCODE_PAUSE_INDEXED(0)
#define KEYCODE_LSHIFT KEYCODE_LSHIFT_INDEXED(0)
#define KEYCODE_RSHIFT KEYCODE_RSHIFT_INDEXED(0)
#define KEYCODE_LCONTROL KEYCODE_LCONTROL_INDEXED(0)
#define KEYCODE_RCONTROL KEYCODE_RCONTROL_INDEXED(0)
#define KEYCODE_LALT KEYCODE_LALT_INDEXED(0)
#define KEYCODE_RALT KEYCODE_RALT_INDEXED(0)
#define KEYCODE_SCRLOCK KEYCODE_SCRLOCK_INDEXED(0)
#define KEYCODE_NUMLOCK KEYCODE_NUMLOCK_INDEXED(0)
#define KEYCODE_CAPSLOCK KEYCODE_CAPSLOCK_INDEXED(0)
#define KEYCODE_LWIN KEYCODE_LWIN_INDEXED(0)
#define KEYCODE_RWIN KEYCODE_RWIN_INDEXED(0)
#define KEYCODE_MENU KEYCODE_MENU_INDEXED(0)
#define KEYCODE_CANCEL KEYCODE_CANCEL_INDEXED(0)

// mouse axes as relative devices
#define MOUSECODE_X_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS)
#define MOUSECODE_Y_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS)
#define MOUSECODE_Z_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_ZAXIS)

#define MOUSECODE_X MOUSECODE_X_INDEXED(0)
#define MOUSECODE_Y MOUSECODE_Y_INDEXED(0)
#define MOUSECODE_Z MOUSECODE_Z_INDEXED(0)

// mouse axes as switches in +/- direction
#define MOUSECODE_X_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_XAXIS)
#define MOUSECODE_X_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_XAXIS)
#define MOUSECODE_Y_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_YAXIS)
#define MOUSECODE_Y_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_YAXIS)
#define MOUSECODE_Z_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS)
#define MOUSECODE_Z_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS)

#define MOUSECODE_X_POS_SWITCH MOUSECODE_X_POS_SWITCH_INDEXED(0)
#define MOUSECODE_X_NEG_SWITCH MOUSECODE_X_NEG_SWITCH_INDEXED(0)
#define MOUSECODE_Y_POS_SWITCH MOUSECODE_Y_POS_SWITCH_INDEXED(0)
#define MOUSECODE_Y_NEG_SWITCH MOUSECODE_Y_NEG_SWITCH_INDEXED(0)
#define MOUSECODE_Z_POS_SWITCH MOUSECODE_Z_POS_SWITCH_INDEXED(0)
#define MOUSECODE_Z_NEG_SWITCH MOUSECODE_Z_NEG_SWITCH_INDEXED(0)

// mouse buttons
#define MOUSECODE_BUTTON1_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1)
#define MOUSECODE_BUTTON2_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2)
#define MOUSECODE_BUTTON3_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3)
#define MOUSECODE_BUTTON4_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4)
#define MOUSECODE_BUTTON5_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5)
#define MOUSECODE_BUTTON6_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6)
#define MOUSECODE_BUTTON7_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7)
#define MOUSECODE_BUTTON8_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8)

#define MOUSECODE_BUTTON1 MOUSECODE_BUTTON1_INDEXED(0)
#define MOUSECODE_BUTTON2 MOUSECODE_BUTTON2_INDEXED(0)
#define MOUSECODE_BUTTON3 MOUSECODE_BUTTON3_INDEXED(0)
#define MOUSECODE_BUTTON4 MOUSECODE_BUTTON4_INDEXED(0)
#define MOUSECODE_BUTTON5 MOUSECODE_BUTTON5_INDEXED(0)
#define MOUSECODE_BUTTON6 MOUSECODE_BUTTON6_INDEXED(0)
#define MOUSECODE_BUTTON7 MOUSECODE_BUTTON7_INDEXED(0)
#define MOUSECODE_BUTTON8 MOUSECODE_BUTTON8_INDEXED(0)

// gun axes as absolute devices
#define GUNCODE_X_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS)
#define GUNCODE_Y_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS)

#define GUNCODE_X GUNCODE_X_INDEXED(0)
#define GUNCODE_Y GUNCODE_Y_INDEXED(0)

// gun buttons
#define GUNCODE_BUTTON1_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1)
#define GUNCODE_BUTTON2_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2)
#define GUNCODE_BUTTON3_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3)
#define GUNCODE_BUTTON4_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4)
#define GUNCODE_BUTTON5_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5)
#define GUNCODE_BUTTON6_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6)
#define GUNCODE_BUTTON7_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7)
#define GUNCODE_BUTTON8_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8)

#define GUNCODE_BUTTON1 GUNCODE_BUTTON1_INDEXED(0)
#define GUNCODE_BUTTON2 GUNCODE_BUTTON2_INDEXED(0)
#define GUNCODE_BUTTON3 GUNCODE_BUTTON3_INDEXED(0)
#define GUNCODE_BUTTON4 GUNCODE_BUTTON4_INDEXED(0)
#define GUNCODE_BUTTON5 GUNCODE_BUTTON5_INDEXED(0)
#define GUNCODE_BUTTON6 GUNCODE_BUTTON6_INDEXED(0)
#define GUNCODE_BUTTON7 GUNCODE_BUTTON7_INDEXED(0)
#define GUNCODE_BUTTON8 GUNCODE_BUTTON8_INDEXED(0)

// joystick axes as absolute devices
#define JOYCODE_X_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS)
#define JOYCODE_Y_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS)
#define JOYCODE_Z_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_ZAXIS)
#define JOYCODE_U_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RXAXIS)
#define JOYCODE_V_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RYAXIS)
#define JOYCODE_W_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RZAXIS)

#define JOYCODE_X JOYCODE_X_INDEXED(0)
#define JOYCODE_Y JOYCODE_Y_INDEXED(0)
#define JOYCODE_Z JOYCODE_Z_INDEXED(0)
#define JOYCODE_U JOYCODE_U_INDEXED(0)
#define JOYCODE_V JOYCODE_V_INDEXED(0)
#define JOYCODE_W JOYCODE_W_INDEXED(0)

// joystick axes as absolute half-axes
#define JOYCODE_X_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_XAXIS)
#define JOYCODE_X_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_XAXIS)
#define JOYCODE_Y_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_YAXIS)
#define JOYCODE_Y_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_YAXIS)
#define JOYCODE_Z_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS)
#define JOYCODE_Z_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS)
#define JOYCODE_U_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RXAXIS)
#define JOYCODE_U_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RXAXIS)
#define JOYCODE_V_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RYAXIS)
#define JOYCODE_V_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RYAXIS)
#define JOYCODE_W_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RZAXIS)
#define JOYCODE_W_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RZAXIS)

#define JOYCODE_X_POS_ABSOLUTE JOYCODE_X_POS_ABSOLUTE_INDEXED(0)
#define JOYCODE_X_NEG_ABSOLUTE JOYCODE_X_NEG_ABSOLUTE_INDEXED(0)
#define JOYCODE_Y_POS_ABSOLUTE JOYCODE_Y_POS_ABSOLUTE_INDEXED(0)
#define JOYCODE_Y_NEG_ABSOLUTE JOYCODE_Y_NEG_ABSOLUTE_INDEXED(0)
#define JOYCODE_Z_POS_ABSOLUTE JOYCODE_Z_POS_ABSOLUTE_INDEXED(0)
#define JOYCODE_Z_NEG_ABSOLUTE JOYCODE_Z_NEG_ABSOLUTE_INDEXED(0)
#define JOYCODE_U_POS_ABSOLUTE JOYCODE_U_POS_ABSOLUTE_INDEXED(0)
#define JOYCODE_U_NEG_ABSOLUTE JOYCODE_U_NEG_ABSOLUTE_INDEXED(0)
#define JOYCODE_V_POS_ABSOLUTE JOYCODE_V_POS_ABSOLUTE_INDEXED(0)
#define JOYCODE_V_NEG_ABSOLUTE JOYCODE_V_NEG_ABSOLUTE_INDEXED(0)
#define JOYCODE_W_POS_ABSOLUTE JOYCODE_W_POS_ABSOLUTE_INDEXED(0)
#define JOYCODE_W_NEG_ABSOLUTE JOYCODE_W_NEG_ABSOLUTE_INDEXED(0)

// joystick axes as switches; X/Y are specially handled for left/right/up/down mapping
#define JOYCODE_X_LEFT_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_LEFT, ITEM_ID_XAXIS)
#define JOYCODE_X_RIGHT_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_RIGHT, ITEM_ID_XAXIS)
#define JOYCODE_Y_UP_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_UP, ITEM_ID_YAXIS)
#define JOYCODE_Y_DOWN_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_DOWN, ITEM_ID_YAXIS)
#define JOYCODE_Z_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS)
#define JOYCODE_Z_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS)
#define JOYCODE_U_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RXAXIS)
#define JOYCODE_U_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RXAXIS)
#define JOYCODE_V_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RYAXIS)
#define JOYCODE_V_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RYAXIS)
#define JOYCODE_W_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RZAXIS)
#define JOYCODE_W_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RZAXIS)

#define JOYCODE_X_LEFT_SWITCH JOYCODE_X_LEFT_SWITCH_INDEXED(0)
#define JOYCODE_X_RIGHT_SWITCH JOYCODE_X_RIGHT_SWITCH_INDEXED(0)
#define JOYCODE_Y_UP_SWITCH JOYCODE_Y_UP_SWITCH_INDEXED(0)
#define JOYCODE_Y_DOWN_SWITCH JOYCODE_Y_DOWN_SWITCH_INDEXED(0)
#define JOYCODE_Z_POS_SWITCH JOYCODE_Z_POS_SWITCH_INDEXED(0)
#define JOYCODE_Z_NEG_SWITCH JOYCODE_Z_NEG_SWITCH_INDEXED(0)
#define JOYCODE_U_POS_SWITCH JOYCODE_U_POS_SWITCH_INDEXED(0)
#define JOYCODE_U_NEG_SWITCH JOYCODE_U_NEG_SWITCH_INDEXED(0)
#define JOYCODE_V_POS_SWITCH JOYCODE_V_POS_SWITCH_INDEXED(0)
#define JOYCODE_V_NEG_SWITCH JOYCODE_V_NEG_SWITCH_INDEXED(0)
#define JOYCODE_W_POS_SWITCH JOYCODE_W_POS_SWITCH_INDEXED(0)
#define JOYCODE_W_NEG_SWITCH JOYCODE_W_NEG_SWITCH_INDEXED(0)

// joystick buttons
#define JOYCODE_BUTTON1_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1)
#define JOYCODE_BUTTON2_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2)
#define JOYCODE_BUTTON3_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3)
#define JOYCODE_BUTTON4_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4)
#define JOYCODE_BUTTON5_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5)
#define JOYCODE_BUTTON6_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6)
#define JOYCODE_BUTTON7_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7)
#define JOYCODE_BUTTON8_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8)
#define JOYCODE_BUTTON9_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON9)
#define JOYCODE_BUTTON10_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON10)
#define JOYCODE_BUTTON11_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON11)
#define JOYCODE_BUTTON12_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON12)
#define JOYCODE_BUTTON13_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON13)
#define JOYCODE_BUTTON14_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON14)
#define JOYCODE_BUTTON15_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON15)
#define JOYCODE_BUTTON16_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON16)
#define JOYCODE_BUTTON17_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON17)
#define JOYCODE_BUTTON18_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON18)
#define JOYCODE_BUTTON19_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON19)
#define JOYCODE_BUTTON20_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON20)
#define JOYCODE_BUTTON21_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON21)
#define JOYCODE_BUTTON22_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON22)
#define JOYCODE_BUTTON23_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON23)
#define JOYCODE_BUTTON24_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON24)
#define JOYCODE_BUTTON25_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON25)
#define JOYCODE_BUTTON26_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON26)
#define JOYCODE_BUTTON27_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON27)
#define JOYCODE_BUTTON28_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON28)
#define JOYCODE_BUTTON29_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON29)
#define JOYCODE_BUTTON30_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON30)
#define JOYCODE_BUTTON31_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON31)
#define JOYCODE_BUTTON32_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON32)
#define JOYCODE_START_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_START)
#define JOYCODE_SELECT_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SELECT)

#define JOYCODE_BUTTON1 JOYCODE_BUTTON1_INDEXED(0)
#define JOYCODE_BUTTON2 JOYCODE_BUTTON2_INDEXED(0)
#define JOYCODE_BUTTON3 JOYCODE_BUTTON3_INDEXED(0)
#define JOYCODE_BUTTON4 JOYCODE_BUTTON4_INDEXED(0)
#define JOYCODE_BUTTON5 JOYCODE_BUTTON5_INDEXED(0)
#define JOYCODE_BUTTON6 JOYCODE_BUTTON6_INDEXED(0)
#define JOYCODE_BUTTON7 JOYCODE_BUTTON7_INDEXED(0)
#define JOYCODE_BUTTON8 JOYCODE_BUTTON8_INDEXED(0)
#define JOYCODE_BUTTON9 JOYCODE_BUTTON9_INDEXED(0)
#define JOYCODE_BUTTON10 JOYCODE_BUTTON10_INDEXED(0)
#define JOYCODE_BUTTON11 JOYCODE_BUTTON11_INDEXED(0)
#define JOYCODE_BUTTON12 JOYCODE_BUTTON12_INDEXED(0)
#define JOYCODE_BUTTON13 JOYCODE_BUTTON13_INDEXED(0)
#define JOYCODE_BUTTON14 JOYCODE_BUTTON14_INDEXED(0)
#define JOYCODE_BUTTON15 JOYCODE_BUTTON15_INDEXED(0)
#define JOYCODE_BUTTON16 JOYCODE_BUTTON16_INDEXED(0)
#define JOYCODE_BUTTON17 JOYCODE_BUTTON17_INDEXED(0)
#define JOYCODE_BUTTON18 JOYCODE_BUTTON18_INDEXED(0)
#define JOYCODE_BUTTON19 JOYCODE_BUTTON19_INDEXED(0)
#define JOYCODE_BUTTON20 JOYCODE_BUTTON20_INDEXED(0)
#define JOYCODE_BUTTON21 JOYCODE_BUTTON21_INDEXED(0)
#define JOYCODE_BUTTON22 JOYCODE_BUTTON22_INDEXED(0)
#define JOYCODE_BUTTON23 JOYCODE_BUTTON23_INDEXED(0)
#define JOYCODE_BUTTON24 JOYCODE_BUTTON24_INDEXED(0)
#define JOYCODE_BUTTON25 JOYCODE_BUTTON25_INDEXED(0)
#define JOYCODE_BUTTON26 JOYCODE_BUTTON26_INDEXED(0)
#define JOYCODE_BUTTON27 JOYCODE_BUTTON27_INDEXED(0)
#define JOYCODE_BUTTON28 JOYCODE_BUTTON28_INDEXED(0)
#define JOYCODE_BUTTON29 JOYCODE_BUTTON29_INDEXED(0)
#define JOYCODE_BUTTON30 JOYCODE_BUTTON30_INDEXED(0)
#define JOYCODE_BUTTON31 JOYCODE_BUTTON31_INDEXED(0)
#define JOYCODE_BUTTON32 JOYCODE_BUTTON32_INDEXED(0)
#define JOYCODE_START JOYCODE_START_INDEXED(0)
#define JOYCODE_SELECT JOYCODE_SELECT_INDEXED(0)



#endif  // MAME_EMU_INPUT_H