2016-09-24 10:41:12 +01:00
|
|
|
/**
|
|
|
|
|
* Copyright (c) 2016 rxi
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or modify it
|
|
|
|
|
* under the terms of the MIT license. See LICENSE for details.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <dos.h>
|
|
|
|
|
#include "luaobj.h"
|
|
|
|
|
#include "mouse.h"
|
|
|
|
|
|
2016-10-15 17:40:23 +01:00
|
|
|
#define BUFFER_SIZE 32
|
|
|
|
|
#define BUFFER_MASK (BUFFER_SIZE - 1)
|
|
|
|
|
|
|
|
|
|
int mouse_inited;
|
|
|
|
|
int mouse_x, mouse_y;
|
|
|
|
|
int mouse_lastX, mouse_lastY;
|
|
|
|
|
int mouse_buttonStates[MOUSE_BUTTON_MAX];
|
|
|
|
|
|
|
|
|
|
struct {
|
|
|
|
|
mouse_Event data[BUFFER_SIZE];
|
|
|
|
|
int writei, readi;
|
|
|
|
|
} mouse_events;
|
2016-09-24 10:41:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
void mouse_init(void) {
|
|
|
|
|
union REGS regs = {};
|
|
|
|
|
int86(0x33, ®s, ®s);
|
2016-10-15 17:40:23 +01:00
|
|
|
mouse_inited = regs.x.ax ? 1 : 0;
|
2016-09-24 10:41:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void mouse_update(void) {
|
2016-10-15 17:40:23 +01:00
|
|
|
if (!mouse_inited) {
|
2016-09-24 10:41:12 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Update mouse position */
|
|
|
|
|
union REGS regs = {};
|
|
|
|
|
regs.x.ax = 3;
|
|
|
|
|
int86(0x33, ®s, ®s);
|
2016-10-15 17:40:23 +01:00
|
|
|
mouse_x = regs.x.cx >> 1;
|
|
|
|
|
mouse_y = regs.x.dx;
|
|
|
|
|
|
|
|
|
|
/* Do moved event if mouse moved */
|
|
|
|
|
if (mouse_x != mouse_lastX || mouse_y != mouse_lastY) {
|
|
|
|
|
mouse_Event e;
|
|
|
|
|
e.type = MOUSE_MOVED;
|
|
|
|
|
e.x = mouse_x;
|
|
|
|
|
e.y = mouse_y;
|
|
|
|
|
e.dx = mouse_x - mouse_lastX;
|
|
|
|
|
e.dy = mouse_y - mouse_lastY;
|
|
|
|
|
mouse_events.data[mouse_events.writei++ & BUFFER_MASK] = e;
|
|
|
|
|
}
|
2016-09-24 10:41:12 +01:00
|
|
|
|
2016-10-15 17:40:23 +01:00
|
|
|
/* Update last position */
|
|
|
|
|
mouse_lastX = mouse_x;
|
|
|
|
|
mouse_lastY = mouse_y;
|
|
|
|
|
|
|
|
|
|
/* Update button states and push pressed/released events */
|
|
|
|
|
int i, t;
|
2016-09-24 10:41:12 +01:00
|
|
|
for (i = 0; i < MOUSE_BUTTON_MAX; i++) {
|
2016-10-15 17:40:23 +01:00
|
|
|
for (t = 0; t < 2; t++) {
|
|
|
|
|
memset(®s, 0, sizeof(regs));
|
|
|
|
|
regs.x.ax = 5 + t;
|
|
|
|
|
regs.x.bx = i;
|
|
|
|
|
int86(0x33, ®s, ®s);
|
|
|
|
|
if (regs.x.bx) {
|
|
|
|
|
/* Push event */
|
|
|
|
|
mouse_Event e;
|
|
|
|
|
e.type = t == 0 ? MOUSE_PRESSED : MOUSE_RELEASED;
|
|
|
|
|
e.button = i;
|
|
|
|
|
e.x = mouse_x;
|
|
|
|
|
e.y = mouse_y;
|
|
|
|
|
mouse_events.data[mouse_events.writei++ & BUFFER_MASK] = e;
|
|
|
|
|
/* Set state */
|
|
|
|
|
mouse_buttonStates[i] = t == 0 ? 1 : 0;
|
|
|
|
|
}
|
2016-09-24 10:41:12 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2016-10-15 17:40:23 +01:00
|
|
|
int mouse_poll(mouse_Event *e) {
|
|
|
|
|
retry:
|
|
|
|
|
/* Event in event buffer? Store and return */
|
|
|
|
|
if (mouse_events.readi != mouse_events.writei) {
|
|
|
|
|
*e = mouse_events.data[mouse_events.readi++ & BUFFER_MASK];
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* No events in buffer -- update; return `0` if no new events were pushed by
|
|
|
|
|
* the update */
|
|
|
|
|
mouse_update();
|
|
|
|
|
if (mouse_events.readi != mouse_events.writei) {
|
|
|
|
|
goto retry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mouse_isDown(int button) {
|
|
|
|
|
return mouse_buttonStates[button];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mouse_getX(void) {
|
|
|
|
|
return mouse_x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mouse_getY(void) {
|
|
|
|
|
return mouse_y;
|
2016-09-24 10:41:12 +01:00
|
|
|
}
|