Skip to content

Commit

Permalink
add Mouse scaled support (Windows); alter semantics of Mouse.xy()
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Nov 19, 2024
1 parent 3dc9158 commit 399b99b
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 40 deletions.
53 changes: 18 additions & 35 deletions src/core/chuck_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1500,42 +1500,35 @@ t_CKBOOL init_class_HID( Chuck_Env * env )
// init Mouse class | 1.5.4.2 (ge & spencer) added
if( !type_engine_import_class_begin( env, "Mouse", "Object",
env->global(), Mouse_ctor, Mouse_dtor,
"Global mouse tracking object." ) )
"Mouse position tracking. (For full access to mouse input, see the Hid class.)" ) )
return FALSE;

// add examples
if( !type_engine_import_add_ex( env, "hid/ezmouse.ck" ) ) goto error;

// add pos() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "vec2", "pos", Mouse_pos );
func->doc = "get the normalized X and Y positions of the mouse cursor, respectively in the range [0.0,1.0]; same as .xy().";
func = make_new_sfun( "vec2", "scaled", Mouse_scaled );
func->doc = "get the current X and Y normalized positions of the mouse cursor relative to its containing monitor; yields X and Y values in the range [0.0,1.0]";
if( !type_engine_import_sfun( env, func ) ) goto error;

// add abs() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "vec2", "abs", Mouse_abs );
func->doc = "get the current X and Y absolute coordinates of the mouse cursor; dependent on screen resolution; could yield positive and negative values in a multi-monitor setup; same as .xy()";
if( !type_engine_import_sfun( env, func ) ) goto error;

// add xy() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "vec2", "xy", Mouse_pos );
func->doc = "get the normalized X and Y positions of the mouse cursor, respectively in the range [0.0,1.0]; same as .pos().";
func = make_new_sfun( "vec2", "xy", Mouse_abs );
func->doc = "get the current X and Y absolute coordinates of the mouse cursor; dependent on screen resolution; could yield positive and negative values in a multi-monitor setup; same as .abs()";
if( !type_engine_import_sfun( env, func ) ) goto error;

// add x() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "float", "x", Mouse_pos_x );
func->doc = "get the normalized X position of the mouse cursor, in the range [0.0,1.0].";
func = make_new_sfun( "float", "x", Mouse_abs_x );
func->doc = "get the current X absolute coordinate of the mouse cursor; dependent on screen resolution; could yield positive and negative values in a multi-monitor setup";
if( !type_engine_import_sfun( env, func ) ) goto error;

// add y() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "float", "y", Mouse_pos_y );
func->doc = "get the normalized Y positions of the mouse cursor, in the range [0.0,1.0].";
if( !type_engine_import_sfun( env, func ) ) goto error;

// add abs() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "vec2", "abs", Mouse_abs );
func->doc = "get the absolute X and Y coordinates of the mouse cursor; this is dependent on screen resolution.";
if( !type_engine_import_sfun( env, func ) ) goto error;

// add abs() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "vec2", "absX", Mouse_abs_x );
func->doc = "get the absolute X coordinate of the mouse cursor; this is dependent on screen resolution.";
if( !type_engine_import_sfun( env, func ) ) goto error;

// add abs() | 1.5.4.2 (ge & spencer ) added
func = make_new_sfun( "vec2", "absY", Mouse_abs_y );
func->doc = "get the absolute Y coordinate of the mouse cursor; this is dependent on screen resolution.";
func = make_new_sfun( "float", "y", Mouse_abs_y );
func->doc = "get the current Y absolute coordinate of the mouse cursor; dependent on screen resolution; could yield positive and negative values in a multi-monitor setup";
if( !type_engine_import_sfun( env, func ) ) goto error;

// end the class import
Expand Down Expand Up @@ -3057,21 +3050,11 @@ CK_DLL_CTOR( Mouse_ctor ) { }
CK_DLL_DTOR( Mouse_dtor ) { }

// get normalized mouse XY position, range [0,1]
CK_DLL_SFUN( Mouse_pos )
CK_DLL_SFUN( Mouse_scaled )
{
RETURN->v_vec2 = ck_get_mouse_xy_normalize();
}

CK_DLL_SFUN( Mouse_pos_x )
{
RETURN->v_float = ck_get_mouse_xy_normalize().x;
}

CK_DLL_SFUN( Mouse_pos_y )
{
RETURN->v_float = ck_get_mouse_xy_normalize().y;
}

