62dd4b15b39f381737d9a4f03f42da746541fd0f
[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 key_is_keyboard( int const id )
93 {
94 vg_static_assert( GLFW_MOUSE_BUTTON_LAST < GLFW_KEY_SPACE, "GLFW: Mouse has too many buttons" );
95 return id > GLFW_MOUSE_BUTTON_LAST;
96 }
97
98 // Mouse AND Keyboard get button press
99 int get_button_cross_device( int const id )
100 {
101 if( key_is_keyboard( id ) )
102 {
103 return glfwGetKey( vg_window, id );
104 }
105 else
106 {
107 return glfwGetMouseButton( vg_window, id ) == GLFW_PRESS;
108 }
109 }
110
111 void vg_update_inputs(void)
112 {
113 // Update button inputs
114 for( int i = 0; i < vg_list_size( vg_button_binds ); i ++ )
115 {
116 struct button_binding *binding = vg_button_binds + i;
117 binding->prev = binding->value;
118
119 if( vg_input_mode == k_EInputMode_pc )
120 {
121 binding->value = get_button_cross_device( binding->bind );
122 }
123 else
124 {
125 binding->value = vg_gamepad.buttons[ binding->bind ];
126 }
127 }
128
129 // Update axis inputs
130 for( int i = 0; i < vg_list_size( vg_axis_binds ); i ++ )
131 {
132 struct axis_binding *binding = vg_axis_binds + i;
133
134 if( vg_input_mode == k_EInputMode_pc )
135 {
136 binding->value = get_button_cross_device( binding->positive );
137 binding->value -= get_button_cross_device( binding->negative );
138 }
139 else
140 {
141 binding->value = vg_gamepad.axes[ binding->bind ];
142 }
143 }
144 }