6bae274d99cff79a25e39c220a6742463578eb60
[fishladder.git] / vg / vg_input.h
1 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
2
3 static inline float vg_get_axis( const char *axis ) __attribute__((unused));
4 static inline int vg_get_button( const char *button ) __attribute__((unused));
5 static inline int vg_get_button_down( const char *button ) __attribute__((unused));
6 static inline int vg_get_button_up( const char *button ) __attribute__((unused));
7
8 // Input
9 // ===========================================================================================================
10 GLFWgamepadstate vg_gamepad;
11 int vg_gamepad_ready = 0;
12 const char *vg_gamepad_name = NULL;
13 int vg_gamepad_id;
14
15 enum EInputMode
16 {
17 k_EInputMode_pc,
18 k_EInputMode_gamepad
19 }
20 vg_input_mode;
21
22 static struct axis_binding
23 {
24 const char *name;
25 union
26 {
27 int positive;
28 int bind;
29 };
30 int negative;
31
32 float value;
33 }
34 vg_axis_binds[];
35
36 static struct button_binding
37 {
38 const char *name;
39 int bind;
40
41 int value; int prev;
42 }
43 vg_button_binds[];
44
45 #include "vg/config.h"
46
47 #pragma GCC diagnostic push
48 #pragma GCC diagnostic ignored "-Wreturn-type"
49
50 static inline float vg_get_axis( const char *axis )
51 {
52 for( int i = 0; i < vg_list_size( vg_axis_binds ); i ++ )
53 {
54 if( !strcmp( axis, vg_axis_binds[i].name ) )
55 {
56 return vg_axis_binds[i].value;
57 }
58 }
59 }
60
61 static inline struct button_binding *vg_get_button_ptr( const char *button )
62 {
63 for( int i = 0; i < vg_list_size( vg_button_binds ); i ++ )
64 {
65 if( !strcmp( button, vg_button_binds[i].name ) )
66 {
67 return vg_button_binds + i;
68 }
69 }
70 }
71 #pragma GCC diagnostic pop
72
73 static int vg_console_enabled(void);
74
75 static inline int vg_get_button( const char *button )
76 {
77 return vg_get_button_ptr( button )->value && !vg_console_enabled();
78 }
79
80 static inline int vg_get_button_down( const char *button )
81 {
82 struct button_binding *bind = vg_get_button_ptr( button );
83 return bind->value & (bind->value ^ bind->prev) && !vg_console_enabled();
84 }
85
86 static inline int vg_get_button_up( const char *button )
87 {
88 struct button_binding *bind = vg_get_button_ptr( button );
89 return bind->prev & (bind->value ^ bind->prev) && !vg_console_enabled();
90 }
91
92 static inline int vg_get_button_state( const char *button )
93 {
94 if( vg_get_button_down( button ) ) return 1;
95 if( vg_get_button_up( button ) ) return 3;
96 if( vg_get_button( button ) ) return 2;
97 return 0;
98 }
99
100 static inline int key_is_keyboard( int const id )
101 {
102 vg_static_assert( GLFW_MOUSE_BUTTON_LAST < GLFW_KEY_SPACE, "GLFW: Mouse has too many buttons" );
103 return id > GLFW_MOUSE_BUTTON_LAST;
104 }
105
106 // Mouse AND Keyboard get button press
107 int get_button_cross_device( int const id )
108 {
109 if( key_is_keyboard( id ) )
110 {
111 return glfwGetKey( vg_window, id );
112 }
113 else
114 {
115 return glfwGetMouseButton( vg_window, id ) == GLFW_PRESS;
116 }
117 }
118
119 void vg_update_inputs(void)
120 {
121 // Update button inputs
122 for( int i = 0; i < vg_list_size( vg_button_binds ); i ++ )
123 {
124 struct button_binding *binding = vg_button_binds + i;
125 binding->prev = binding->value;
126
127 if( vg_input_mode == k_EInputMode_pc )
128 {
129 binding->value = get_button_cross_device( binding->bind );
130 }
131 else
132 {
133 binding->value = vg_gamepad.buttons[ binding->bind ];
134 }
135 }
136
137 // Update axis inputs
138 for( int i = 0; i < vg_list_size( vg_axis_binds ); i ++ )
139 {
140 struct axis_binding *binding = vg_axis_binds + i;
141
142 if( vg_input_mode == k_EInputMode_pc )
143 {
144 binding->value = get_button_cross_device( binding->positive );
145 binding->value -= get_button_cross_device( binding->negative );
146 }
147 else
148 {
149 binding->value = vg_gamepad.axes[ binding->bind ];
150 }
151 }
152 }