bad char
[vg.git] / vg_input.h
index 9c5be8447ecc242f4baff8171601fbfc18f39a18..1636e07458db2da4b5d1cbe512eb7886112c4cfb 100644 (file)
@@ -1,34 +1,31 @@
-/* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
-#ifndef VG_INPUT_H
-#define VG_INPUT_H
-
-#include "common.h"
-#include "vg/vg_loader.h"
+#pragma once
 
+/* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */
 #define VG_MAX_CONTROLLERS 4
 
-static float controller_deadzone = 0.05f;
+#include "vg_platform.h"
+
+extern f32 controller_deadzone;
+
 typedef u32 vg_input_op;
 typedef vg_input_op *vg_input_program;
 
-enum vg_input_type {
+enum vg_input_type 
+{
    k_vg_input_type_button_u8,
    k_vg_input_type_axis_f32,
    k_vg_input_type_joy_v2f
 };
 
-enum vg_input_op {
+enum vg_input_op 
+{
    /* data source */
    vg_keyboard,
    vg_mouse,
    vg_joy_button,
    vg_joy_axis,
-
-   /* hacky constants */
-   vg_0_0f,
-   vg_0_5f,
-   vg_1_0f,
-   vg_2_0f,
+   vg_joy_ls,
+   vg_joy_rs,
 
    /* modes */
    vg_mode_mul,
@@ -40,14 +37,17 @@ enum vg_input_op {
    /* control */
    vg_index,
    vg_end,
+   vg_gui_visible,
 
    /* math */
    vg_normalize
 };
 
-struct{
+struct vg_input
+{
    const u8 *sdl_keys;
    u32 sdl_mouse;
+   f32 hidden_mouse_travel;
 
    struct vg_controller{
       SDL_GameController *handle; /* handle for controller. NULL if unused */
@@ -70,375 +70,24 @@ struct{
    display_input_method;
    SDL_GameControllerType display_input_type;
 }
-static vg_input = { .active_controller_index = -2 };
-
-static u8 vg_getkey( SDL_Keycode kc )
-{
-   SDL_Scancode sc = SDL_GetScancodeFromKey( kc );
-   return vg_input.sdl_keys[sc];
-}
-
-/*
- * takes SDL device index, and tries to open that on any free channel
- */
-static int vg_open_gamecontroller( Sint32 index )
-{
-   struct vg_controller *controller = NULL;
-   int vg_id = 0;
-   const char *name = SDL_GameControllerNameForIndex( index );
-   SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index );
-
-   if( instance_id == -1 ){
-      vg_error( ". Invalid device index (vg_open_gamecontroller)\n" );
-      return -1;
-   }
-
-   for( int j=0; j<VG_MAX_CONTROLLERS; j++ ){
-      struct vg_controller *esta = &vg_input.controllers[j];
-
-      if( esta->handle ){
-         if( esta->instance_id == instance_id ){
-            vg_warn( " . SDL_JoystickID[%d] is already in open at index #%d\n", 
-                     esta->instance_id, j );
-            return -1;
-         }
-      }
-      else{
-         if( !controller ){
-            controller = &vg_input.controllers[j];
-            vg_id = j;
-         }
-      }
-   }
-
-   if( controller ){
-      controller->handle = SDL_GameControllerOpen( index );
-      controller->instance_id = instance_id;
-
-      if( controller->handle ){
-         vg_success( 
-               " . opened SDL_JoystickID[%d] as controller '%s' at index #%d\n",
-               instance_id, name, vg_id );
-         
-         for( u32 i=0; i< SDL_CONTROLLER_BUTTON_MAX; i++ )
-            controller->buttons[i] = 0;
-         
-         for( u32 i=0; i< SDL_CONTROLLER_AXIS_MAX; i++ )
-            controller->axises[i] = 0.0f;
-
-         if( vg_input.active_controller_index == -2 ){
-            vg_input.active_controller_index = vg_id;
-            vg_input.display_input_method = k_input_method_controller;
-            vg_input.display_input_type = 
-               SDL_GameControllerGetType( controller->handle );
-         }
-
-         return vg_id;
-      }
-      else{
-         vg_error( ". Failed to attach game controller '%s'. Reason: %s\n",
-                     name, SDL_GetError() );
-         return -1;
-      }
-   }
-   else{
-      vg_error( ". Too many controllers open! ignoring '%s'\n", name );
-      return -1;
-   }
-}
-
-static void vg_input_device_event( SDL_Event *ev )
-{
-   if( ev->type == SDL_CONTROLLERDEVICEADDED ){
-      int is_controller = SDL_IsGameController( ev->cdevice.which );
-      const char *name = SDL_JoystickNameForIndex( ev->cdevice.which );
-
-      Sint32 index = ev->cdevice.which;
-      SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index );
-      vg_info( "SDL_CONTROLLERDEVICEADDED | device index: %d, name: '%s'\n", 
-                  index, name );
-
-      if( is_controller ){
-         vg_open_gamecontroller( index );
-      }
-   }
-   else if( ev->type == SDL_CONTROLLERDEVICEREMOVED ){
-      vg_info( "SDL_CONTROLLERDEVICEREMOVED | instance_id: %d\n", 
-                  ev->cdevice.which );
-
-      for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
-         struct vg_controller *controller = &vg_input.controllers[i];
-
-         if( controller->handle ){
-            if( controller->instance_id == ev->cdevice.which ){
-               vg_info( " . closing controller at index #%d\n", i );
-               SDL_GameControllerClose( controller->handle );
-               controller->handle = NULL;
-               controller->instance_id = -1;
-
-               if( vg_input.active_controller_index == i ){
-                  vg_input.active_controller_index = -1;
-                  vg_input.display_input_method = k_input_method_kbm;
-                  vg_info( "display_input: k_input_method_kbm\n" );
-               }
-               break;
-            }
-         }
-      }
-   }
-}
-
-static void vg_input_controller_event( SDL_Event *ev )
-{
-   if( ev->type == SDL_CONTROLLERAXISMOTION ){
-      for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
-         struct vg_controller *esta = &vg_input.controllers[i];
-
-         if( ev->caxis.which == esta->instance_id ){
-            float value = (float)ev->caxis.value / 32767.0f;
-
-            if( ev->caxis.axis == SDL_CONTROLLER_AXIS_LEFTX ||
-                ev->caxis.axis == SDL_CONTROLLER_AXIS_LEFTY ||
-                ev->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX ||
-                ev->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY )
-            {
-               float deadz   = vg_clampf( controller_deadzone, 0.0f, 0.999f ),
-                     high    = vg_maxf( 0.0f, fabsf(value) - deadz );
-               
-               value = vg_signf(value) * (high / (1.0f-deadz));
-            }
-            else if( ev->caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ||
-                     ev->caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT ){
-               value = 0.5f + value*0.5f;
-            }
-
-            esta->axises[ ev->caxis.axis ] = value;
-            break;
-         }
-      }
-   }
-   else if( ev->type == SDL_CONTROLLERBUTTONDOWN ){
-      struct vg_controller *active = NULL;
-
-      if( vg_input.active_controller_index >= 0 )
-         active = &vg_input.controllers[vg_input.active_controller_index];
-
-      if( !active || (ev->cbutton.which != active->instance_id) ){
-         active = NULL;
-         vg_input.active_controller_index = -1;
-         vg_input.display_input_method = k_input_method_kbm;
-
-         for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
-            if( vg_input.controllers[i].instance_id == ev->cbutton.which ){
-               active = &vg_input.controllers[i];
-               vg_input.active_controller_index = i;
-               vg_input.display_input_type = 
-                  SDL_GameControllerGetType(active->handle);
-               break;
-            }
-         }
-         
-         if( active ){
-            vg_info( "Switching active controller index to #%d\n", 
-                       vg_input.active_controller_index );
-         }
-         else{
-            vg_error( "Input out of range (SDL_JoystickID#%d)\n", 
-                       ev->cbutton.which );
-         }
-      }
-
-      if( active ){
-         if( vg_input.display_input_method != k_input_method_controller ){
-            vg_input.display_input_method = k_input_method_controller;
-            vg_info( "display_input: k_input_method_controller\n" );
-         }
-         active->buttons[ ev->cbutton.button ] = 1;
-      }
-   }
-   else if( ev->type == SDL_CONTROLLERBUTTONUP ){
-      for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
-         struct vg_controller *esta = &vg_input.controllers[i];
-
-         if( ev->cbutton.which == esta->instance_id ){
-            esta->buttons[ ev->cbutton.button ] = 0;
-            break;
-         }
-      }
-   }
-}
-
-static void vg_process_inputs(void)
-{
-   int count;
-   vg_input.sdl_keys = SDL_GetKeyboardState( &count );
-   vg_input.sdl_mouse = SDL_GetMouseState(NULL,NULL);
-
-   if( vg_input.display_input_method != k_input_method_kbm ){
-      /* check for giving keyboard priority */
-      for( int i=0; i<count; i++ ){
-         if( vg_input.sdl_keys[i] ){
-            vg_input.display_input_method = k_input_method_kbm;
-            vg_info( "display_input: k_input_method_kbm (keyboard %d)\n", i );
-            break;
-         }
-      }
-
-      /* check for giving mouse priority */
-      if( vg_input.sdl_mouse & 
-            (SDL_BUTTON(SDL_BUTTON_LEFT)|SDL_BUTTON(SDL_BUTTON_RIGHT)|
-             SDL_BUTTON(SDL_BUTTON_MIDDLE)) )
-      {
-         vg_input.display_input_method = k_input_method_kbm;
-         vg_info( "display_input: k_input_method_kbm (mouse)\n" );
-      }
-   }
-}
-
-static void async_vg_input_init( void *payload, u32 size )
-{
-   VG_VAR_F32( controller_deadzone, flags=VG_VAR_PERSISTENT );
-
-   vg_info( "Checking for controllers\n" );
-   SDL_GameControllerAddMappingsFromFile( "gamecontrollerdb.txt" );
-   
-   int joy_count = SDL_NumJoysticks();
-   for( int i=0; i<joy_count; i++ ) {
-      const char *name = SDL_JoystickNameForIndex( i );
-      int is_controller = SDL_IsGameController(i);
-
-      vg_info( "%d: %s [controller: %d]\n", i, name, is_controller );
-
-      if( is_controller ){
-         vg_open_gamecontroller( i );
-      }
-   }
-}
-
-static void vg_input_init(void)
-{
-   vg_async_call( async_vg_input_init, NULL, 0 );
-}
-
-static void vg_input_free(void)
-{
-   for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
-      struct vg_controller *controller = &vg_input.controllers[i];
-
-      if( controller->handle ){
-         SDL_GameControllerClose( controller->handle );
-         controller->handle = NULL;
-      }
-   }
-}
-
-struct vg_controller *vg_active_controller(void){
-   if( vg_input.active_controller_index >= 0 )
-      return &vg_input.controllers[vg_input.active_controller_index];
-   else
-      return NULL;
-}
-
-static u8 vg_controller_button( SDL_GameControllerButton button ){
-   struct vg_controller *c = vg_active_controller();
-   if( c ) return c->buttons[ button ];
-   else return 0;
-}
-
-static f32 vg_controller_axis( SDL_GameControllerAxis axis ){
-   struct vg_controller *c = vg_active_controller();
-   if( c ) return c->axises[ axis ];
-   else return 0;
-}
-
-static void vg_input_apply_to_u8( vg_input_op mode, u8 data, u8 *inout_result ){
-   if     ( mode == vg_mode_absmax )  *inout_result |= data;
-   else if( mode == vg_mode_mul )     *inout_result &= data;
-   else vg_fatal_error( "mode not supported for destination type (%d)", mode );
-}
-
-static void vg_input_apply_to_f32( vg_input_op mode, f32 data, 
-                                   f32 *inout_result ){
-   if     ( mode == vg_mode_absmax ){
-      if( fabsf(data) > fabsf(*inout_result) )
-         *inout_result = data;
-   }
-   else if( mode == vg_mode_max ) *inout_result = vg_maxf(*inout_result,data);
-   else if( mode == vg_mode_mul ) *inout_result *= (f32)data;
-   else if( mode == vg_mode_sub ) *inout_result -= (f32)data;
-   else if( mode == vg_mode_add ) *inout_result += (f32)data;
-   else vg_fatal_error( "mode not supported for destination type (%d)", mode );
-}
-
-static void vg_exec_input_program( enum vg_input_type type, vg_input_op *ops, 
-                                   void *out_result ){
-   u8 *out_button = NULL;
-   f32 *out_joy = NULL;
-
-   if( type == k_vg_input_type_button_u8 ){
-      out_button = out_result;
-      *out_button = 0;
-   }
-   else if( type == k_vg_input_type_axis_f32 ){
-      out_joy = out_result;
-      out_joy[0] = 0.0f;
-   }
-   else if( type == k_vg_input_type_joy_v2f ){
-      out_joy = out_result;
-      out_joy[0] = 0.0f;
-      out_joy[1] = 0.0f;
-   }
-
-   /* computer state */
-   vg_input_op mode = vg_mode_absmax;
-   u32 pc = 0, index = 0;
-
-next_code:;
-   vg_input_op op = ops[ pc ++ ];
-
-   if( (op >= vg_mode_mul) && (op <= vg_mode_max) ){
-      mode = op;
-   }
-   else if( (op == vg_keyboard) || (op == vg_mouse) || (op == vg_joy_button) ){
-      u8 state = 0;
-
-      if( op == vg_keyboard )
-         state = vg_getkey(ops[pc ++]);
-      else if( op == vg_mouse )
-         state = (vg_input.sdl_mouse & SDL_BUTTON(ops[pc ++]))?1:0;
-      else
-         state = vg_controller_button(ops[pc ++]);
-
-      if( type == k_vg_input_type_button_u8 )
-         vg_input_apply_to_u8( mode, state, out_button );
-      else
-         vg_input_apply_to_f32( mode, (f32)state, &out_joy[index] );
-   }
-   else if( op == vg_joy_axis ){
-      f32 state = vg_controller_axis( ops[pc ++] );
-      if( type == k_vg_input_type_button_u8 )
-         vg_input_apply_to_u8( mode, state>0.5f?1:0, out_button );
-      else 
-         vg_input_apply_to_f32( mode, state, &out_joy[index] );
-   }
-   else if( (op >= vg_0_0f) && (op <= vg_2_0f) ){
-      f32 value = (f32)(op - vg_0_5f) * 0.5f;
-      vg_input_apply_to_f32( mode, value, &out_joy[index] );
-   }
-   else if( op == vg_index ){
-      index = ops[pc ++];
-   }
-   else if( op == vg_end ){
-      return;
-   }
-   else if( op == vg_normalize ){
-      v2_normalize( out_joy );
-   }
-   else {
-      vg_fatal_error( "unknown op\n" );
-   }
-
-   goto next_code;
-}
-
-#endif
+extern vg_input;
+
+u8 vg_getkey( SDL_Keycode kc );
+void vg_process_inputs(void);
+void async_vg_input_init( void *payload, u32 size );
+void vg_input_init(void);
+void vg_input_free(void);
+struct vg_controller *vg_active_controller(void);
+u8 vg_controller_button( SDL_GameControllerButton button );
+f32 vg_controller_axis( SDL_GameControllerAxis axis );
+void vg_exec_input_program( enum vg_input_type type, vg_input_op *ops, 
+                            void *out_result );
+const char *controller_button_str( SDL_GameControllerButton button );
+void vg_keyboard_key_string( vg_str *str, u32 key, int special_glyphs );
+void vg_mouse_button_string( vg_str *str, u32 button, int special_glyphs );
+void vg_joy_axis_string( vg_str *str, SDL_GameControllerAxis axis, 
+                         int special_glyphs );
+void vg_joy_string( vg_str *str, vg_input_op op, int special_glyphs );
+void vg_input_string( vg_str *str, vg_input_op *ops, int glyphs );
+void vg_input_device_event( SDL_Event *ev );
+void vg_input_controller_event( SDL_Event *ev );