2018-04-28 11:30:53 -04:00
|
|
|
#include "dglmouse.h"
|
2020-07-19 19:24:48 -04:00
|
|
|
#include "dgl.h"
|
2018-05-21 14:48:22 -04:00
|
|
|
#include "dglevent.h"
|
2018-04-28 11:30:53 -04:00
|
|
|
#include <string.h>
|
|
|
|
#include <dos.h>
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
static bool _installed = false;
|
|
|
|
static bool _has_mouse = false;
|
2018-04-28 11:30:53 -04:00
|
|
|
|
2018-05-21 14:48:22 -04:00
|
|
|
static INPUTEVENT *mouse_event;
|
|
|
|
|
2018-04-28 11:30:53 -04:00
|
|
|
volatile int mouse_x;
|
|
|
|
volatile int mouse_y;
|
|
|
|
volatile int mouse_buttons;
|
|
|
|
volatile int mouse_delta_x;
|
|
|
|
volatile int mouse_delta_y;
|
2018-05-21 14:48:22 -04:00
|
|
|
volatile int mouse_prev_buttons;
|
2018-04-28 11:30:53 -04:00
|
|
|
|
|
|
|
static void reset_mouse_state(void) {
|
|
|
|
mouse_x = 0;
|
|
|
|
mouse_y = 0;
|
|
|
|
mouse_buttons = 0;
|
|
|
|
mouse_delta_x = 0;
|
|
|
|
mouse_delta_y = 0;
|
2018-05-21 14:48:22 -04:00
|
|
|
mouse_prev_buttons = 0;
|
2018-04-28 11:30:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
static bool init_mouse_driver(void) {
|
2018-04-28 11:30:53 -04:00
|
|
|
union REGS regs;
|
|
|
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
regs.w.ax = 0x00;
|
|
|
|
int386(0x33, ®s, ®s);
|
|
|
|
|
|
|
|
return (regs.w.ax != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void update_mouse_state(void) {
|
|
|
|
union REGS regs;
|
|
|
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
regs.w.ax = 0x03;
|
|
|
|
int386(0x33, ®s, ®s);
|
|
|
|
mouse_x = (regs.w.cx / 2);
|
|
|
|
mouse_y = regs.w.dx;
|
2018-05-21 14:48:22 -04:00
|
|
|
mouse_prev_buttons = mouse_buttons;
|
2018-04-28 11:30:53 -04:00
|
|
|
mouse_buttons = regs.w.bx;
|
|
|
|
mouse_delta_x = 0;
|
|
|
|
mouse_delta_y = 0;
|
|
|
|
}
|
|
|
|
|
2018-05-21 14:48:22 -04:00
|
|
|
static void push_motion_event(void) {
|
|
|
|
_events_push(&mouse_event);
|
|
|
|
mouse_event->type = EVENT_TYPE_MOUSE_MOTION;
|
|
|
|
mouse_event->mouse_motion.x = mouse_x;
|
|
|
|
mouse_event->mouse_motion.y = mouse_y;
|
|
|
|
mouse_event->mouse_motion.x_delta = mouse_delta_x;
|
|
|
|
mouse_event->mouse_motion.y_delta = mouse_delta_y;
|
|
|
|
mouse_event->mouse_motion.buttons = mouse_buttons;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void push_button_event(EVENT_ACTION action, MOUSE_BUTTON button) {
|
|
|
|
_events_push(&mouse_event);
|
|
|
|
mouse_event->type = EVENT_TYPE_MOUSE_BUTTON;
|
|
|
|
mouse_event->mouse_button.x = mouse_x;
|
|
|
|
mouse_event->mouse_button.y = mouse_y;
|
|
|
|
mouse_event->mouse_button.action = action;
|
|
|
|
mouse_event->mouse_button.button = button;
|
|
|
|
}
|
|
|
|
|
2018-04-28 11:30:53 -04:00
|
|
|
#pragma off (check_stack)
|
|
|
|
void __loadds far mouse_int_handler(int eax, int ebx, int ecx, int edx) {
|
|
|
|
#pragma aux mouse_int_handler parm [eax] [ebx] [ecx] [edx]
|
|
|
|
mouse_delta_x = (ecx / 2) - mouse_x;
|
|
|
|
mouse_delta_y = edx - mouse_y;
|
|
|
|
mouse_x = (ecx / 2);
|
|
|
|
mouse_y = edx;
|
2018-05-21 14:48:22 -04:00
|
|
|
mouse_prev_buttons = mouse_buttons;
|
2018-04-28 11:30:53 -04:00
|
|
|
mouse_buttons = ebx;
|
2018-05-21 14:48:22 -04:00
|
|
|
|
|
|
|
if (_events_enabled) {
|
|
|
|
if (mouse_delta_x || mouse_delta_y) {
|
|
|
|
push_motion_event();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mouse_buttons != mouse_prev_buttons) {
|
|
|
|
if ((mouse_buttons & MOUSE_LEFTBUTTON) !=
|
|
|
|
(mouse_prev_buttons & MOUSE_LEFTBUTTON)) {
|
|
|
|
if (mouse_buttons & MOUSE_LEFTBUTTON)
|
|
|
|
push_button_event(EVENT_ACTION_PRESSED, MOUSE_LEFTBUTTON);
|
|
|
|
else
|
|
|
|
push_button_event(EVENT_ACTION_RELEASED, MOUSE_LEFTBUTTON);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mouse_buttons & MOUSE_RIGHTBUTTON) !=
|
|
|
|
(mouse_prev_buttons & MOUSE_RIGHTBUTTON)) {
|
|
|
|
if (mouse_buttons & MOUSE_RIGHTBUTTON)
|
|
|
|
push_button_event(EVENT_ACTION_PRESSED, MOUSE_RIGHTBUTTON);
|
|
|
|
else
|
|
|
|
push_button_event(EVENT_ACTION_RELEASED, MOUSE_RIGHTBUTTON);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mouse_buttons & MOUSE_CENTERBUTTON) !=
|
|
|
|
(mouse_prev_buttons & MOUSE_CENTERBUTTON)) {
|
|
|
|
if (mouse_buttons & MOUSE_CENTERBUTTON)
|
|
|
|
push_button_event(EVENT_ACTION_PRESSED, MOUSE_CENTERBUTTON);
|
|
|
|
else
|
|
|
|
push_button_event(EVENT_ACTION_RELEASED, MOUSE_CENTERBUTTON);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-04-28 11:30:53 -04:00
|
|
|
}
|
|
|
|
#pragma on (check_stack)
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
bool mouse_init(void) {
|
2018-04-28 11:30:53 -04:00
|
|
|
union REGS regs;
|
|
|
|
struct SREGS sregs;
|
|
|
|
|
|
|
|
if (_installed) {
|
|
|
|
dgl_set_error(DGL_MOUSE_ALREADY_INITIALIZED);
|
2020-07-19 19:24:48 -04:00
|
|
|
return false;
|
2018-04-28 11:30:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
reset_mouse_state();
|
|
|
|
|
|
|
|
_has_mouse = init_mouse_driver();
|
|
|
|
if (!_has_mouse) {
|
2020-07-19 19:24:48 -04:00
|
|
|
_installed = true;
|
|
|
|
return true;
|
2018-04-28 11:30:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
update_mouse_state();
|
|
|
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
memset(&sregs, 0, sizeof(sregs));
|
|
|
|
regs.w.ax = 0x0c;
|
|
|
|
regs.w.cx = 31;
|
|
|
|
regs.x.edx = FP_OFF(mouse_int_handler);
|
|
|
|
sregs.es = FP_SEG(mouse_int_handler);
|
|
|
|
int386x(0x33, ®s, ®s, &sregs);
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
_installed = true;
|
|
|
|
return true;
|
2018-04-28 11:30:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
bool mouse_shutdown(void) {
|
2018-04-28 11:30:53 -04:00
|
|
|
union REGS regs;
|
|
|
|
|
|
|
|
if (!_installed)
|
2020-07-19 19:24:48 -04:00
|
|
|
return true; // don't care
|
2018-04-28 11:30:53 -04:00
|
|
|
|
|
|
|
if (!_has_mouse) {
|
2020-07-19 19:24:48 -04:00
|
|
|
_installed = false;
|
|
|
|
return true;
|
2018-04-28 11:30:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
regs.w.ax = 0x0c;
|
|
|
|
regs.w.cx = 0;
|
|
|
|
int386(0x33, ®s, ®s);
|
|
|
|
|
|
|
|
reset_mouse_state();
|
|
|
|
init_mouse_driver();
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
_installed = false;
|
|
|
|
return true;
|
2018-04-28 11:30:53 -04:00
|
|
|
}
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
bool mouse_is_initialized(void) {
|
2018-04-28 11:30:53 -04:00
|
|
|
return _installed;
|
|
|
|
}
|
|
|
|
|
2020-07-19 19:24:48 -04:00
|
|
|
bool mouse_is_present(void) {
|
2018-04-28 11:30:53 -04:00
|
|
|
return _has_mouse;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mouse_show(void) {
|
|
|
|
union REGS regs;
|
|
|
|
|
|
|
|
if (!_has_mouse)
|
|
|
|
return;
|
|
|
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
regs.w.ax = 0x01;
|
|
|
|
int386(0x33, ®s, ®s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mouse_hide(void) {
|
|
|
|
union REGS regs;
|
|
|
|
|
|
|
|
if (!_has_mouse)
|
|
|
|
return;
|
|
|
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
regs.w.ax = 0x02;
|
|
|
|
int386(0x33, ®s, ®s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mouse_set_bounds(int min_x, int min_y, int max_x, int max_y) {
|
|
|
|
union REGS regs;
|
|
|
|
|
|
|
|
if (!_has_mouse)
|
|
|
|
return;
|
|
|
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
|
|
|
|
regs.w.ax = 0x07;
|
|
|
|
regs.w.cx = min_x;
|
|
|
|
regs.w.dx = max_x;
|
|
|
|
int386(0x33, ®s, ®s);
|
|
|
|
|
|
|
|
regs.w.ax = 0x08;
|
|
|
|
regs.w.cx = min_y;
|
|
|
|
regs.w.dx = max_y;
|
|
|
|
int386(0x33, ®s, ®s);
|
|
|
|
}
|
|
|
|
|