1 |
|
2 #define INPUT_CC |
|
3 |
1 |
4 #include "Input.hh" |
2 #include "Input.hh" |
5 |
3 #include "Config.hh" |
6 template <typename BitEnumType> struct InputKeymapEntry { |
|
7 BitEnumType input; |
|
8 int keycode1, keycode2; |
|
9 }; |
|
10 |
4 |
11 InputKeymapEntry<PlayerInputBit> INPUT_PLAYER_KEYMAP[] = { |
5 InputKeymapEntry<PlayerInputBit> INPUT_PLAYER_KEYMAP[] = { |
12 { INPUT_AIM_UP, -CL_KEY_ENTER, CL_KEY_UP }, |
6 { INPUT_AIM_UP, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_UP } }, |
13 { INPUT_AIM_DOWN, -CL_KEY_ENTER, CL_KEY_DOWN }, |
7 { INPUT_AIM_DOWN, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_DOWN } }, |
14 { INPUT_MOVE_LEFT, -CL_KEY_ENTER, CL_KEY_LEFT }, |
8 { INPUT_MOVE_LEFT, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_LEFT } }, |
15 { INPUT_MOVE_RIGHT, -CL_KEY_ENTER, CL_KEY_RIGHT }, |
9 { INPUT_MOVE_RIGHT, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_RIGHT } }, |
16 { INPUT_JUMP, -CL_KEY_ENTER, CL_KEY_RSHIFT }, |
10 { INPUT_JUMP, INPUT_FLAG_NOREPEAT, { -CL_KEY_ENTER, CL_KEY_RSHIFT } }, |
17 { INPUT_DIG, CL_KEY_LEFT, CL_KEY_RIGHT }, |
11 { INPUT_DIG, INPUT_FLAG_NOREPEAT, { CL_KEY_LEFT, CL_KEY_RIGHT } }, |
18 { INPUT_SHOOT, CL_KEY_RCONTROL, 0 }, |
12 { INPUT_SHOOT, INPUT_FLAG_REPEAT, { CL_KEY_RCONTROL, 0 } }, |
19 { INPUT_CHANGE_PREV, CL_KEY_ENTER, CL_KEY_LEFT }, |
13 { INPUT_CHANGE_PREV, INPUT_FLAG_NOREPEAT, { CL_KEY_ENTER, CL_KEY_LEFT } }, |
20 { INPUT_CHANGE_NEXT, CL_KEY_ENTER, CL_KEY_RIGHT }, |
14 { INPUT_CHANGE_NEXT, INPUT_FLAG_NOREPEAT, { CL_KEY_ENTER, CL_KEY_RIGHT } }, |
21 { INPUT_ROPE, CL_KEY_ENTER, CL_KEY_RSHIFT }, |
15 { INPUT_ROPE, INPUT_FLAG_NOREPEAT, { CL_KEY_ENTER, CL_KEY_RSHIFT } }, |
22 { INPUT_UNROPE, -CL_KEY_ENTER, CL_KEY_RSHIFT }, |
16 { INPUT_UNROPE, INPUT_FLAG_NOREPEAT, { -CL_KEY_ENTER, CL_KEY_RSHIFT } }, |
23 { INPUT_ROPE_UP, CL_KEY_ENTER, CL_KEY_UP }, |
17 { INPUT_ROPE_UP, INPUT_FLAG_REPEAT, { CL_KEY_ENTER, CL_KEY_UP } }, |
24 { INPUT_ROPE_DOWN, CL_KEY_ENTER, CL_KEY_DOWN }, |
18 { INPUT_ROPE_DOWN, INPUT_FLAG_REPEAT, { CL_KEY_ENTER, CL_KEY_DOWN } }, |
25 { INPUT_SUICIDE, CL_KEY_LCONTROL, CL_KEY_K }, |
19 { INPUT_SUICIDE, INPUT_FLAG_NOREPEAT, { CL_KEY_LCONTROL, CL_KEY_K } }, |
26 { INPUT_NONE, 0, 0 } |
20 { INPUT_NONE, 0, { 0, 0 } } |
27 }; |
21 }; |
28 |
22 |
29 InputKeymapEntry<GuiInputBit> INPUT_GUI_KEYMAP[] = { |
23 InputKeymapEntry<GuiInputBit> INPUT_GUI_KEYMAP[] = { |
30 { GUI_INPUT_QUIT, CL_KEY_ESCAPE, 0 }, |
24 { GUI_INPUT_QUIT, 0, { CL_KEY_ESCAPE, 0 } }, |
31 { GUI_INPUT_DISPLAY_WEAPON, CL_KEY_ENTER, 0 }, |
25 { GUI_INPUT_DISPLAY_WEAPON, 0, { CL_KEY_ENTER, 0 } }, |
32 { GUI_INPUT_DEBUG_PLAYER, CL_KEY_I, 0 }, |
26 { GUI_INPUT_DEBUG_PLAYER, 0, { CL_KEY_I, 0 } }, |
|
27 { GUI_INPUT_NONE, 0, { 0, 0, } } |
33 }; |
28 }; |
34 |
29 |
35 Input::Input (CL_InputDevice &keyboard) : |
30 /* |
36 keyboard(keyboard) |
31 * InputKeyRepeatEntry |
|
32 */ |
|
33 template <typename BitEnumType> |
|
34 InputKeyRepeatEntry<BitEnumType>::InputKeyRepeatEntry (BitEnumType value, TimeMS expire) : |
|
35 value(value), expire(expire) |
37 { |
36 { |
38 |
37 |
39 } |
38 } |
|
39 |
|
40 template <typename BitEnumType> |
|
41 bool InputKeyRepeatEntry<BitEnumType>::operator< (const struct InputKeyRepeatEntry &other) { |
|
42 return other.expire > expire; |
|
43 } |
|
44 |
|
45 template <typename BitEnumType> |
|
46 bool InputKeyRepeatEntry<BitEnumType>::updateExpired (TimeMS dt) { |
|
47 expire -= dt; |
|
48 |
|
49 return (expire <= 0); |
|
50 } |
|
51 |
|
52 /* |
|
53 * InputKeyRepeatQueue |
|
54 */ |
|
55 template <typename BitEnumType> |
|
56 InputKeyRepeatQueue<BitEnumType>::InputKeyRepeatQueue (TimeMS expire) : |
|
57 expire(expire) |
|
58 { |
|
59 |
|
60 } |
|
61 |
|
62 template <typename BitEnumType> |
|
63 void InputKeyRepeatQueue<BitEnumType>::push (BitEnumType bit) { |
|
64 list.push_back(InputKeyRepeatEntry<BitEnumType>(bit, expire)); |
|
65 } |
|
66 |
|
67 template <typename BitEnumType> |
|
68 bool InputKeyRepeatQueue<BitEnumType>::find (BitEnumType bit) { |
|
69 for (list_iterator it = list.begin(); it != list.end(); it++) { |
|
70 if (it->value == bit) |
|
71 return true; |
|
72 } |
|
73 |
|
74 return false; |
|
75 } |
|
76 |
|
77 template <typename BitEnumType> |
|
78 void InputKeyRepeatQueue<BitEnumType>::update (TimeMS dt) { |
|
79 list_iterator it = list.begin(); |
40 |
80 |
41 bool Input::checkKeycode (int keycode) { |
81 // go through each entry, updateExpired and remove if expired |
|
82 while (it != list.end()) { |
|
83 if (it->updateExpired(dt)) |
|
84 it = list.erase(it); |
|
85 else |
|
86 it++; |
|
87 } |
|
88 } |
|
89 |
|
90 /* |
|
91 * InputHandler |
|
92 */ |
|
93 template <typename BitEnumType, typename BitMaskType> |
|
94 InputHandler<BitEnumType, BitMaskType>::InputHandler (CL_InputDevice &keyboard, InputKeymapEntry<BitEnumType> *keymap, TimeMS keyrepeat_expire) : |
|
95 keyboard(keyboard), |
|
96 keymap(keymap), |
|
97 value(0), |
|
98 dt(0), |
|
99 queue(keyrepeat_expire) |
|
100 { |
|
101 |
|
102 } |
|
103 |
|
104 template <typename BitEnumType, typename BitMaskType> |
|
105 bool InputHandler<BitEnumType, BitMaskType>::checkKeycode (int keycode) { |
42 if (keycode > 0) |
106 if (keycode > 0) |
43 return keyboard.get_keycode(keycode); |
107 return keyboard.get_keycode(keycode); |
44 |
108 |
45 else if (keycode < 0) |
109 else if (keycode < 0) |
46 return !keyboard.get_keycode(-keycode); |
110 return !keyboard.get_keycode(-keycode); |
47 |
111 |
48 else // == 0 |
112 else // == 0 |
49 return true; |
113 return true; |
50 } |
114 } |
|
115 |
|
116 template <typename BitEnumType, typename BitMaskType> |
|
117 void InputHandler<BitEnumType, BitMaskType>::readValue (BitMaskType &mask, TimeMS &dt) { |
|
118 // copy to args |
|
119 mask = this->value; |
|
120 dt = this->dt; |
51 |
121 |
52 template <typename BitEnumType, typename BitMaskType> BitMaskType Input::buildMask (InputKeymapEntry<BitEnumType> *keymap) { |
122 this->value = 0; |
53 BitMaskType input_mask = 0; |
123 this->dt = 0; |
54 |
|
55 for (InputKeymapEntry<BitEnumType> *e = keymap; (e->keycode1 || e->keycode2) && e->input; e++) { |
|
56 if (checkKeycode(e->keycode1) && checkKeycode(e->keycode2)) |
|
57 input_mask |= e->input; |
|
58 } |
|
59 |
|
60 return input_mask; |
|
61 } |
124 } |
62 |
125 |
63 PlayerInput Input::readPlayerInput (void) { |
126 template <typename BitEnumType, typename BitMaskType> |
64 return buildMask<PlayerInputBit, PlayerInput>(INPUT_PLAYER_KEYMAP); |
127 void InputHandler<BitEnumType, BitMaskType>::update (TimeMS dt) { |
|
128 // update the key-repeat queue |
|
129 queue.update(dt); |
|
130 |
|
131 // then go through the keymap |
|
132 for (InputKeymapEntry<BitEnumType> *e = keymap; e->input != 0; e++) { |
|
133 // check if we've got the correct keycodes |
|
134 if (checkKeycode(e->keycodes[0]) && checkKeycode(e->keycodes[1])) { |
|
135 // should we do keyrepeats? |
|
136 if (e->flags & INPUT_FLAG_NOREPEAT) { |
|
137 // if it's in the queue, ignore, else add it |
|
138 if (queue.find(e->input)) |
|
139 continue; |
|
140 else |
|
141 queue.push(e->input); |
|
142 } |
|
143 |
|
144 // set bit in mask |
|
145 this->value |= e->input; |
|
146 } |
|
147 } |
|
148 |
|
149 // then increment our dt |
|
150 this->dt += dt; |
|
151 } |
|
152 |
|
153 /** |
|
154 * Input |
|
155 */ |
|
156 Input::Input (CL_InputDevice &keyboard) : |
|
157 keyboard(keyboard), |
|
158 update_timer(INPUT_POLL_INTERVAL), |
|
159 player(keyboard, INPUT_PLAYER_KEYMAP, INPUT_REPEAT_DELAY), |
|
160 gui(keyboard, INPUT_GUI_KEYMAP, INPUT_REPEAT_DELAY) |
|
161 { |
|
162 // connect timer |
|
163 slots.connect(update_timer.sig_tick(), &player, &InputHandler<PlayerInputBit, PlayerInput>::update); |
|
164 slots.connect(update_timer.sig_tick(), &gui, &InputHandler<GuiInputBit, GuiInput>::update); |
|
165 |
|
166 // enable timer |
|
167 update_timer.start(); |
|
168 } |
|
169 |
|
170 void Input::readPlayerInput (PlayerInput &mask, TimeMS &dt) { |
|
171 player.readValue(mask, dt); |
65 } |
172 } |
66 |
173 |
67 GuiInput Input::readGuiInput (void) { |
174 GuiInput Input::readGuiInput (void) { |
68 return buildMask<GuiInputBit, GuiInput>(INPUT_GUI_KEYMAP); |
175 GuiInput mask; |
|
176 TimeMS dt; |
|
177 |
|
178 gui.readValue(mask, dt); |
|
179 |
|
180 return mask; |
69 } |
181 } |
70 |
182 |