2014-03-16 16:49:59 -07:00
/*
2015-01-01 15:04:46 -08:00
* Copyright 2011 - 2015 Branimir Karadzic . All rights reserved .
2014-03-16 16:49:59 -07:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
# include "entry_p.h"
# if BX_PLATFORM_EMSCRIPTEN
# include <emscripten.h>
2015-08-20 14:03:40 -07:00
# include <emscripten/html5.h>
2014-03-16 16:49:59 -07:00
2015-08-15 11:27:26 -07:00
extern " C " void entry_emscripten_yield ( )
{
// emscripten_sleep(0);
}
2014-03-16 16:49:59 -07:00
namespace entry
{
2015-08-20 14:03:40 -07:00
static WindowHandle s_defaultWindow = { 0 } ;
static uint8_t s_translateKey [ 256 ] ;
struct Context
{
Context ( )
: m_scrollf ( 0.0f )
, m_mx ( 0 )
, m_my ( 0 )
, m_scroll ( 0 )
{
memset ( s_translateKey , 0 , sizeof ( s_translateKey ) ) ;
s_translateKey [ 27 ] = Key : : Esc ;
s_translateKey [ uint8_t ( ' \n ' ) ] =
s_translateKey [ uint8_t ( ' \r ' ) ] = Key : : Return ;
s_translateKey [ uint8_t ( ' \t ' ) ] = Key : : Tab ;
s_translateKey [ 127 ] = Key : : Backspace ;
s_translateKey [ uint8_t ( ' ' ) ] = Key : : Space ;
s_translateKey [ 38 ] = Key : : Up ;
s_translateKey [ 40 ] = Key : : Down ;
s_translateKey [ 37 ] = Key : : Left ;
s_translateKey [ 39 ] = Key : : Right ;
s_translateKey [ uint8_t ( ' + ' ) ] =
s_translateKey [ uint8_t ( ' = ' ) ] = Key : : Plus ;
s_translateKey [ uint8_t ( ' _ ' ) ] =
s_translateKey [ uint8_t ( ' - ' ) ] = Key : : Minus ;
s_translateKey [ uint8_t ( ' : ' ) ] =
s_translateKey [ uint8_t ( ' ; ' ) ] = Key : : Semicolon ;
s_translateKey [ uint8_t ( ' " ' ) ] =
s_translateKey [ uint8_t ( ' \' ' ) ] = Key : : Quote ;
s_translateKey [ uint8_t ( ' { ' ) ] =
s_translateKey [ uint8_t ( ' [ ' ) ] = Key : : LeftBracket ;
s_translateKey [ uint8_t ( ' } ' ) ] =
s_translateKey [ uint8_t ( ' ] ' ) ] = Key : : RightBracket ;
s_translateKey [ uint8_t ( ' < ' ) ] =
s_translateKey [ uint8_t ( ' , ' ) ] = Key : : Comma ;
s_translateKey [ uint8_t ( ' > ' ) ] =
s_translateKey [ uint8_t ( ' . ' ) ] = Key : : Period ;
s_translateKey [ uint8_t ( ' ? ' ) ] =
s_translateKey [ uint8_t ( ' / ' ) ] = Key : : Slash ;
s_translateKey [ uint8_t ( ' | ' ) ] =
s_translateKey [ uint8_t ( ' \\ ' ) ] = Key : : Backslash ;
s_translateKey [ uint8_t ( ' ~ ' ) ] =
s_translateKey [ uint8_t ( ' ` ' ) ] = Key : : Tilde ;
s_translateKey [ uint8_t ( ' 0 ' ) ] = Key : : Key0 ;
s_translateKey [ uint8_t ( ' 1 ' ) ] = Key : : Key1 ;
s_translateKey [ uint8_t ( ' 2 ' ) ] = Key : : Key2 ;
s_translateKey [ uint8_t ( ' 3 ' ) ] = Key : : Key3 ;
s_translateKey [ uint8_t ( ' 4 ' ) ] = Key : : Key4 ;
s_translateKey [ uint8_t ( ' 5 ' ) ] = Key : : Key5 ;
s_translateKey [ uint8_t ( ' 6 ' ) ] = Key : : Key6 ;
s_translateKey [ uint8_t ( ' 7 ' ) ] = Key : : Key7 ;
s_translateKey [ uint8_t ( ' 8 ' ) ] = Key : : Key8 ;
s_translateKey [ uint8_t ( ' 9 ' ) ] = Key : : Key9 ;
for ( char ch = ' a ' ; ch < = ' z ' ; + + ch )
{
s_translateKey [ uint8_t ( ch ) ] =
s_translateKey [ uint8_t ( ch - ' ' ) ] = Key : : KeyA + ( ch - ' a ' ) ;
}
}
int32_t run ( int _argc , char * * _argv )
{
emscripten_set_mousedown_callback ( " #canvas " , this , true , mouseCb ) ;
emscripten_set_mouseup_callback ( " #canvas " , this , true , mouseCb ) ;
emscripten_set_mousemove_callback ( " #canvas " , this , true , mouseCb ) ;
emscripten_set_wheel_callback ( " #canvas " , this , true , wheelCb ) ;
emscripten_set_keypress_callback ( NULL , this , true , keyCb ) ;
emscripten_set_keydown_callback ( NULL , this , true , keyCb ) ;
emscripten_set_keyup_callback ( NULL , this , true , keyCb ) ;
emscripten_set_resize_callback ( 0 , this , true , resizeCb ) ;
EmscriptenFullscreenStrategy fullscreenStrategy = { } ;
fullscreenStrategy . scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT ;
fullscreenStrategy . canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE ;
fullscreenStrategy . filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT ;
fullscreenStrategy . canvasResizedCallback = canvasResizeCb ;
fullscreenStrategy . canvasResizedCallbackUserData = this ;
emscripten_request_fullscreen_strategy ( " #canvas " , false , & fullscreenStrategy ) ;
2015-08-24 19:12:01 -07:00
emscripten_set_focus_callback ( NULL , this , true , focusCb ) ;
emscripten_set_focusin_callback ( NULL , this , true , focusCb ) ;
emscripten_set_focusout_callback ( NULL , this , true , focusCb ) ;
2015-08-20 14:03:40 -07:00
int32_t result = main ( _argc , _argv ) ;
return result ;
}
2015-08-24 19:12:01 -07:00
static EM_BOOL mouseCb ( int eventType , const EmscriptenMouseEvent * event , void * userData ) ;
static EM_BOOL wheelCb ( int eventType , const EmscriptenWheelEvent * event , void * userData ) ;
static EM_BOOL keyCb ( int eventType , const EmscriptenKeyboardEvent * event , void * userData ) ;
static EM_BOOL resizeCb ( int eventType , const EmscriptenUiEvent * event , void * userData ) ;
static EM_BOOL canvasResizeCb ( int eventType , const void * reserved , void * userData ) ;
static EM_BOOL focusCb ( int eventType , const EmscriptenFocusEvent * event , void * userData ) ;
2015-08-20 14:03:40 -07:00
EventQueue m_eventQueue ;
float m_scrollf ;
int32_t m_mx ;
int32_t m_my ;
int32_t m_scroll ;
} ;
static Context s_ctx ;
EM_BOOL Context : : mouseCb ( int eventType , const EmscriptenMouseEvent * event , void * userData )
{
BX_UNUSED ( userData ) ;
if ( event )
{
switch ( eventType )
{
case EMSCRIPTEN_EVENT_MOUSEMOVE :
{
s_ctx . m_mx = event - > canvasX ;
s_ctx . m_my = event - > canvasY ;
s_ctx . m_eventQueue . postMouseEvent ( s_defaultWindow , s_ctx . m_mx , s_ctx . m_my , s_ctx . m_scroll ) ;
return true ;
}
case EMSCRIPTEN_EVENT_MOUSEDOWN :
case EMSCRIPTEN_EVENT_MOUSEUP :
case EMSCRIPTEN_EVENT_DBLCLICK :
{
s_ctx . m_mx = event - > canvasX ;
s_ctx . m_my = event - > canvasY ;
MouseButton : : Enum mb = ( event - > button = = 2 ) ? MouseButton : : Right : ( ( event - > button = = 1 ) ? MouseButton : : Middle : MouseButton : : Left ) ;
s_ctx . m_eventQueue . postMouseEvent ( s_defaultWindow , s_ctx . m_mx , s_ctx . m_my , s_ctx . m_scroll , mb , ( eventType ! = EMSCRIPTEN_EVENT_MOUSEUP ) ) ;
return true ;
}
}
}
return false ;
}
EM_BOOL Context : : wheelCb ( int eventType , const EmscriptenWheelEvent * event , void * userData )
{
BX_UNUSED ( userData ) ;
if ( event )
{
switch ( eventType )
{
case EMSCRIPTEN_EVENT_WHEEL :
{
s_ctx . m_scrollf + = event - > deltaY ;
s_ctx . m_scroll = ( int32_t ) s_ctx . m_scrollf ;
s_ctx . m_eventQueue . postMouseEvent ( s_defaultWindow , s_ctx . m_mx , s_ctx . m_my , s_ctx . m_scroll ) ;
return true ;
}
}
}
return false ;
}
uint8_t translateModifiers ( const EmscriptenKeyboardEvent * event )
{
uint8_t mask = 0 ;
if ( event - > shiftKey )
mask | = Modifier : : LeftShift | Modifier : : RightShift ;
if ( event - > altKey )
mask | = Modifier : : LeftAlt | Modifier : : RightAlt ;
if ( event - > ctrlKey )
mask | = Modifier : : LeftCtrl | Modifier : : RightCtrl ;
if ( event - > metaKey )
mask | = Modifier : : LeftMeta | Modifier : : RightMeta ;
return mask ;
}
Key : : Enum handleKeyEvent ( const EmscriptenKeyboardEvent * event , uint8_t * specialKeys , uint8_t * _pressedChar )
{
* _pressedChar = ( uint8_t ) event - > keyCode ;
int keyCode = ( int ) event - > keyCode ;
* specialKeys = translateModifiers ( event ) ;
if ( event - > charCode = = 0 )
{
switch ( keyCode )
{
case 112 : return Key : : F1 ;
case 113 : return Key : : F2 ;
case 114 : return Key : : F3 ;
case 115 : return Key : : F4 ;
case 116 : return Key : : F5 ;
case 117 : return Key : : F6 ;
case 118 : return Key : : F7 ;
case 119 : return Key : : F8 ;
case 120 : return Key : : F9 ;
case 121 : return Key : : F10 ;
case 122 : return Key : : F11 ;
case 123 : return Key : : F12 ;
case 37 : return Key : : Left ;
case 39 : return Key : : Right ;
case 38 : return Key : : Up ;
case 40 : return Key : : Down ;
}
}
// if this is a unhandled key just return None
if ( keyCode < 256 )
{
return ( Key : : Enum ) s_translateKey [ keyCode ] ;
}
return Key : : None ;
}
EM_BOOL Context : : keyCb ( int eventType , const EmscriptenKeyboardEvent * event , void * userData )
{
BX_UNUSED ( userData ) ;
if ( event )
{
uint8_t modifiers = 0 ;
uint8_t pressedChar [ 4 ] ;
Key : : Enum key = handleKeyEvent ( event , & modifiers , & pressedChar [ 0 ] ) ;
// Returning true means that we take care of the key (instead of the default behavior)
if ( key ! = Key : : None )
{
switch ( eventType )
{
case EMSCRIPTEN_EVENT_KEYPRESS :
case EMSCRIPTEN_EVENT_KEYDOWN :
{
if ( key = = Key : : KeyQ & & ( modifiers & Modifier : : RightMeta ) )
{
s_ctx . m_eventQueue . postExitEvent ( ) ;
}
else
{
enum { ShiftMask = Modifier : : LeftShift | Modifier : : RightShift } ;
s_ctx . m_eventQueue . postCharEvent ( s_defaultWindow , 1 , pressedChar ) ;
s_ctx . m_eventQueue . postKeyEvent ( s_defaultWindow , key , modifiers , true ) ;
return true ;
}
break ;
}
case EMSCRIPTEN_EVENT_KEYUP :
{
s_ctx . m_eventQueue . postKeyEvent ( s_defaultWindow , key , modifiers , false ) ;
return true ;
}
}
}
}
return false ;
}
2015-08-24 19:12:01 -07:00
EM_BOOL Context : : resizeCb ( int eventType , const EmscriptenUiEvent * event , void * userData )
2015-08-20 14:03:40 -07:00
{
BX_UNUSED ( eventType , event , userData ) ;
return false ;
}
2015-08-24 19:12:01 -07:00
EM_BOOL Context : : canvasResizeCb ( int eventType , const void * reserved , void * userData )
2015-08-20 14:03:40 -07:00
{
BX_UNUSED ( eventType , reserved , userData ) ;
return false ;
}
2015-08-24 19:12:01 -07:00
EM_BOOL Context : : focusCb ( int eventType , const EmscriptenFocusEvent * event , void * userData )
{
printf ( " focusCb %d " , eventType ) ;
BX_UNUSED ( event , userData ) ;
if ( event )
{
switch ( eventType )
{
case EMSCRIPTEN_EVENT_BLUR :
{
s_ctx . m_eventQueue . postSuspendEvent ( s_defaultWindow , Suspend : : DidSuspend ) ;
return true ;
}
case EMSCRIPTEN_EVENT_FOCUS :
{
s_ctx . m_eventQueue . postSuspendEvent ( s_defaultWindow , Suspend : : DidResume ) ;
return true ;
}
case EMSCRIPTEN_EVENT_FOCUSIN :
{
s_ctx . m_eventQueue . postSuspendEvent ( s_defaultWindow , Suspend : : WillResume ) ;
return true ;
}
case EMSCRIPTEN_EVENT_FOCUSOUT :
{
s_ctx . m_eventQueue . postSuspendEvent ( s_defaultWindow , Suspend : : WillSuspend ) ;
return true ;
}
}
}
return false ;
}
2014-03-16 16:49:59 -07:00
const Event * poll ( )
{
2015-08-15 11:27:26 -07:00
entry_emscripten_yield ( ) ;
2015-08-20 14:03:40 -07:00
return s_ctx . m_eventQueue . poll ( ) ;
2014-03-16 16:49:59 -07:00
}
2014-09-22 19:34:10 -07:00
const Event * poll ( WindowHandle _handle )
2014-03-16 16:49:59 -07:00
{
2015-08-15 11:27:26 -07:00
entry_emscripten_yield ( ) ;
2015-08-20 14:03:40 -07:00
return s_ctx . m_eventQueue . poll ( _handle ) ;
2014-09-22 19:34:10 -07:00
}
void release ( const Event * _event )
{
2015-08-20 14:03:40 -07:00
s_ctx . m_eventQueue . release ( _event ) ;
2014-09-22 19:34:10 -07:00
}
WindowHandle createWindow ( int32_t _x , int32_t _y , uint32_t _width , uint32_t _height , uint32_t _flags , const char * _title )
{
BX_UNUSED ( _x , _y , _width , _height , _flags , _title ) ;
WindowHandle handle = { UINT16_MAX } ;
2015-08-20 14:03:40 -07:00
2014-09-22 19:34:10 -07:00
return handle ;
}
void destroyWindow ( WindowHandle _handle )
{
BX_UNUSED ( _handle ) ;
}
void setWindowPos ( WindowHandle _handle , int32_t _x , int32_t _y )
{
BX_UNUSED ( _handle , _x , _y ) ;
2014-03-16 16:49:59 -07:00
}
2014-09-22 19:34:10 -07:00
void setWindowSize ( WindowHandle _handle , uint32_t _width , uint32_t _height )
2014-03-16 16:49:59 -07:00
{
2014-09-22 19:34:10 -07:00
BX_UNUSED ( _handle , _width , _height ) ;
2014-03-16 16:49:59 -07:00
}
2014-09-22 19:34:10 -07:00
void setWindowTitle ( WindowHandle _handle , const char * _title )
2014-08-05 20:57:52 +01:00
{
2014-09-22 19:34:10 -07:00
BX_UNUSED ( _handle , _title ) ;
2014-08-05 20:57:52 +01:00
}
2014-09-22 19:34:10 -07:00
void toggleWindowFrame ( WindowHandle _handle )
2014-03-16 16:49:59 -07:00
{
2014-09-22 19:34:10 -07:00
BX_UNUSED ( _handle ) ;
2014-03-16 16:49:59 -07:00
}
2015-03-07 23:38:48 +01:00
void toggleFullscreen ( WindowHandle _handle )
{
BX_UNUSED ( _handle ) ;
}
2014-09-22 19:34:10 -07:00
void setMouseLock ( WindowHandle _handle , bool _lock )
2014-03-16 16:49:59 -07:00
{
2014-09-22 19:34:10 -07:00
BX_UNUSED ( _handle , _lock ) ;
2014-03-16 16:49:59 -07:00
}
}
int main ( int _argc , char * * _argv )
{
2015-08-20 14:03:40 -07:00
using namespace entry ;
return s_ctx . run ( _argc , _argv ) ;
2014-03-16 16:49:59 -07:00
}
# endif // BX_PLATFORM_EMSCRIPTEN