diff options
author | Javier <dev.git@javispedro.com> | 2022-04-08 03:07:53 +0200 |
---|---|---|
committer | Javier <dev.git@javispedro.com> | 2022-04-08 03:07:53 +0200 |
commit | 0f6414cb3f8afa2012f6567e2fbfe844b8bd4b78 (patch) | |
tree | 4e96753e0af164b97a38cc5667100144501e2c2e | |
parent | 98a343355c3459b892792585788069bac3bc40e7 (diff) | |
download | vbados-0f6414cb3f8afa2012f6567e2fbfe844b8bd4b78.tar.gz vbados-0f6414cb3f8afa2012f6567e2fbfe844b8bd4b78.zip |
snap mouse position to character grid on text modes
-rw-r--r-- | dosmain.c | 4 | ||||
-rw-r--r-- | dostsr.c | 39 | ||||
-rw-r--r-- | dostsr.h | 3 |
3 files changed, 37 insertions, 9 deletions
@@ -383,7 +383,7 @@ static __declspec(aborts) int install_driver(LPTSRDATA data, bool high) static bool check_if_driver_uninstallable(LPTSRDATA data) { void (__interrupt __far *cur_int33_handler)() = _dos_getvect(0x33); - void (__interrupt __far *our_int33_handler)() = MK_FP(FP_SEG(data), FP_OFF(int33_isr)); + void (__interrupt __far *our_int33_handler)() = data:>int33_isr; if (cur_int33_handler != our_int33_handler) { fprintf(stderr, "INT33 has been hooked by someone else, removing anyway\n"); @@ -393,7 +393,7 @@ static bool check_if_driver_uninstallable(LPTSRDATA data) #if USE_WIN386 { void (__interrupt __far *cur_int2f_handler)() = _dos_getvect(0x2f); - void (__interrupt __far *our_int2f_handler)() = MK_FP(FP_SEG(data), FP_OFF(int2f_isr)); + void (__interrupt __far *our_int2f_handler)() = data:>int2f_isr; if (cur_int2f_handler != our_int2f_handler) { fprintf(stderr, "INT2F has been hooked by someone else, removing anyway\n"); @@ -54,6 +54,14 @@ static void bound_position_to_window(void) if (data.pos.y > data.max.y) data.pos.y = data.max.y; } +/** Constraints coordinate value to the desired granularity, + * which must be a power of two. */ +static inline int16_t snap_to_grid(int16_t val, int16_t granularity) +{ + // Build a bitmask that masks away the undesired low-order bits + return val & (-granularity); +} + static void hide_text_cursor(void) { // Restore the character under the old position of the cursor @@ -476,6 +484,8 @@ static void reload_video_info(void) data.screen_max.y = data.video_mode.pixels_height - 1; data.screen_scale.x = 1; data.screen_scale.y = 1; + data.screen_granularity.x = 1; + data.screen_granularity.y = 1; // The actual range of coordinates expected by int33 clients // is, for some reason, different than real resolution in some modes. @@ -485,6 +495,14 @@ static void reload_video_info(void) data.screen_scale.x = 640 / 320; } + // In text modes, we are supposed to always round the mouse cursor + // to character boundaries. + if (data.video_mode.type == VIDEO_TEXT) { + // Always assume 8x8 character size irregardless of true font + data.screen_granularity.x = 8; + data.screen_granularity.y = 8; + } + dlog_print("Current video mode="); dlog_printx(data.video_mode.mode); dlog_print(" screen_max="); @@ -656,6 +674,10 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, in events |= INT33_EVENT_MASK_WHEEL_MOVEMENT; // Higher byte of buttons contains wheel movement buttons |= (z & 0xFF) << 8; + // Accumulate delta wheel movement + data.wheel_delta += z; + data.wheel_last.x = data.pos.x; + data.wheel_last.y = data.pos.y; } // Update button status @@ -683,8 +705,11 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, in events &= data.event_mask; if (data.event_handler && events) { + x = snap_to_grid(data.pos.x, data.screen_granularity.x); + y = snap_to_grid(data.pos.y, data.screen_granularity.y); + call_event_handler(data.event_handler, events, - buttons, data.pos.x, data.pos.y, data.delta.x, data.delta.y); + buttons, x, y, data.delta.x, data.delta.y); } } @@ -989,8 +1014,8 @@ static void reset_mouse_state() static void return_clear_wheel_counter(union INTPACK __far *r) { - r->x.cx = data.wheel_last.x; - r->x.dx = data.wheel_last.y; + r->x.cx = snap_to_grid(data.wheel_last.x, data.screen_granularity.x); + r->x.dx = snap_to_grid(data.wheel_last.y, data.screen_granularity.y); r->x.bx = data.wheel_delta; data.wheel_last.x = 0; data.wheel_last.y = 0; @@ -999,8 +1024,8 @@ static void return_clear_wheel_counter(union INTPACK __far *r) static void return_clear_button_counter(union INTPACK __far *r, struct buttoncounter *c) { - r->x.cx = c->last.x; - r->x.dx = c->last.y; + r->x.cx = snap_to_grid(c->last.x, data.screen_granularity.x); + r->x.dx = snap_to_grid(c->last.y, data.screen_granularity.y); r->x.bx = c->count; c->last.x = 0; c->last.y = 0; @@ -1033,8 +1058,8 @@ static void int33_handler(union INTPACK r) #if TRACE_EVENTS dlog_puts("Mouse get position"); #endif - r.x.cx = data.pos.x; - r.x.dx = data.pos.y; + r.x.cx = snap_to_grid(data.pos.x, data.screen_granularity.x); + r.x.dx = snap_to_grid(data.pos.y, data.screen_granularity.y); r.x.bx = data.buttons; if (data.haswheel) { r.h.bh = data.wheel_delta; @@ -85,6 +85,9 @@ typedef struct tsrdata { * physical screen coordinates. * real coordinates = virtual coordinates * screen_scale. */ struct point screen_scale; + /** In text modes, we want to snap the cursor position to the cell grid. + * This stores the desired grid granularity. */ + struct point screen_granularity; // Detected mouse hardware /** Whether the current mouse has a wheel (and support is enabled). */ |