CK_DLL_SFUN( Mouse_abs )
{
RETURN->v_vec2 = ck_get_mouse_xy_absolute();
Expand Down
4 changes: 1 addition & 3 deletions src/core/chuck_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,7 @@ CK_DLL_MFUN( HidOut_send );

CK_DLL_CTOR( Mouse_ctor );
CK_DLL_DTOR( Mouse_dtor );
CK_DLL_SFUN( Mouse_pos );
CK_DLL_SFUN( Mouse_pos_x );
CK_DLL_SFUN( Mouse_pos_y );
CK_DLL_SFUN( Mouse_scaled );
CK_DLL_SFUN( Mouse_abs );
CK_DLL_SFUN( Mouse_abs_x );
CK_DLL_SFUN( Mouse_abs_y );
Expand Down
62 changes: 60 additions & 2 deletions src/core/util_hid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7800,6 +7800,33 @@ const char * Keyboard_name( int k )
#endif


#ifdef __PLATFORM_WINDOWS__

// multiple monitors info:
// https://stackoverflow.com/questions/4631292/how-to-detect-the-current-screen-resolution
t_CKBOOL GetMonitorRealResolution( HMONITOR monitor, t_CKFLOAT * pixelsWidth, t_CKFLOAT * pixelsHeight )
{
// zero out
*pixelsWidth = *pixelsHeight = 0;

// get monitor info
MONITORINFOEX info; info.cbSize = sizeof( MONITORINFOEX );
if( !GetMonitorInfoA( monitor, &info ) ) return FALSE;

// get display setting
DEVMODE devmode; devmode.dmSize = sizeof( DEVMODE );
if( !EnumDisplaySettingsA( info.szDevice, ENUM_CURRENT_SETTINGS, &devmode ) ) return FALSE;

// get monitor pixel dimensions (note does not take DPI scaling into account; see below for alternate method)
*pixelsWidth = (t_CKFLOAT)devmode.dmPelsWidth;
*pixelsHeight = (t_CKFLOAT)devmode.dmPelsHeight;

// done
return TRUE;
}

#endif

//-----------------------------------------------------------------------------
// unified easy mouse functions
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -7831,14 +7858,45 @@ t_CKVEC2 ck_get_mouse_xy_normalize()
// reclaim
CFRelease( cg_event );
#elif defined(__PLATFORM_WINDOWS__)
// multiple monitors info
// https://stackoverflow.com/questions/4631292/how-to-detect-the-current-screen-resolution

t_CKINT x = 0, y = 0;
t_CKFLOAT logicalWidth = 0, logicalHeight = 0;
POINT pt;
MONITORINFOEX info; info.cbSize = sizeof( MONITORINFOEX );
DEVMODE devmode; devmode.dmSize = sizeof( DEVMODE );
HMONITOR monitor = NULL;

// get cursor position; in a mutliple monitor setup, this could return negative values
// for monitors to the left or above the primary monitor
if( !GetCursorPos( &pt ) ) goto done;
// get the monitor that contains the point
monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST ); if( !monitor ) goto done;
// get monitor info
if( !GetMonitorInfo( monitor, &info ) ) goto done;
// get logical width and height, this takes DPI scaling into account
// e.g., in Settings->Display->Make everything bigger (Windows 10, 11)
logicalWidth = (t_CKFLOAT)info.rcMonitor.right - info.rcMonitor.left;
logicalHeight = (t_CKFLOAT)info.rcMonitor.bottom - info.rcMonitor.top;
// map to monitor coordinate
x = (t_CKINT)pt.x - info.rcMonitor.left;
y = (t_CKINT)pt.y - info.rcMonitor.top;
// normalize
retval.x = x / logicalWidth;
retval.y = y / logicalHeight;

// cerr << pt.x << " " << pt.y << " => " << x << " " << y << " " << " offset: "
// << info.rcMonitor.left << " " << info.rcMonitor.top
// << " dim: " << logicalWidth << " " << logicalHeight
// << " return: " << retval.x << " " << retval.y << endl;

// t_CKFLOAT screenWidth = GetSystemMetrics( SM_CXVIRTUALSCREEN );
// t_CKFLOAT screenHeight = GetSystemMetrics( SM_CYVIRTUALSCREEN );
#elif defined(__PLATFORM_LINUX__)
#else
// unsupported, for now; return 0,0
#endif

done:
// done
return retval;
}
Expand Down

0 comments on commit 399b99b

Please sign in to comment.