2013-08-07 21:45:56 -07:00
/*
2016-01-01 00:11:04 -08:00
* Copyright 2010 - 2016 Branimir Karadzic . All rights reserved .
* License : https : //github.com/bkaradzic/bgfx#license-bsd-2-clause
2013-08-07 21:45:56 -07:00
*/
# include <memory.h>
2013-12-24 20:18:49 -08:00
# include "entry_p.h"
# include "input.h"
2015-05-30 22:11:42 -07:00
# include "cmd.h"
2013-12-24 20:18:49 -08:00
2015-02-09 20:12:46 -08:00
# include <bx/allocator.h>
2014-11-08 20:57:47 -08:00
# include <bx/ringbuffer.h>
2016-02-16 14:54:46 +01:00
# include <tinystl/string.h>
2014-08-22 16:35:30 +02:00
# include <tinystl/allocator.h>
# include <tinystl/unordered_map.h>
namespace stl = tinystl ;
2013-08-07 21:45:56 -07:00
struct Mouse
{
Mouse ( )
: m_width ( 1280 )
, m_height ( 720 )
2014-08-05 21:13:50 -07:00
, m_wheelDelta ( 120 )
2013-08-07 21:45:56 -07:00
, m_lock ( false )
{
}
void reset ( )
{
if ( m_lock )
{
m_norm [ 0 ] = 0.0f ;
m_norm [ 1 ] = 0.0f ;
2014-08-05 21:13:50 -07:00
m_norm [ 2 ] = 0.0f ;
2013-08-07 21:45:56 -07:00
}
memset ( m_buttons , 0 , sizeof ( m_buttons ) ) ;
}
void setResolution ( uint16_t _width , uint16_t _height )
{
m_width = _width ;
m_height = _height ;
}
2014-08-05 21:13:50 -07:00
void setPos ( int32_t _mx , int32_t _my , int32_t _mz )
2013-08-07 21:45:56 -07:00
{
m_absolute [ 0 ] = _mx ;
m_absolute [ 1 ] = _my ;
2014-08-05 21:13:50 -07:00
m_absolute [ 2 ] = _mz ;
2013-08-07 21:45:56 -07:00
m_norm [ 0 ] = float ( _mx ) / float ( m_width ) ;
m_norm [ 1 ] = float ( _my ) / float ( m_height ) ;
2014-08-05 21:13:50 -07:00
m_norm [ 2 ] = float ( _mz ) / float ( m_wheelDelta ) ;
2013-08-07 21:45:56 -07:00
}
void setButtonState ( entry : : MouseButton : : Enum _button , uint8_t _state )
{
m_buttons [ _button ] = _state ;
}
2014-08-05 21:13:50 -07:00
int32_t m_absolute [ 3 ] ;
float m_norm [ 3 ] ;
2013-08-07 21:45:56 -07:00
int32_t m_wheel ;
uint8_t m_buttons [ entry : : MouseButton : : Count ] ;
uint16_t m_width ;
uint16_t m_height ;
2014-08-05 21:13:50 -07:00
uint16_t m_wheelDelta ;
2013-08-07 21:45:56 -07:00
bool m_lock ;
} ;
struct Keyboard
{
Keyboard ( )
2014-11-08 20:57:47 -08:00
: m_ring ( BX_COUNTOF ( m_char ) )
2013-08-07 21:45:56 -07:00
{
}
void reset ( )
{
memset ( m_key , 0 , sizeof ( m_key ) ) ;
memset ( m_once , 0xff , sizeof ( m_once ) ) ;
}
static uint32_t encodeKeyState ( uint8_t _modifiers , bool _down )
{
uint32_t state = 0 ;
state | = uint32_t ( _modifiers ) < < 16 ;
state | = uint32_t ( _down ) < < 8 ;
return state ;
}
2015-06-02 14:28:22 -07:00
static bool decodeKeyState ( uint32_t _state , uint8_t & _modifiers )
2013-08-07 21:45:56 -07:00
{
_modifiers = ( _state > > 16 ) & 0xff ;
2015-06-02 14:28:22 -07:00
return 0 ! = ( ( _state > > 8 ) & 0xff ) ;
2013-08-07 21:45:56 -07:00
}
void setKeyState ( entry : : Key : : Enum _key , uint8_t _modifiers , bool _down )
{
m_key [ _key ] = encodeKeyState ( _modifiers , _down ) ;
m_once [ _key ] = false ;
}
2015-06-02 14:28:22 -07:00
bool getKeyState ( entry : : Key : : Enum _key , uint8_t * _modifiers )
{
uint8_t modifiers ;
_modifiers = NULL = = _modifiers ? & modifiers : _modifiers ;
return decodeKeyState ( m_key [ _key ] , * _modifiers ) ;
}
2015-06-04 18:26:09 -07:00
uint8_t getModifiersState ( )
{
uint8_t modifiers = 0 ;
for ( uint32_t ii = 0 ; ii < entry : : Key : : Count ; + + ii )
{
modifiers | = ( m_key [ ii ] > > 16 ) & 0xff ;
}
return modifiers ;
}
2014-11-08 20:57:47 -08:00
void pushChar ( uint8_t _len , const uint8_t _char [ 4 ] )
{
for ( uint32_t len = m_ring . reserve ( 4 )
; len < _len
; len = m_ring . reserve ( 4 )
)
{
popChar ( ) ;
}
2014-11-11 02:09:39 +01:00
memcpy ( & m_char [ m_ring . m_current ] , _char , 4 ) ;
2014-11-08 20:57:47 -08:00
m_ring . commit ( 4 ) ;
}
const uint8_t * popChar ( )
{
if ( 0 < m_ring . available ( ) )
{
uint8_t * utf8 = & m_char [ m_ring . m_read ] ;
m_ring . consume ( 4 ) ;
return utf8 ;
}
return NULL ;
}
void charFlush ( )
{
m_ring . m_current = 0 ;
m_ring . m_write = 0 ;
m_ring . m_read = 0 ;
}
2013-08-07 21:45:56 -07:00
uint32_t m_key [ 256 ] ;
bool m_once [ 256 ] ;
2014-11-08 20:57:47 -08:00
bx : : RingBufferControl m_ring ;
uint8_t m_char [ 256 ] ;
2013-08-07 21:45:56 -07:00
} ;
2014-12-15 20:58:54 -08:00
struct Gamepad
{
Gamepad ( )
{
reset ( ) ;
}
void reset ( )
{
memset ( m_axis , 0 , sizeof ( m_axis ) ) ;
}
void setAxis ( entry : : GamepadAxis : : Enum _axis , int32_t _value )
{
m_axis [ _axis ] = _value ;
}
int32_t getAxis ( entry : : GamepadAxis : : Enum _axis )
{
return m_axis [ _axis ] ;
}
int32_t m_axis [ entry : : GamepadAxis : : Count ] ;
} ;
2013-08-07 21:45:56 -07:00
struct Input
{
Input ( )
{
reset ( ) ;
}
~ Input ( )
{
}
void addBindings ( const char * _name , const InputBinding * _bindings )
{
2016-02-16 14:54:46 +01:00
m_inputBindingsMap . insert ( stl : : make_pair ( stl : : string ( _name ) , _bindings ) ) ;
2013-08-07 21:45:56 -07:00
}
void removeBindings ( const char * _name )
{
2016-02-16 14:54:46 +01:00
InputBindingMap : : iterator it = m_inputBindingsMap . find ( stl : : string ( _name ) ) ;
2014-11-12 22:16:19 -08:00
if ( it ! = m_inputBindingsMap . end ( ) )
{
m_inputBindingsMap . erase ( it ) ;
}
2013-08-07 21:45:56 -07:00
}
void process ( const InputBinding * _bindings )
{
for ( const InputBinding * binding = _bindings ; binding - > m_key ! = entry : : Key : : None ; + + binding )
{
uint8_t modifiers ;
2015-06-02 14:28:22 -07:00
bool down = Keyboard : : decodeKeyState ( m_keyboard . m_key [ binding - > m_key ] , modifiers ) ;
2013-08-07 21:45:56 -07:00
if ( binding - > m_flags = = 1 )
{
2013-08-09 21:33:28 -07:00
if ( down )
2013-08-07 21:45:56 -07:00
{
2013-08-09 21:33:28 -07:00
if ( modifiers = = binding - > m_modifiers
& & ! m_keyboard . m_once [ binding - > m_key ] )
2013-08-07 21:45:56 -07:00
{
2015-05-30 22:11:42 -07:00
if ( NULL = = binding - > m_fn )
{
cmdExec ( ( const char * ) binding - > m_userData ) ;
}
else
{
binding - > m_fn ( binding - > m_userData ) ;
}
2013-08-07 21:45:56 -07:00
m_keyboard . m_once [ binding - > m_key ] = true ;
}
}
else
{
m_keyboard . m_once [ binding - > m_key ] = false ;
}
}
else
{
if ( down
& & modifiers = = binding - > m_modifiers )
{
2015-05-30 22:11:42 -07:00
if ( NULL = = binding - > m_fn )
{
cmdExec ( ( const char * ) binding - > m_userData ) ;
}
else
{
binding - > m_fn ( binding - > m_userData ) ;
}
2013-08-07 21:45:56 -07:00
}
}
}
}
void process ( )
{
for ( InputBindingMap : : const_iterator it = m_inputBindingsMap . begin ( ) ; it ! = m_inputBindingsMap . end ( ) ; + + it )
{
process ( it - > second ) ;
}
}
void reset ( )
{
m_mouse . reset ( ) ;
m_keyboard . reset ( ) ;
2014-12-15 20:58:54 -08:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_gamepad ) ; + + ii )
{
m_gamepad [ ii ] . reset ( ) ;
}
2013-08-07 21:45:56 -07:00
}
2016-02-16 14:54:46 +01:00
typedef stl : : unordered_map < stl : : string , const InputBinding * > InputBindingMap ;
2013-08-07 21:45:56 -07:00
InputBindingMap m_inputBindingsMap ;
Mouse m_mouse ;
Keyboard m_keyboard ;
2014-12-15 20:58:54 -08:00
Gamepad m_gamepad [ ENTRY_CONFIG_MAX_GAMEPADS ] ;
2013-08-07 21:45:56 -07:00
} ;
2015-02-09 20:12:46 -08:00
static Input * s_input ;
void inputInit ( )
{
s_input = BX_NEW ( entry : : getAllocator ( ) , Input ) ;
}
void inputShutdown ( )
{
BX_DELETE ( entry : : getAllocator ( ) , s_input ) ;
}
2013-08-07 21:45:56 -07:00
void inputAddBindings ( const char * _name , const InputBinding * _bindings )
{
2015-02-09 20:12:46 -08:00
s_input - > addBindings ( _name , _bindings ) ;
2013-08-07 21:45:56 -07:00
}
void inputRemoveBindings ( const char * _name )
{
2015-02-09 20:12:46 -08:00
s_input - > removeBindings ( _name ) ;
2013-08-07 21:45:56 -07:00
}
void inputProcess ( )
{
2015-02-09 20:12:46 -08:00
s_input - > process ( ) ;
2013-08-07 21:45:56 -07:00
}
void inputSetMouseResolution ( uint16_t _width , uint16_t _height )
{
2015-02-09 20:12:46 -08:00
s_input - > m_mouse . setResolution ( _width , _height ) ;
2013-08-07 21:45:56 -07:00
}
void inputSetKeyState ( entry : : Key : : Enum _key , uint8_t _modifiers , bool _down )
{
2015-02-09 20:12:46 -08:00
s_input - > m_keyboard . setKeyState ( _key , _modifiers , _down ) ;
2013-08-07 21:45:56 -07:00
}
2015-06-02 14:28:22 -07:00
bool inputGetKeyState ( entry : : Key : : Enum _key , uint8_t * _modifiers )
{
return s_input - > m_keyboard . getKeyState ( _key , _modifiers ) ;
}
2015-06-04 18:26:09 -07:00
uint8_t inputGetModifiersState ( )
{
return s_input - > m_keyboard . getModifiersState ( ) ;
}
2014-11-08 20:57:47 -08:00
void inputChar ( uint8_t _len , const uint8_t _char [ 4 ] )
{
2015-02-09 20:12:46 -08:00
s_input - > m_keyboard . pushChar ( _len , _char ) ;
2014-11-08 20:57:47 -08:00
}
const uint8_t * inputGetChar ( )
{
2015-02-09 20:12:46 -08:00
return s_input - > m_keyboard . popChar ( ) ;
2014-11-08 20:57:47 -08:00
}
void inputCharFlush ( )
{
2015-02-09 20:12:46 -08:00
s_input - > m_keyboard . charFlush ( ) ;
2014-11-08 20:57:47 -08:00
}
2014-08-05 21:13:50 -07:00
void inputSetMousePos ( int32_t _mx , int32_t _my , int32_t _mz )
2013-08-07 21:45:56 -07:00
{
2015-02-09 20:12:46 -08:00
s_input - > m_mouse . setPos ( _mx , _my , _mz ) ;
2013-08-07 21:45:56 -07:00
}
void inputSetMouseButtonState ( entry : : MouseButton : : Enum _button , uint8_t _state )
{
2015-02-09 20:12:46 -08:00
s_input - > m_mouse . setButtonState ( _button , _state ) ;
2013-08-07 21:45:56 -07:00
}
2014-08-05 21:13:50 -07:00
void inputGetMouse ( float _mouse [ 3 ] )
2013-08-07 21:45:56 -07:00
{
2015-02-09 20:12:46 -08:00
_mouse [ 0 ] = s_input - > m_mouse . m_norm [ 0 ] ;
_mouse [ 1 ] = s_input - > m_mouse . m_norm [ 1 ] ;
_mouse [ 2 ] = s_input - > m_mouse . m_norm [ 2 ] ;
s_input - > m_mouse . m_norm [ 0 ] = 0.0f ;
s_input - > m_mouse . m_norm [ 1 ] = 0.0f ;
s_input - > m_mouse . m_norm [ 2 ] = 0.0f ;
2013-08-07 21:45:56 -07:00
}
bool inputIsMouseLocked ( )
{
2015-02-09 20:12:46 -08:00
return s_input - > m_mouse . m_lock ;
2013-08-07 21:45:56 -07:00
}
void inputSetMouseLock ( bool _lock )
{
2015-02-09 20:12:46 -08:00
if ( s_input - > m_mouse . m_lock ! = _lock )
2013-08-07 21:45:56 -07:00
{
2015-02-09 20:12:46 -08:00
s_input - > m_mouse . m_lock = _lock ;
2014-09-18 22:32:33 -07:00
entry : : WindowHandle defaultWindow = { 0 } ;
entry : : setMouseLock ( defaultWindow , _lock ) ;
2013-08-07 21:45:56 -07:00
if ( _lock )
{
2015-02-09 20:12:46 -08:00
s_input - > m_mouse . m_norm [ 0 ] = 0.0f ;
s_input - > m_mouse . m_norm [ 1 ] = 0.0f ;
s_input - > m_mouse . m_norm [ 2 ] = 0.0f ;
2013-08-07 21:45:56 -07:00
}
}
}
2014-12-15 20:58:54 -08:00
void inputSetGamepadAxis ( entry : : GamepadHandle _handle , entry : : GamepadAxis : : Enum _axis , int32_t _value )
{
2015-02-09 20:12:46 -08:00
s_input - > m_gamepad [ _handle . idx ] . setAxis ( _axis , _value ) ;
2014-12-15 20:58:54 -08:00
}
int32_t inputGetGamepadAxis ( entry : : GamepadHandle _handle , entry : : GamepadAxis : : Enum _axis )
{
2015-02-09 20:12:46 -08:00
return s_input - > m_gamepad [ _handle . idx ] . getAxis ( _axis ) ;
2014-12-15 20:58:54 -08:00
}