1 /*
2 BStone: A Source port of
3 Blake Stone: Aliens of Gold and Blake Stone: Planet Strike
4 
5 Copyright (c) 1992-2013 Apogee Entertainment, LLC
6 Copyright (c) 2013-2015 Boris I. Bendovsky (bibendovsky@hotmail.com)
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the
20 Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23 
24 
25 //
26 //      ID Engine
27 //      ID_IN.h - Header file for Input Manager
28 //      v1.0d1
29 //      By Jason Blochowiak
30 //
31 
32 
33 #ifndef BSTONE_ID_IN_INCLUDED
34 #define BSTONE_ID_IN_INCLUDED
35 
36 
37 #ifdef  __DEBUG__
38 #define __DEBUG_InputMgr__
39 #endif
40 
41 #include <cstdint>
42 #include <bitset>
43 #include <memory>
44 #include <vector>
45 
46 #define MaxPlayers 4
47 #define MaxKbds 2
48 #define MaxJoys 2
49 #define NumCodes 128
50 
51 enum class ScanCode {
52     sc_none = 0,
53 
54     sc_return = 0x1C,
55     sc_escape = 0x01,
56     sc_space = 0x39,
57     sc_minus = 0x0C,
58     sc_equals = 0x0D,
59     sc_backspace = 0x0E,
60     sc_tab = 0x0F,
61     sc_alt = 0x38,
62     sc_left_bracket = 0x1A,
63     sc_right_bracket = 0x1B,
64     sc_control = 0x1D,
65     sc_caps_lock = 0x3A,
66     sc_num_lock = 0x45,
67     sc_scroll_lock = 0x46,
68     sc_left_shift = 0x2A,
69     sc_right_shift = 0x36,
70     sc_up_arrow = 0x48,
71     sc_down_arrow = 0x50,
72     sc_left_arrow = 0x4B,
73     sc_right_arrow = 0x4D,
74     sc_insert = 0x52,
75     sc_delete = 0x53,
76     sc_home = 0x47,
77     sc_end = 0x4F,
78     sc_page_up = 0x49,
79     sc_page_down = 0x51,
80     sc_slash = 0x35,
81     sc_f1 = 0x3B,
82     sc_f2 = 0x3C,
83     sc_f3 = 0x3D,
84     sc_f4 = 0x3E,
85     sc_f5 = 0x3F,
86     sc_f6 = 0x40,
87     sc_f7 = 0x41,
88     sc_f8 = 0x42,
89     sc_f9 = 0x43,
90     sc_f10 = 0x44,
91     sc_f11 = 0x57,
92     sc_f12 = 0x59,
93     sc_print_screen = 0x37,
94     sc_pause = 0x54,
95     sc_back_quote = 0x29,
96     sc_semicolon = 0x27,
97     sc_quote = 0x28,
98     sc_backslash = 0x2B,
99     sc_comma = 0x33,
100     sc_period = 0x34,
101 
102     sc_1 = 0x02,
103     sc_2 = 0x03,
104     sc_3 = 0x04,
105     sc_4 = 0x05,
106     sc_5 = 0x06,
107     sc_6 = 0x07,
108     sc_7 = 0x08,
109     sc_8 = 0x09,
110     sc_9 = 0x0a,
111     sc_0 = 0x0b,
112 
113     sc_a = 0x1E,
114     sc_b = 0x30,
115     sc_c = 0x2E,
116     sc_d = 0x20,
117     sc_e = 0x12,
118     sc_f = 0x21,
119     sc_g = 0x22,
120     sc_h = 0x23,
121     sc_i = 0x17,
122     sc_j = 0x24,
123     sc_k = 0x25,
124     sc_l = 0x26,
125     sc_m = 0x32,
126     sc_n = 0x31,
127     sc_o = 0x18,
128     sc_p = 0x19,
129     sc_q = 0x10,
130     sc_r = 0x13,
131     sc_s = 0x1F,
132     sc_t = 0x14,
133     sc_u = 0x16,
134     sc_v = 0x2F,
135     sc_w = 0x11,
136     sc_x = 0x2D,
137     sc_y = 0x15,
138     sc_z = 0x2C,
139 
140     sc_kp_minus = 0x4A,
141     sc_kp_plus = 0x4E,
142 
143     sc_mouse_left = 0x64,
144     sc_mouse_middle = 0x65,
145     sc_mouse_right = 0x66,
146     sc_mouse_x1 = 0x67,
147     sc_mouse_x2 = 0x68
148 }; // ScanCode
149 
150 #define key_None 0
151 #define key_Return 0x0d
152 #define key_Enter key_Return
153 #define key_Escape 0x1b
154 #define key_Space 0x20
155 #define key_BackSpace 0x08
156 #define key_Tab 0x09
157 #define key_Delete 0x7f
158 #define key_UnderScore 0x0c
159 
160 //      Stuff for the mouse
161 #define MReset 0
162 #define MButtons 3
163 #define MDelta 11
164 
165 #define MouseInt 0x33
166 
167 #define  NGint 0x15
168 #define  NGjoy(com) _AH = 0x84; _DX = com; geninterrupt(NGint);
169 
170 #define MaxJoyValue 5000 // JAM
171 
172 enum Demo {
173     demo_Off,
174     demo_Record,
175     demo_Playback,
176     demo_PlayDone
177 }; // Demo
178 
179 enum ControlType {
180     ctrl_None, // JAM - added
181     ctrl_Keyboard,
182     ctrl_Keyboard1 = ctrl_Keyboard,
183     ctrl_Keyboard2,
184     ctrl_Joystick,
185     ctrl_Joystick1 = ctrl_Joystick,
186     ctrl_Joystick2,
187     ctrl_Mouse
188 }; // ControlType
189 
190 enum Motion {
191     motion_Left = -1,
192     motion_Up = -1,
193     motion_None = 0,
194     motion_Right = 1,
195     motion_Down = 1
196 }; // Motion
197 
198 enum Direction {
199     dir_North,
200     dir_NorthEast,
201     dir_East,
202     dir_SouthEast,
203     dir_South,
204     dir_SouthWest,
205     dir_West,
206     dir_NorthWest,
207     dir_None
208 }; // Direction
209 
210 // BBi
211 enum BindingId {
212     e_bi_forward,
213     e_bi_backward,
214     e_bi_left,
215     e_bi_right,
216     e_bi_strafe,
217     e_bi_strafe_left,
218     e_bi_strafe_right,
219     e_bi_quick_left,
220     e_bi_quick_right,
221     e_bi_turn_around,
222     e_bi_run,
223 
224     e_bi_attack,
225     e_bi_weapon_1,
226     e_bi_weapon_2,
227     e_bi_weapon_3,
228     e_bi_weapon_4,
229     e_bi_weapon_5,
230     e_bi_weapon_6,
231     e_bi_weapon_7,
232 
233     e_bi_use,
234 
235     e_bi_stats,
236     e_bi_radar_magnify,
237     e_bi_radar_minify,
238 
239     e_bi_help,
240     e_bi_save,
241     e_bi_load,
242     e_bi_sound,
243     e_bi_controls,
244     e_bi_end_game,
245     e_bi_quick_save,
246     e_bi_quick_load,
247     e_bi_quick_exit,
248 
249     e_bi_attack_info,
250     e_bi_lightning,
251     e_bi_sfx,
252     e_bi_music,
253     e_bi_ceiling,
254     e_bi_flooring,
255     e_bi_heart_beat,
256 
257     e_bi_pause,
258     e_bi_grab_mouse,
259 
260     e_bi_last_entry,
261 }; // BindingId
262 
263 const int k_max_binding_keys = 2;
264 const int k_max_bindings = e_bi_last_entry;
265 
266 using Binding = ScanCode[k_max_binding_keys];
267 using Bindings = Binding[k_max_bindings];
268 
269 const bool default_in_use_modern_bindings = true;
270 extern bool in_use_modern_bindings;
271 extern Bindings in_bindings;
272 
273 void in_set_default_bindings();
274 
275 struct CursorInfo {
276     int button0;
277     int button1;
278     int button2;
279     int button3;
280     int x;
281     int y;
282     Motion xaxis;
283     Motion yaxis;
284     Direction dir;
285 }; //  CursorInfo
286 
287 using ControlInfo = CursorInfo;
288 
289 struct KeyboardDef {
290     ScanCode button0;
291     ScanCode button1;
292     ScanCode upleft;
293     ScanCode up;
294     ScanCode upright;
295     ScanCode left;
296     ScanCode right;
297     ScanCode downleft;
298     ScanCode down;
299     ScanCode downright;
300 }; // KeyboardDef
301 
302 struct JoystickDef {
303     uint16_t joyMinX;
304     uint16_t joyMinY;
305     uint16_t threshMinX;
306     uint16_t threshMinY;
307     uint16_t threshMaxX;
308     uint16_t threshMaxY;
309     uint16_t joyMaxX;
310     uint16_t joyMaxY;
311     uint16_t joyMultXL;
312     uint16_t joyMultYL;
313     uint16_t joyMultXH;
314     uint16_t joyMultYH;
315 }; // JoystickDef
316 
317 
318 // Global variables
319 
320 class KeyboardState {
321 private:
322     using State = std::bitset<NumCodes>;
323 
324 
325 public:
KeyboardState()326     KeyboardState() :
327             state_()
328     {
329     }
330 
331     KeyboardState(
332         const KeyboardState& that) = delete;
333 
334     KeyboardState& operator=(
335         const KeyboardState& that) = delete;
336 
~KeyboardState()337     ~KeyboardState()
338     {
339     }
340 
341     State::reference operator[](
342         int index)
343     {
344         return state_[index];
345     }
346 
347     State::reference operator[](
348         ScanCode scan_code)
349     {
350         return state_[static_cast<size_t>(scan_code)];
351     }
352 
reset()353     void reset()
354     {
355         state_.reset();
356     }
357 
358 private:
359     State state_;
360 }; // KeyboardState
361 
362 extern bool NGinstalled; // JAM
363 
364 extern bool JoystickCalibrated; // JAM - added
365 extern ControlType ControlTypeUsed; // JAM - added
366 extern KeyboardState Keyboard;
367 extern bool MousePresent;
368 extern bool JoysPresent[];
369 extern bool Paused;
370 extern char LastASCII;
371 extern ScanCode LastScan;
372 extern KeyboardDef KbdDefs;
373 extern JoystickDef JoyDefs[];
374 extern ControlType Controls[MaxPlayers];
375 
376 extern uint8_t* DemoBuffer;
377 extern uint16_t DemoOffset, DemoSize;
378 
379 // Function prototypes
380 #define IN_KeyDown(code) (Keyboard[(code)])
381 #define IN_ClearKey(code) { Keyboard[code] = false; \
382                             if (code == LastScan) { LastScan = ScanCode::sc_none; } }
383 
384 // DEBUG - put names in prototypes
385 void IN_Startup();
386 void IN_Shutdown();
387 
388 void IN_Default(
389     bool gotit,
390     ControlType in);
391 
392 void IN_SetKeyHook(void (*)());
393 void IN_ClearKeysDown();
394 void IN_ReadCursor(CursorInfo*);
395 void IN_ReadControl(int16_t, ControlInfo*);
396 void IN_SetControlType(int16_t, ControlType);
397 void IN_GetJoyAbs(uint16_t joy, uint16_t * xp, uint16_t * yp);
398 
399 void IN_SetupJoy(
400     uint16_t joy,
401     uint16_t minx,
402     uint16_t maxx,
403     uint16_t miny,
404     uint16_t maxy);
405 
406 void IN_StopDemo();
407 void IN_FreeDemoBuffer();
408 void IN_Ack();
409 void IN_AckBack();
410 
411 extern bool IN_UserInput(
412     uint32_t delay);
413 extern char IN_WaitForASCII();
414 extern ScanCode IN_WaitForKey();
415 extern uint16_t IN_GetJoyButtonsDB(
416     uint16_t joy);
417 extern const std::string& IN_GetScanName(ScanCode);
418 
419 
420 uint8_t IN_MouseButtons();
421 uint8_t IN_JoyButtons();
422 
423 
424 // BBi
425 extern bool in_is_mouse_grabbed;
426 
427 bool in_grab_mouse(
428     bool grab);
429 
430 
431 void in_handle_events();
432 
433 void in_get_mouse_deltas(
434     int& dx,
435     int& dy);
436 
437 void in_clear_mouse_deltas();
438 
439 bool in_is_binding_pressed(
440     BindingId binding_id);
441 
442 void in_reset_binding_state(
443     BindingId binding_id);
444 
445 void in_reset_state();
446 // BBi
447 
448 
449 #endif // BSTONE_ID_IN_INCLUDED
450