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