Fix mouse state packing bit-field overlap
The old packing was: X << 32 | Y << 16 | buttons where X and Y were full 32-bit values. Y's upper 16 bits (bits 32-47) overlapped with X (bits 32-63), and buttons (bits 0-31) overlapped with Y (bits 16-47). This corrupted X whenever Y >= 65536, and corrupted Y whenever buttons had any bits set above bit 15. The Lean unpacking side already assumed a non-overlapping layout: X = bits 63:32, Y = bits 31:16 (masked to 16), buttons = bits 15:0 Now the C side explicitly masks Y and buttons to 16 bits before packing, matching the Lean expectations. This means Y is limited to [-32768, 32767] which is adequate for screen coordinates and typical relative mode deltas. Also fix the SDLIO error type in sdl_set_relative_mouse_mode (same lean_mk_io_user_error issue fixed in the earlier commit). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e3dcc8da14
commit
3ec33e9a27
@@ -652,15 +652,19 @@ lean_obj_res sdl_get_mouse_state(lean_obj_arg w) {
|
||||
mouse_cache.last_frame_tick = current_tick;
|
||||
}
|
||||
|
||||
uint64_t packed = ((uint64_t)(uint32_t)(int32_t)mouse_cache.x << 32) |
|
||||
((uint64_t)(uint32_t)(int32_t)mouse_cache.y << 16) |
|
||||
(uint64_t)mouse_cache.buttons;
|
||||
// Pack into 64 bits: X[63:32] | Y[31:16] | buttons[15:0]
|
||||
// X gets full 32 bits; Y and buttons are truncated to 16 bits each.
|
||||
int32_t ix = (int32_t)mouse_cache.x;
|
||||
int32_t iy = (int32_t)mouse_cache.y;
|
||||
uint64_t packed = ((uint64_t)(uint32_t)ix << 32) |
|
||||
((uint64_t)((uint32_t)iy & 0xFFFF) << 16) |
|
||||
((uint64_t)(mouse_cache.buttons & 0xFFFF));
|
||||
return lean_io_result_mk_ok(lean_box_uint64(packed));
|
||||
}
|
||||
|
||||
lean_obj_res sdl_set_relative_mouse_mode(b_lean_obj_arg g_window, bool enabled, lean_obj_arg w) {
|
||||
SDL_Window* window = (SDL_Window*)lean_get_external_data(g_window);
|
||||
if (window == NULL) return lean_io_result_mk_error(lean_mk_io_user_error(lean_mk_string("C: Window is NULL")));
|
||||
if (window == NULL) return lean_io_result_mk_error(lean_mk_string("C: Window is NULL"));
|
||||
int32_t result = SDL_SetWindowRelativeMouseMode(window, enabled);
|
||||
mouse_cache.relative_mode = enabled;
|
||||
mouse_cache.last_frame_tick = 0; // Force refresh
|
||||
|
||||
Reference in New Issue
Block a user