aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2022-04-08 03:07:53 +0200
committerJavier <dev.git@javispedro.com>2022-04-08 03:07:53 +0200
commit0f6414cb3f8afa2012f6567e2fbfe844b8bd4b78 (patch)
tree4e96753e0af164b97a38cc5667100144501e2c2e
parent98a343355c3459b892792585788069bac3bc40e7 (diff)
downloadvbados-0f6414cb3f8afa2012f6567e2fbfe844b8bd4b78.tar.gz
vbados-0f6414cb3f8afa2012f6567e2fbfe844b8bd4b78.zip
snap mouse position to character grid on text modes
-rw-r--r--dosmain.c4
-rw-r--r--dostsr.c39
-rw-r--r--dostsr.h3
3 files changed, 37 insertions, 9 deletions
diff --git a/dosmain.c b/dosmain.c
index 5e789a9..18120a8 100644
--- a/dosmain.c
+++ b/dosmain.c
@@ -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");
diff --git a/dostsr.c b/dostsr.c
index f0dc0ca..f3d199e 100644
--- a/dostsr.c
+++ b/dostsr.c
@@ -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;
diff --git a/dostsr.h b/dostsr.h
index 50d4441..b3a5b3c 100644
--- a/dostsr.h
+++ b/dostsr.h
@@ -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). */