2013-01-13 15:35:06 -08:00
/*
2014-02-10 22:07:04 -08:00
* Copyright 2011 - 2014 Branimir Karadzic . All rights reserved .
2013-01-13 15:35:06 -08:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
2013-08-14 21:08:46 -07:00
# include "entry_p.h"
2013-01-13 15:35:06 -08:00
2013-08-14 21:08:46 -07:00
# if ENTRY_CONFIG_USE_NATIVE && BX_PLATFORM_WINDOWS
2013-01-13 15:35:06 -08:00
2013-08-07 23:11:20 -07:00
# include <bgfxplatform.h>
2013-01-16 22:44:51 -08:00
2013-01-13 15:35:06 -08:00
# include <bx/uint32_t.h>
# include <bx/thread.h>
2013-01-16 22:44:51 -08:00
# include <windowsx.h>
2013-01-13 15:35:06 -08:00
2013-01-16 22:44:51 -08:00
# define WM_USER_SET_WINDOW_SIZE (WM_USER+0)
# define WM_USER_TOGGLE_WINDOW_FRAME (WM_USER+1)
2013-01-19 00:22:25 -08:00
# define WM_USER_MOUSE_LOCK (WM_USER+2)
2013-01-16 22:44:51 -08:00
2013-01-13 15:35:06 -08:00
namespace entry
{
2013-01-16 22:44:51 -08:00
struct TranslateKeyModifiers
{
int m_vk ;
Modifier : : Enum m_modifier ;
} ;
static const TranslateKeyModifiers s_translateKeyModifiers [ 8 ] =
{
{ VK_LMENU , Modifier : : LeftAlt } ,
{ VK_RMENU , Modifier : : RightAlt } ,
{ VK_LCONTROL , Modifier : : LeftCtrl } ,
{ VK_RCONTROL , Modifier : : RightCtrl } ,
{ VK_LSHIFT , Modifier : : LeftShift } ,
{ VK_RSHIFT , Modifier : : RightShift } ,
{ VK_LWIN , Modifier : : LeftMeta } ,
{ VK_RWIN , Modifier : : RightMeta } ,
} ;
static uint8_t translateKeyModifiers ( )
{
uint8_t modifiers = 0 ;
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( s_translateKeyModifiers ) ; + + ii )
2013-01-16 22:44:51 -08:00
{
const TranslateKeyModifiers & tkm = s_translateKeyModifiers [ ii ] ;
modifiers | = 0 > GetKeyState ( tkm . m_vk ) ? tkm . m_modifier : Modifier : : None ;
}
return modifiers ;
}
static uint8_t s_translateKey [ 256 ] ;
static Key : : Enum translateKey ( WPARAM _wparam )
{
return ( Key : : Enum ) s_translateKey [ _wparam & 0xff ] ;
}
2013-01-13 15:35:06 -08:00
struct MainThreadEntry
{
int m_argc ;
char * * m_argv ;
2013-01-16 22:44:51 -08:00
static int32_t threadFunc ( void * _userData ) ;
2013-01-13 15:35:06 -08:00
} ;
2013-01-13 10:47:30 -08:00
struct Context
{
Context ( )
: m_frame ( true )
2013-08-30 22:31:40 -07:00
, m_mouseLock ( false )
2013-01-16 22:44:51 -08:00
, m_init ( false )
2013-01-13 10:47:30 -08:00
, m_exit ( false )
2014-08-05 22:37:47 -07:00
, m_mz ( 0 )
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
memset ( s_translateKey , 0 , sizeof ( s_translateKey ) ) ;
2013-01-17 23:22:38 -08:00
s_translateKey [ VK_ESCAPE ] = Key : : Esc ;
s_translateKey [ VK_RETURN ] = Key : : Return ;
s_translateKey [ VK_TAB ] = Key : : Tab ;
s_translateKey [ VK_BACK ] = Key : : Backspace ;
s_translateKey [ VK_SPACE ] = Key : : Space ;
s_translateKey [ VK_UP ] = Key : : Up ;
s_translateKey [ VK_DOWN ] = Key : : Down ;
s_translateKey [ VK_LEFT ] = Key : : Left ;
s_translateKey [ VK_RIGHT ] = Key : : Right ;
s_translateKey [ VK_PRIOR ] = Key : : PageUp ;
s_translateKey [ VK_NEXT ] = Key : : PageUp ;
s_translateKey [ VK_HOME ] = Key : : Home ;
s_translateKey [ VK_END ] = Key : : End ;
s_translateKey [ VK_SNAPSHOT ] = Key : : Print ;
s_translateKey [ VK_OEM_PLUS ] = Key : : Plus ;
2013-01-16 22:44:51 -08:00
s_translateKey [ VK_OEM_MINUS ] = Key : : Minus ;
2013-01-17 23:22:38 -08:00
s_translateKey [ VK_F1 ] = Key : : F1 ;
s_translateKey [ VK_F2 ] = Key : : F2 ;
s_translateKey [ VK_F3 ] = Key : : F3 ;
s_translateKey [ VK_F4 ] = Key : : F4 ;
s_translateKey [ VK_F5 ] = Key : : F5 ;
s_translateKey [ VK_F6 ] = Key : : F6 ;
s_translateKey [ VK_F7 ] = Key : : F7 ;
s_translateKey [ VK_F8 ] = Key : : F8 ;
s_translateKey [ VK_F9 ] = Key : : F9 ;
s_translateKey [ VK_F10 ] = Key : : F10 ;
s_translateKey [ VK_F11 ] = Key : : F11 ;
s_translateKey [ VK_F12 ] = Key : : F12 ;
s_translateKey [ VK_NUMPAD0 ] = Key : : NumPad0 ;
s_translateKey [ VK_NUMPAD1 ] = Key : : NumPad1 ;
s_translateKey [ VK_NUMPAD2 ] = Key : : NumPad2 ;
s_translateKey [ VK_NUMPAD3 ] = Key : : NumPad3 ;
s_translateKey [ VK_NUMPAD4 ] = Key : : NumPad4 ;
s_translateKey [ VK_NUMPAD5 ] = Key : : NumPad5 ;
s_translateKey [ VK_NUMPAD6 ] = Key : : NumPad6 ;
s_translateKey [ VK_NUMPAD7 ] = Key : : NumPad7 ;
s_translateKey [ VK_NUMPAD8 ] = Key : : NumPad8 ;
s_translateKey [ VK_NUMPAD9 ] = Key : : NumPad9 ;
s_translateKey [ ' 0 ' ] = Key : : Key0 ;
s_translateKey [ ' 1 ' ] = Key : : Key1 ;
s_translateKey [ ' 2 ' ] = Key : : Key2 ;
s_translateKey [ ' 3 ' ] = Key : : Key3 ;
s_translateKey [ ' 4 ' ] = Key : : Key4 ;
s_translateKey [ ' 5 ' ] = Key : : Key5 ;
s_translateKey [ ' 6 ' ] = Key : : Key6 ;
s_translateKey [ ' 7 ' ] = Key : : Key7 ;
s_translateKey [ ' 8 ' ] = Key : : Key8 ;
s_translateKey [ ' 9 ' ] = Key : : Key9 ;
s_translateKey [ ' A ' ] = Key : : KeyA ;
s_translateKey [ ' B ' ] = Key : : KeyB ;
s_translateKey [ ' C ' ] = Key : : KeyC ;
s_translateKey [ ' D ' ] = Key : : KeyD ;
s_translateKey [ ' E ' ] = Key : : KeyE ;
s_translateKey [ ' F ' ] = Key : : KeyF ;
s_translateKey [ ' G ' ] = Key : : KeyG ;
s_translateKey [ ' H ' ] = Key : : KeyH ;
s_translateKey [ ' I ' ] = Key : : KeyI ;
s_translateKey [ ' J ' ] = Key : : KeyJ ;
s_translateKey [ ' K ' ] = Key : : KeyK ;
s_translateKey [ ' L ' ] = Key : : KeyL ;
s_translateKey [ ' M ' ] = Key : : KeyM ;
s_translateKey [ ' N ' ] = Key : : KeyN ;
s_translateKey [ ' O ' ] = Key : : KeyO ;
s_translateKey [ ' P ' ] = Key : : KeyP ;
s_translateKey [ ' Q ' ] = Key : : KeyQ ;
s_translateKey [ ' R ' ] = Key : : KeyR ;
s_translateKey [ ' S ' ] = Key : : KeyS ;
s_translateKey [ ' T ' ] = Key : : KeyT ;
s_translateKey [ ' U ' ] = Key : : KeyU ;
s_translateKey [ ' V ' ] = Key : : KeyV ;
s_translateKey [ ' W ' ] = Key : : KeyW ;
s_translateKey [ ' X ' ] = Key : : KeyX ;
s_translateKey [ ' Y ' ] = Key : : KeyY ;
s_translateKey [ ' Z ' ] = Key : : KeyZ ;
2013-01-13 10:47:30 -08:00
}
2013-04-18 21:16:09 -07:00
int32_t run ( int _argc , char * * _argv )
2013-01-13 10:47:30 -08:00
{
2013-10-10 22:57:42 -07:00
SetDllDirectory ( " . " ) ;
2013-01-13 10:47:30 -08:00
HINSTANCE instance = ( HINSTANCE ) GetModuleHandle ( NULL ) ;
WNDCLASSEX wnd ;
memset ( & wnd , 0 , sizeof ( wnd ) ) ;
wnd . cbSize = sizeof ( wnd ) ;
wnd . lpfnWndProc = DefWindowProc ;
wnd . hInstance = instance ;
2014-04-16 21:03:36 -07:00
wnd . hIcon = LoadIcon ( NULL , IDI_APPLICATION ) ;
wnd . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
2013-01-13 10:47:30 -08:00
wnd . hbrBackground = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;
wnd . lpszClassName = " bgfx_letterbox " ;
2014-04-16 21:03:36 -07:00
wnd . hIconSm = LoadIcon ( NULL , IDI_APPLICATION ) ;
2013-01-13 10:47:30 -08:00
RegisterClassExA ( & wnd ) ;
memset ( & wnd , 0 , sizeof ( wnd ) ) ;
wnd . cbSize = sizeof ( wnd ) ;
wnd . style = CS_HREDRAW | CS_VREDRAW ;
wnd . lpfnWndProc = wndProc ;
wnd . hInstance = instance ;
2014-04-16 21:03:36 -07:00
wnd . hIcon = LoadIcon ( NULL , IDI_APPLICATION ) ;
wnd . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
2013-01-13 10:47:30 -08:00
wnd . lpszClassName = " bgfx " ;
2014-04-16 21:03:36 -07:00
wnd . hIconSm = LoadIcon ( NULL , IDI_APPLICATION ) ;
2013-01-13 10:47:30 -08:00
RegisterClassExA ( & wnd ) ;
HWND hwnd = CreateWindowA ( " bgfx_letterbox "
, " BGFX "
, WS_POPUP | WS_SYSMENU
, - 32000
, - 32000
, 0
, 0
, NULL
, NULL
, instance
, 0
) ;
m_hwnd = CreateWindowA ( " bgfx "
, " BGFX "
, WS_OVERLAPPEDWINDOW | WS_VISIBLE
, 0
, 0
2013-08-14 21:08:46 -07:00
, ENTRY_DEFAULT_WIDTH
, ENTRY_DEFAULT_HEIGHT
2013-01-13 10:47:30 -08:00
, hwnd
, NULL
, instance
, 0
) ;
2013-01-13 18:39:25 -08:00
bgfx : : winSetHwnd ( m_hwnd ) ;
2013-01-13 10:47:30 -08:00
2013-08-14 21:08:46 -07:00
adjust ( ENTRY_DEFAULT_WIDTH , ENTRY_DEFAULT_HEIGHT , true ) ;
m_width = ENTRY_DEFAULT_WIDTH ;
m_height = ENTRY_DEFAULT_HEIGHT ;
m_oldWidth = ENTRY_DEFAULT_WIDTH ;
m_oldHeight = ENTRY_DEFAULT_HEIGHT ;
2013-01-13 10:47:30 -08:00
MainThreadEntry mte ;
mte . m_argc = _argc ;
mte . m_argv = _argv ;
bx : : Thread thread ;
thread . init ( mte . threadFunc , & mte ) ;
2013-01-16 22:44:51 -08:00
m_init = true ;
2013-01-13 10:47:30 -08:00
2013-01-19 12:38:30 -08:00
m_eventQueue . postSizeEvent ( m_width , m_height ) ;
2013-01-13 10:47:30 -08:00
MSG msg ;
msg . message = WM_NULL ;
while ( ! m_exit )
{
WaitMessage ( ) ;
while ( 0 ! = PeekMessage ( & msg , NULL , 0U , 0U , PM_REMOVE ) )
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
}
thread . shutdown ( ) ;
2013-01-16 22:44:51 -08:00
DestroyWindow ( m_hwnd ) ;
DestroyWindow ( hwnd ) ;
2013-01-13 10:47:30 -08:00
return 0 ;
}
LRESULT process ( HWND _hwnd , UINT _id , WPARAM _wparam , LPARAM _lparam )
{
2013-01-16 22:44:51 -08:00
if ( m_init )
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
switch ( _id )
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
case WM_USER_SET_WINDOW_SIZE :
{
uint32_t width = GET_X_LPARAM ( _lparam ) ;
uint32_t height = GET_Y_LPARAM ( _lparam ) ;
adjust ( width , height , true ) ;
}
break ;
2013-01-13 10:47:30 -08:00
2013-01-16 22:44:51 -08:00
case WM_USER_TOGGLE_WINDOW_FRAME :
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
if ( m_frame )
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
m_oldWidth = m_width ;
m_oldHeight = m_height ;
2013-01-13 10:47:30 -08:00
}
2013-01-16 22:44:51 -08:00
adjust ( m_oldWidth , m_oldHeight , ! m_frame ) ;
}
break ;
2013-01-19 00:22:25 -08:00
case WM_USER_MOUSE_LOCK :
setMouseLock ( ! ! _lparam ) ;
break ;
2013-01-16 22:44:51 -08:00
case WM_DESTROY :
break ;
2013-01-13 10:47:30 -08:00
2013-01-16 22:44:51 -08:00
case WM_QUIT :
case WM_CLOSE :
m_exit = true ;
m_eventQueue . postExitEvent ( ) ;
break ;
case WM_SIZING :
{
RECT & rect = * ( RECT * ) _lparam ;
2013-02-27 01:25:23 -08:00
uint32_t width = rect . right - rect . left - m_frameWidth ;
uint32_t height = rect . bottom - rect . top - m_frameHeight ;
2013-01-16 22:44:51 -08:00
2013-02-27 01:25:23 -08:00
//Recalculate size according to aspect ratio
2013-01-16 22:44:51 -08:00
switch ( _wparam )
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
case WMSZ_LEFT :
case WMSZ_RIGHT :
{
float aspectRatio = 1.0f / m_aspectRatio ;
2013-08-14 21:08:46 -07:00
width = bx : : uint32_max ( ENTRY_DEFAULT_WIDTH / 4 , width ) ;
2013-01-16 22:44:51 -08:00
height = uint32_t ( float ( width ) * aspectRatio ) ;
}
break ;
default :
{
float aspectRatio = m_aspectRatio ;
2013-08-14 21:08:46 -07:00
height = bx : : uint32_max ( ENTRY_DEFAULT_HEIGHT / 4 , height ) ;
2013-01-16 22:44:51 -08:00
width = uint32_t ( float ( height ) * aspectRatio ) ;
}
break ;
2013-01-13 10:47:30 -08:00
}
2013-02-27 01:25:23 -08:00
//Recalculate position using different anchor points
switch ( _wparam )
{
case WMSZ_LEFT :
case WMSZ_TOPLEFT :
case WMSZ_BOTTOMLEFT :
rect . left = rect . right - width - m_frameWidth ;
rect . bottom = rect . top + height + m_frameHeight ;
break ;
2013-02-02 21:07:06 -08:00
2013-02-27 01:25:23 -08:00
default :
rect . right = rect . left + width + m_frameWidth ;
rect . bottom = rect . top + height + m_frameHeight ;
break ;
}
2014-08-05 20:57:52 +01:00
2013-02-02 21:07:06 -08:00
m_eventQueue . postSizeEvent ( m_width , m_height ) ;
2013-01-16 22:44:51 -08:00
}
return 0 ;
2013-01-13 10:47:30 -08:00
2013-01-16 22:44:51 -08:00
case WM_SIZE :
{
2013-01-19 12:11:24 -08:00
uint32_t width = GET_X_LPARAM ( _lparam ) ;
uint32_t height = GET_Y_LPARAM ( _lparam ) ;
2013-02-02 21:07:06 -08:00
m_width = width ;
m_height = height ;
m_eventQueue . postSizeEvent ( m_width , m_height ) ;
2013-01-16 22:44:51 -08:00
}
break ;
2013-01-13 10:47:30 -08:00
2013-01-16 22:44:51 -08:00
case WM_SYSCOMMAND :
switch ( _wparam )
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
case SC_MINIMIZE :
case SC_RESTORE :
2013-01-13 10:47:30 -08:00
{
2013-01-16 22:44:51 -08:00
HWND parent = GetWindow ( _hwnd , GW_OWNER ) ;
if ( NULL ! = parent )
{
PostMessage ( parent , _id , _wparam , _lparam ) ;
}
2013-01-13 10:47:30 -08:00
}
}
2013-01-16 22:44:51 -08:00
break ;
2013-01-13 10:47:30 -08:00
2013-01-17 23:22:38 -08:00
case WM_MOUSEMOVE :
{
int32_t mx = GET_X_LPARAM ( _lparam ) ;
int32_t my = GET_Y_LPARAM ( _lparam ) ;
2013-01-19 00:22:25 -08:00
if ( m_mouseLock )
{
mx - = m_mx ;
my - = m_my ;
if ( 0 = = mx
& & 0 = = my )
{
break ;
}
setMousePos ( m_mx , m_my ) ;
}
2014-08-05 21:13:50 -07:00
m_eventQueue . postMouseEvent ( mx , my , 0 ) ;
}
break ;
case WM_MOUSEWHEEL :
{
2014-08-05 22:03:45 -07:00
POINT pt = { GET_X_LPARAM ( _lparam ) , GET_Y_LPARAM ( _lparam ) } ;
ScreenToClient ( m_hwnd , & pt ) ;
int32_t mx = pt . x ;
int32_t my = pt . y ;
2014-08-05 22:37:47 -07:00
m_mz + = GET_WHEEL_DELTA_WPARAM ( _wparam ) ;
m_eventQueue . postMouseEvent ( mx , my , m_mz ) ;
2013-01-17 23:22:38 -08:00
}
break ;
2013-01-16 22:44:51 -08:00
case WM_LBUTTONDOWN :
case WM_LBUTTONUP :
case WM_LBUTTONDBLCLK :
{
int32_t mx = GET_X_LPARAM ( _lparam ) ;
int32_t my = GET_Y_LPARAM ( _lparam ) ;
2014-08-05 21:13:50 -07:00
m_eventQueue . postMouseEvent ( mx , my , 0 , MouseButton : : Left , _id = = WM_LBUTTONDOWN ) ;
2013-01-16 22:44:51 -08:00
}
break ;
case WM_MBUTTONDOWN :
case WM_MBUTTONUP :
case WM_MBUTTONDBLCLK :
{
int32_t mx = GET_X_LPARAM ( _lparam ) ;
int32_t my = GET_Y_LPARAM ( _lparam ) ;
2014-08-05 21:13:50 -07:00
m_eventQueue . postMouseEvent ( mx , my , 0 , MouseButton : : Middle , _id = = WM_MBUTTONDOWN ) ;
2013-01-16 22:44:51 -08:00
}
break ;
case WM_RBUTTONUP :
case WM_RBUTTONDOWN :
case WM_RBUTTONDBLCLK :
{
int32_t mx = GET_X_LPARAM ( _lparam ) ;
int32_t my = GET_Y_LPARAM ( _lparam ) ;
2014-08-05 21:13:50 -07:00
m_eventQueue . postMouseEvent ( mx , my , 0 , MouseButton : : Right , _id = = WM_RBUTTONDOWN ) ;
2013-01-16 22:44:51 -08:00
}
break ;
2013-01-13 10:47:30 -08:00
2013-01-16 22:44:51 -08:00
case WM_KEYDOWN :
case WM_SYSKEYDOWN :
case WM_KEYUP :
case WM_SYSKEYUP :
{
uint8_t modifiers = translateKeyModifiers ( ) ;
Key : : Enum key = translateKey ( _wparam ) ;
2013-10-23 22:48:16 -07:00
if ( Key : : Print = = key
2014-01-13 20:36:33 -08:00
& & 0x3 = = ( ( uint32_t ) ( _lparam ) > > 30 ) )
2013-10-23 22:48:16 -07:00
{
// VK_SNAPSHOT doesn't generate keydown event. Fire on down event when previous
// key state bit is set to 1 and transition state bit is set to 1.
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646280%28v=vs.85%29.aspx
m_eventQueue . postKeyEvent ( key , modifiers , true ) ;
}
2013-01-16 22:44:51 -08:00
m_eventQueue . postKeyEvent ( key , modifiers , _id = = WM_KEYDOWN | | _id = = WM_SYSKEYDOWN ) ;
}
break ;
default :
break ;
}
2013-01-13 10:47:30 -08:00
}
return DefWindowProc ( _hwnd , _id , _wparam , _lparam ) ;
}
void adjust ( uint32_t _width , uint32_t _height , bool _windowFrame )
{
m_width = _width ;
m_height = _height ;
m_aspectRatio = float ( _width ) / float ( _height ) ;
ShowWindow ( m_hwnd , SW_SHOWNORMAL ) ;
RECT rect ;
RECT newrect = { 0 , 0 , ( LONG ) _width , ( LONG ) _height } ;
DWORD style = WS_POPUP | WS_SYSMENU ;
if ( m_frame )
{
GetWindowRect ( m_hwnd , & m_rect ) ;
m_style = GetWindowLong ( m_hwnd , GWL_STYLE ) ;
}
if ( _windowFrame )
{
rect = m_rect ;
style = m_style ;
}
else
{
# if defined(__MINGW32__)
rect = m_rect ;
style = m_style ;
# else
HMONITOR monitor = MonitorFromWindow ( m_hwnd , MONITOR_DEFAULTTONEAREST ) ;
MONITORINFO mi ;
mi . cbSize = sizeof ( mi ) ;
GetMonitorInfo ( monitor , & mi ) ;
newrect = mi . rcMonitor ;
rect = mi . rcMonitor ;
# endif // !defined(__MINGW__)
}
SetWindowLong ( m_hwnd , GWL_STYLE , style ) ;
2013-02-27 01:25:23 -08:00
uint32_t prewidth = newrect . right - newrect . left ;
uint32_t preheight = newrect . bottom - newrect . top ;
2013-01-13 10:47:30 -08:00
AdjustWindowRect ( & newrect , style , FALSE ) ;
2013-02-27 01:25:23 -08:00
m_frameWidth = ( newrect . right - newrect . left ) - prewidth ;
m_frameHeight = ( newrect . bottom - newrect . top ) - preheight ;
2013-01-13 10:47:30 -08:00
UpdateWindow ( m_hwnd ) ;
if ( rect . left = = - 32000
| | rect . top = = - 32000 )
{
rect . left = 0 ;
rect . top = 0 ;
}
int32_t left = rect . left ;
int32_t top = rect . top ;
int32_t width = ( newrect . right - newrect . left ) ;
int32_t height = ( newrect . bottom - newrect . top ) ;
if ( ! _windowFrame )
{
float aspectRatio = 1.0f / m_aspectRatio ;
2013-08-14 21:08:46 -07:00
width = bx : : uint32_max ( ENTRY_DEFAULT_WIDTH / 4 , width ) ;
2013-01-13 10:47:30 -08:00
height = uint32_t ( float ( width ) * aspectRatio ) ;
left = newrect . left + ( newrect . right - newrect . left - width ) / 2 ;
top = newrect . top + ( newrect . bottom - newrect . top - height ) / 2 ;
}
HWND parent = GetWindow ( m_hwnd , GW_OWNER ) ;
if ( NULL ! = parent )
{
if ( _windowFrame )
{
SetWindowPos ( parent
, HWND_TOP
, - 32000
, - 32000
, 0
, 0
, SWP_SHOWWINDOW
) ;
}
else
{
SetWindowPos ( parent
, HWND_TOP
, newrect . left
, newrect . top
, newrect . right - newrect . left
, newrect . bottom - newrect . top
, SWP_SHOWWINDOW
) ;
}
}
SetWindowPos ( m_hwnd
, HWND_TOP
, left
, top
, width
, height
, SWP_SHOWWINDOW
) ;
ShowWindow ( m_hwnd , SW_RESTORE ) ;
m_frame = _windowFrame ;
}
2013-01-19 00:22:25 -08:00
void setMousePos ( int32_t _mx , int32_t _my )
{
POINT pt = { _mx , _my } ;
ClientToScreen ( m_hwnd , & pt ) ;
SetCursorPos ( pt . x , pt . y ) ;
}
void setMouseLock ( bool _lock )
{
if ( _lock ! = m_mouseLock )
{
if ( _lock )
{
m_mx = m_width / 2 ;
m_my = m_height / 2 ;
ShowCursor ( false ) ;
setMousePos ( m_mx , m_my ) ;
}
else
{
setMousePos ( m_mx , m_my ) ;
ShowCursor ( true ) ;
}
m_mouseLock = _lock ;
}
}
2014-08-05 20:57:52 +01:00
bool setWindowTitle ( const char * _title )
{
return ( 1 = = SetWindowText ( m_hwnd , _title ) ) ;
}
2013-01-13 10:47:30 -08:00
static LRESULT CALLBACK wndProc ( HWND _hwnd , UINT _id , WPARAM _wparam , LPARAM _lparam ) ;
2013-01-16 22:44:51 -08:00
EventQueue m_eventQueue ;
2013-01-13 10:47:30 -08:00
HWND m_hwnd ;
RECT m_rect ;
DWORD m_style ;
uint32_t m_width ;
uint32_t m_height ;
2013-01-16 22:44:51 -08:00
uint32_t m_oldWidth ;
uint32_t m_oldHeight ;
2013-02-27 01:25:23 -08:00
uint32_t m_frameWidth ;
uint32_t m_frameHeight ;
2013-01-13 10:47:30 -08:00
float m_aspectRatio ;
2013-01-19 00:22:25 -08:00
int32_t m_mx ;
int32_t m_my ;
2014-08-05 22:37:47 -07:00
int32_t m_mz ;
2013-01-19 00:22:25 -08:00
2013-01-13 10:47:30 -08:00
bool m_frame ;
2013-01-19 00:22:25 -08:00
bool m_mouseLock ;
2013-01-16 22:44:51 -08:00
bool m_init ;
2013-01-13 10:47:30 -08:00
bool m_exit ;
2013-01-16 22:44:51 -08:00
2013-01-13 10:47:30 -08:00
} ;
static Context s_ctx ;
2013-01-13 15:35:06 -08:00
2013-01-13 10:47:30 -08:00
LRESULT CALLBACK Context : : wndProc ( HWND _hwnd , UINT _id , WPARAM _wparam , LPARAM _lparam )
{
return s_ctx . process ( _hwnd , _id , _wparam , _lparam ) ;
}
2013-01-16 22:44:51 -08:00
const Event * poll ( )
{
return s_ctx . m_eventQueue . poll ( ) ;
}
void release ( const Event * _event )
{
s_ctx . m_eventQueue . release ( _event ) ;
}
2013-02-21 21:07:31 -08:00
void setWindowSize ( uint32_t _width , uint32_t _height )
{
PostMessage ( s_ctx . m_hwnd , WM_USER_SET_WINDOW_SIZE , 0 , ( _height < < 16 ) | ( _width & 0xffff ) ) ;
2013-01-16 22:44:51 -08:00
}
2014-08-05 20:57:52 +01:00
bool setWindowTitle ( const char * _title )
{
return s_ctx . setWindowTitle ( _title ) ;
}
2013-01-16 22:44:51 -08:00
void toggleWindowFrame ( )
2013-02-21 21:07:31 -08:00
{
PostMessage ( s_ctx . m_hwnd , WM_USER_TOGGLE_WINDOW_FRAME , 0 , 0 ) ;
2013-01-16 22:44:51 -08:00
}
2013-01-19 00:22:25 -08:00
void setMouseLock ( bool _lock )
{
PostMessage ( s_ctx . m_hwnd , WM_USER_MOUSE_LOCK , 0 , _lock ) ;
}
2013-01-16 22:44:51 -08:00
int32_t MainThreadEntry : : threadFunc ( void * _userData )
2013-01-13 15:35:06 -08:00
{
2013-01-16 22:44:51 -08:00
MainThreadEntry * self = ( MainThreadEntry * ) _userData ;
2013-08-07 21:45:56 -07:00
int32_t result = main ( self - > m_argc , self - > m_argv ) ;
2013-01-16 22:44:51 -08:00
PostMessage ( s_ctx . m_hwnd , WM_QUIT , 0 , 0 ) ;
return result ;
2013-01-13 15:35:06 -08:00
}
} // namespace entry
int main ( int _argc , char * * _argv )
{
using namespace entry ;
2013-04-18 21:16:09 -07:00
return s_ctx . run ( _argc , _argv ) ;
2013-01-13 15:35:06 -08:00
}
# endif // BX_PLATFORM_WINDOWS