1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
5 static inline float vg_get_axis( const char *axis
);
6 static inline int vg_get_button( const char *button
);
7 static inline int vg_get_button_down( const char *button
);
8 static inline int vg_get_button_up( const char *button
);
12 k_button_state_down
= 1,
13 k_button_state_up
= 3,
14 k_button_state_pressed
= 2,
15 k_button_state_none
= 0
18 GLFWgamepadstate vg_gamepad
;
19 int vg_gamepad_ready
= 0;
20 const char *vg_gamepad_name
= NULL
;
23 /* TODO: Fix this... */
31 static struct axis_binding
46 static struct button_binding
54 vg_controller_binds
[];
56 #include "vg_config.h"
58 #pragma GCC diagnostic push
59 #pragma GCC diagnostic ignored "-Wreturn-type"
61 static inline float vg_get_axis( const char *axis
)
63 for( int i
= 0; i
< vg_list_size( vg_axis_binds
); i
++ )
64 if( !strcmp( axis
, vg_axis_binds
[i
].name
) )
65 return vg_axis_binds
[i
].value
;
68 static inline struct button_binding
*vg_get_button_ptr( const char *button
)
70 for( int i
=0; i
<vg_list_size(vg_button_binds
); i
++ )
71 if( !strcmp(button
,vg_button_binds
[i
].name
) )
72 return vg_button_binds
+ i
;
76 static inline struct button_binding
*vg_get_button_ptr_c( const char *button
)
78 for( int i
=0; i
<vg_list_size(vg_controller_binds
); i
++ )
79 if( !strcmp(button
,vg_controller_binds
[i
].name
) )
80 return vg_controller_binds
+ i
;
84 #pragma GCC diagnostic pop
86 static int vg_console_enabled(void);
88 static inline void vg_get_button_states( const char *name
, int *cur
, int *prev
)
90 struct button_binding
*bind
= vg_get_button_ptr( name
),
91 *bindc
= vg_get_button_ptr_c( name
);
103 *cur
|= bindc
->value
;
104 *prev
|= bindc
->prev
;
108 static inline int vg_get_button( const char *button
)
111 vg_get_button_states( button
, &cur
, &prev
);
113 return cur
&& !vg_console_enabled();
116 static inline int vg_get_button_down( const char *button
)
119 vg_get_button_states( button
, &cur
, &prev
);
121 return cur
& (cur
^ prev
) && !vg_console_enabled();
124 static inline int vg_get_button_up( const char *button
)
127 vg_get_button_states( button
, &cur
, &prev
);
129 return prev
& (cur
^ prev
) && !vg_console_enabled();
132 static inline enum vg_button_state
vg_get_button_state( const char *button
)
134 if(vg_get_button_down( button
)) return k_button_state_down
;
135 if(vg_get_button_up( button
)) return k_button_state_up
;
136 if(vg_get_button( button
)) return k_button_state_pressed
;
137 return k_button_state_none
;
140 static inline int key_is_keyboard( int const id
)
142 vg_static_assert( GLFW_MOUSE_BUTTON_LAST
< GLFW_KEY_SPACE
,
143 "GLFW: Mouse has too many buttons" );
144 return id
> GLFW_MOUSE_BUTTON_LAST
;
147 int get_button_cross_device( int const id
)
149 if( key_is_keyboard( id
) )
150 return glfwGetKey( vg_window
, id
);
152 return glfwGetMouseButton( vg_window
, id
) == GLFW_PRESS
;
155 void vg_update_inputs(void)
157 if( !glfwGetGamepadState( GLFW_JOYSTICK_1
, &vg_gamepad
) )
159 vg_gamepad_ready
= 0;
162 /* Update button inputs */
163 for( int i
= 0; i
< vg_list_size( vg_button_binds
); i
++ )
165 struct button_binding
*binding
= vg_button_binds
+ i
;
166 binding
->prev
= binding
->value
;
167 binding
->value
= get_button_cross_device( binding
->bind
);
170 for( int i
=0; i
<vg_list_size( vg_controller_binds
); i
++ )
172 struct button_binding
*binding
= vg_controller_binds
+ i
;
173 binding
->prev
= binding
->value
;
174 binding
->value
= vg_gamepad
.buttons
[ binding
->bind
];
177 /* Update axis inputs */
178 for( int i
= 0; i
< vg_list_size( vg_axis_binds
); i
++ )
180 struct axis_binding
*binding
= vg_axis_binds
+ i
;
181 binding
->value
= vg_gamepad
.axes
[ binding
->bind
];
185 static void vg_gamepad_init(void)
187 for( int id
= 0; id
<= GLFW_JOYSTICK_LAST
; id
++ )
189 if( glfwJoystickPresent( id
) )
191 vg_info( "Joystick found: '%s'\n", glfwGetJoystickName(id
) );
194 if( glfwJoystickIsGamepad( id
) )
196 vg_gamepad_name
= glfwGetGamepadName( id
);
197 vg_success( "Gamepad with mapping registered: %s\n", vg_gamepad_name
);
199 vg_gamepad_ready
= 1;