aboutsummaryrefslogtreecommitdiff
path: root/dostsr.c
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2022-04-08 02:17:46 +0200
committerJavier <dev.git@javispedro.com>2022-04-08 02:17:46 +0200
commit98a343355c3459b892792585788069bac3bc40e7 (patch)
tree1ff4674815775c323822e03c3c0f05c49204a549 /dostsr.c
parentdb308ca65b8f0ddb61969e7e4b4fb2145d8a27c2 (diff)
downloadvbados-98a343355c3459b892792585788069bac3bc40e7.tar.gz
vbados-98a343355c3459b892792585788069bac3bc40e7.zip
try to detect video mode changes
Diffstat (limited to 'dostsr.c')
-rw-r--r--dostsr.c112
1 files changed, 84 insertions, 28 deletions
diff --git a/dostsr.c b/dostsr.c
index 8f6bf04..f0dc0ca 100644
--- a/dostsr.c
+++ b/dostsr.c
@@ -467,21 +467,9 @@ static void load_cursor(void)
#endif
}
-/** Refreshes the information about the current video mode. */
-static void refresh_video_info(void)
+/** Reloads the information about the current video mode. */
+static void reload_video_info(void)
{
- uint8_t cur_mode = bda_get_video_mode() & ~0x80;
- bool mode_change = cur_mode != data.video_mode.mode;
-
- if (mode_change && data.cursor_visible) {
- // Assume cursor is lost
- data.cursor_visible = false;
- }
-
- dlog_print("Current video mode=");
- dlog_printx(cur_mode);
- dlog_endline();
-
get_current_video_mode_info(&data.video_mode);
data.screen_max.x = data.video_mode.pixels_width - 1;
@@ -496,6 +484,53 @@ static void refresh_video_info(void)
data.screen_max.x = 640 - 1;
data.screen_scale.x = 640 / 320;
}
+
+ dlog_print("Current video mode=");
+ dlog_printx(data.video_mode.mode);
+ dlog_print(" screen_max=");
+ dlog_printd(data.screen_max.x);
+ dlog_putc(',');
+ dlog_printd(data.screen_max.y);
+ dlog_endline();
+}
+
+/** True if the current video is different from what we have stored
+ * and we probably need to recompute video mode info. */
+static inline bool video_mode_changed(void)
+{
+ uint8_t cur_mode = bda_get_video_mode() & ~0x80;
+
+ if (cur_mode != data.video_mode.mode)
+ return true;
+
+ if (data.video_mode.type == VIDEO_TEXT) {
+ // Also check to see if the font size was changed..
+ return data.video_mode.pixels_height != (bda_get_last_row()+1) * 8;
+ } else {
+ return false;
+ }
+}
+
+/** Checks if the video mode has changed and if so
+ * refreshes the information about the current video mode. */
+static void refresh_video_info(void)
+{
+ if (video_mode_changed()) {
+ if (data.cursor_visible) {
+ // Assume cursor is lost with no way to restore prev contents
+ data.cursor_visible = false;
+ }
+
+ reload_video_info();
+
+ if (data.video_mode.type != VIDEO_UNKNOWN) {
+ // If we know the screen size for this mode, then reset the window to it
+ data.min.x = 0;
+ data.min.y = 0;
+ data.max.x = data.screen_max.x;
+ data.max.y = data.screen_max.y;
+ }
+ }
}
/** Calls the application-registered event handler. */
@@ -569,10 +604,14 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, in
// Programs that expect relative movement data
// will almost never set a mickeyPerPixel value.
// So all we can do is guess.
- data.delta.x += (x - data.pos.x) * 8;
- data.delta.y += (y - data.pos.y) * 8;
+ if (data.abs_pos.x >= 0 && data.abs_pos.y >= 0) {
+ data.delta.x += (x - data.abs_pos.x) * 8;
+ data.delta.y += (y - data.abs_pos.y) * 8;
+ }
+ data.abs_pos.x = x;
+ data.abs_pos.y = y;
- // Store the new absolute position
+ // Set the new absolute position
data.pos.x = x;
data.pos.y = y;
data.pos_frac.x = 0;
@@ -603,6 +642,8 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, in
data.delta.y += y;
data.delta_frac.x = 0;
data.delta_frac.y = 0;
+ data.abs_pos.x = -1;
+ data.abs_pos.y = -1;
// Convert mickeys into pixels
data.pos.x += scalei_rem(x, data.mickeysPerLine.x, 8, &data.pos_frac.x);
@@ -704,6 +745,7 @@ static void ps2_mouse_handler(uint16_t word1, uint16_t word2, uint16_t word3, ui
if ((vbox_get_mouse(&data.vb, &abs, &vbx, &vby) == 0) && abs) {
// VirtualBox gives unsigned coordinates from 0...0xFFFFU,
// scale to 0..screen_size (in pixels).
+ refresh_video_info();
// If the user is using a window larger than the screen, use it.
x = scaleu(vbx, 0xFFFFU, MAX(data.max.x, data.screen_max.x));
y = scaleu(vby, 0xFFFFU, MAX(data.max.y, data.screen_max.y));
@@ -757,10 +799,12 @@ static void ps2_mouse_handler(uint16_t word1, uint16_t word2, uint16_t word3, ui
z = (int8_t) (uint8_t) vmw.z;
} else {
abs = true;
+ // Scale to screen coordinates
+ refresh_video_info();
x = scaleu(vmw.x & 0xFFFFU, 0xFFFFU,
- MAX(data.max.x, data.screen_max.x));
+ MAX(data.max.x, data.screen_max.x));
y = scaleu(vmw.y & 0xFFFFU, 0xFFFFU,
- MAX(data.max.y, data.screen_max.y));
+ MAX(data.max.y, data.screen_max.y));
z = (int8_t) (uint8_t) vmw.z;
}
@@ -924,6 +968,8 @@ static void reset_mouse_state()
data.delta.y = 0;
data.delta_frac.x = 0;
data.delta_frac.y = 0;
+ data.abs_pos.x = -1;
+ data.abs_pos.y = -1;
data.buttons = 0;
for (i = 0; i < NUM_BUTTONS; i++) {
data.button[i].pressed.count = 0;
@@ -968,7 +1014,7 @@ static void int33_handler(union INTPACK r)
switch (r.x.ax) {
case INT33_RESET_MOUSE:
dlog_puts("Mouse reset");
- refresh_video_info();
+ reload_video_info();
reset_mouse_settings();
reset_mouse_hardware();
reset_mouse_state();
@@ -984,6 +1030,9 @@ static void int33_handler(union INTPACK r)
refresh_cursor();
break;
case INT33_GET_MOUSE_POSITION:
+#if TRACE_EVENTS
+ dlog_puts("Mouse get position");
+#endif
r.x.cx = data.pos.x;
r.x.dx = data.pos.y;
r.x.bx = data.buttons;
@@ -993,6 +1042,9 @@ static void int33_handler(union INTPACK r)
}
break;
case INT33_SET_MOUSE_POSITION:
+#if TRACE_EVENTS
+ dlog_puts("Mouse set position");
+#endif
data.pos.x = r.x.cx;
data.pos.y = r.x.dx;
data.pos_frac.x = 0;
@@ -1073,14 +1125,13 @@ static void int33_handler(union INTPACK r)
refresh_cursor();
break;
case INT33_GET_MOUSE_MOTION:
+#if TRACE_EVENTS
+ dlog_puts("Mouse get motion");
+#endif
r.x.cx = data.delta.x;
r.x.dx = data.delta.y;
data.delta.x = 0;
data.delta.y = 0;
-#if USE_VIRTUALBOX
- // Likely this means we need a relative mouse, or we will get out of sync
- //if (data.vbabs) enable_vbox_absolute(false);
-#endif
break;
case INT33_SET_EVENT_HANDLER:
dlog_puts("Mouse set event handler");
@@ -1143,7 +1194,7 @@ static void int33_handler(union INTPACK r)
break;
case INT33_RESET_SETTINGS:
dlog_puts("Mouse reset settings");
- refresh_video_info();
+ reload_video_info();
reset_mouse_settings();
reset_mouse_state();
r.x.ax = INT33_MOUSE_FOUND;
@@ -1160,8 +1211,9 @@ static void int33_handler(union INTPACK r)
r.h.cl = 0;
break;
case INT33_GET_MAX_COORDINATES:
- r.x.cx = data.screen_max.x;
- r.x.dx = data.screen_max.y;
+ r.x.bx = 0;
+ r.x.cx = MAX(data.screen_max.x, data.max.x);
+ r.x.dx = MAX(data.screen_max.y, data.max.y);
break;
case INT33_GET_WINDOW:
r.x.ax = data.min.x;
@@ -1169,11 +1221,15 @@ static void int33_handler(union INTPACK r)
r.x.cx = data.max.x;
r.x.dx = data.max.y;
break;
+#if USE_WHEEL
+ // Wheel API extensions:
case INT33_GET_CAPABILITIES:
r.x.ax = INT33_WHEEL_API_MAGIC; // Driver supports wheel API
r.x.bx = 0;
r.x.cx = data.haswheel ? INT33_CAPABILITY_MOUSE_API : 0;
break;
+#endif
+ // Our internal API extensions:
case INT33_GET_TSR_DATA:
dlog_puts("Get TSR data");
r.x.es = FP_SEG(&data);
@@ -1333,7 +1389,7 @@ static LPTSRDATA int33_get_tsr_data(void);
"xor ax, ax" \
"mov es, ax" \
"mov di, ax" \
- "mov ax, 0x7f" \
+ "mov ax, 0x73" \
"int 0x33" \
__value [es di] \
__modify [ax]