/* * mouse.h — Sprinter mouse driver (RST 30h). * * The driver is installed in the system shell. After a successful * mouse_init(), the driver tracks the hardware and you can query state * or move/show/hide the cursor on demand. * * coordinate units: * READ_STATE / GOTO take pixel coordinates. In text mode 03h * (80x32) divide x by 8 and y by 8 (NOT 16) to get char-cell * position. * * buttons bitmask: * bit 0 = left, bit 1 = right */ #ifndef MOUSE_H #define MOUSE_H #include typedef struct { uint16_t x; /* pixel coordinate */ uint16_t y; /* pixel coordinate */ uint8_t buttons; /* bit 0 = left, bit 1 = right */ } mouse_state_t; int mouse_init (void); /* 0 OK, -1 if no driver */ void mouse_show (void); void mouse_hide (void); void mouse_refresh(void); void mouse_read (mouse_state_t *st); void mouse_goto (int x, int y); void mouse_bounds_x(int xmin, int xmax); void mouse_bounds_y(int ymin, int ymax); /* Text-mode cursor shape (function $0A). * sym_and / sym_xor — character glyph mask * attr_and / attr_xor — attribute byte mask * Default cursor is XOR'd inverse video at the cell. */ void mouse_text_cursor(uint8_t sym_and, uint8_t sym_xor, uint8_t attr_and, uint8_t attr_xor); /* ---- Graphics-mode cursor image (functions $09 / $0B) ----------- * * The driver accepts an opaque bitmap for the cursor in graphics modes. * Doc does not specify the byte layout — empirically size = width*height * bytes (1 byte per pixel for 256-colour mode, presumably packed nibbles * for 16-colour mode). hot_x / hot_y mark the "click point" within the * cursor image (0,0 = top-left). */ typedef struct { const void *image; /* bitmap data */ uint8_t width; uint8_t height; uint8_t hot_x; uint8_t hot_y; } mouse_cursor_t; void mouse_load_cursor(const mouse_cursor_t *c); /* Read back the current cursor. * c->image must point to a buffer large enough to hold width*height bytes. * width, height, hot_x, hot_y are written by the driver. */ void mouse_get_cursor(mouse_cursor_t *c); /* ---- Sensitivity (functions $0E / $0F) ------------------------- * * Verified empirically (2026-05-31): the value is a DIVIDER — the * driver counts that many raw hardware steps from the mouse before * advancing the cursor by one screen pixel. So **smaller value = more * sensitive** (cursor moves faster), and larger value = slower cursor. * (The doc statement "higher = less movement needed" appears to be * inverted.) Useful starting point: 2 on both axes. */ uint8_t mouse_get_sensitivity_x(void); uint8_t mouse_get_sensitivity_y(void); void mouse_set_sensitivity(uint8_t horz, uint8_t vert); /* ---- Solid-C compatibility ------------------------------------- * * Solid-C uses shorter `ms_*` names + typed state structs. The semantics * are identical to our `mouse_*` API. */ #define LEFT_BUTTON 1 #define RIGHT_BUTTON 2 /* MSGSTAT mirrors mouse_state_t — same field order and types. */ typedef mouse_state_t MSGSTAT; #define ms_init mouse_init #define ms_show mouse_show #define ms_hide mouse_hide #define ms_ref mouse_refresh #define ms_xbnd mouse_bounds_x #define ms_ybnd mouse_bounds_y #define ms_spos mouse_goto #define mssgpos mouse_goto #define ms_tcur mouse_text_cursor #define ms_scur mouse_load_cursor #define ms_gcur mouse_get_cursor #define ms_vmod mouse_video_mode_changed #define ms_ssen mouse_set_sensitivity #define msgstat(st) mouse_read((st)) /* ---- $81 CHANGE VIDEO MODE ------------------------------------- * * Call after changing the video mode (set_videotextmode or gfx_init) so * the driver re-syncs its internal coordinate ranges and cursor image. * * `mode` is the byte you switched to — TEXT_MODE_* (from ) or * GFX_MODE_* (from ), e.g. 0x03 for 80×32 text or 0x81 for * 320×256×256. The driver REQUIRES the new mode in register A — * passing garbage leaves the cursor mis-configured (text-mode XOR * pattern applied in graphics, etc.). */ void mouse_video_mode_changed(uint8_t mode); #endif