Added event.c/h and lua binding
* Changed mouse.c to mimic keyboard.c * Changed boot.lua to use event.poll() instead of mouse/keyboard.poll() * Removed love.keyboard.poll()
This commit is contained in:
@@ -13,6 +13,23 @@ function love.boot()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Init event handlers table
|
||||
local t = {
|
||||
"mousepressed",
|
||||
"mousereleased",
|
||||
"mousemoved",
|
||||
"keypressed",
|
||||
"keyreleased",
|
||||
"textinput",
|
||||
}
|
||||
love.handlers = {}
|
||||
for i, name in ipairs(t) do
|
||||
love.handlers[name] = function(...)
|
||||
local fn = love[name]
|
||||
if fn then fn(...) end
|
||||
end
|
||||
end
|
||||
|
||||
-- Try to mount .exe file, then the first argument
|
||||
for i, v in ipairs { love.argv[1], love.argv[2] } do
|
||||
local mounted = love.filesystem.mount(v)
|
||||
@@ -48,25 +65,13 @@ function love.run()
|
||||
love.timer.step()
|
||||
|
||||
while true do
|
||||
-- Handle mouse events
|
||||
for _, e in ipairs(love.mouse.poll()) do
|
||||
if e.type == "motion" then
|
||||
if love.mousemoved then love.mousemoved(e.x, e.y, e.dx, e.dy) end
|
||||
elseif e.type == "pressed" then
|
||||
if love.mousepressed then love.mousepressed(e.x, e.y, e.button) end
|
||||
elseif e.type == "released" then
|
||||
if love.mousereleased then love.mousereleased(e.x, e.y, e.button) end
|
||||
end
|
||||
end
|
||||
-- Handle keyboard events
|
||||
for _, e in ipairs(love.keyboard.poll()) do
|
||||
if e.type == "down" then
|
||||
if love.keypressed then love.keypressed(e.key, e.code, e.isrepeat) end
|
||||
elseif e.type == "up" then
|
||||
if love.keyreleased then love.keyreleased(e.key, e.code) end
|
||||
elseif e.type == "text" then
|
||||
if love.textinput then love.textinput(e.text) end
|
||||
-- Handle events
|
||||
while 1 do
|
||||
local name, a,b,c,d = love.event.poll()
|
||||
if not name then
|
||||
break
|
||||
end
|
||||
love.handlers[name](a, b, c, d)
|
||||
end
|
||||
-- Update
|
||||
love.timer.step()
|
||||
|
||||
76
src/event.c
Normal file
76
src/event.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "event.h"
|
||||
|
||||
|
||||
const char* event_typestr(int type) {
|
||||
switch (type) {
|
||||
case EVENT_KEYBOARD_PRESSED : return "keypressed";
|
||||
case EVENT_KEYBOARD_RELEASED : return "keyreleased";
|
||||
case EVENT_KEYBOARD_TEXTINPUT : return "textinput";
|
||||
case EVENT_MOUSE_MOVED : return "mousemoved";
|
||||
case EVENT_MOUSE_PRESSED : return "mousepressed";
|
||||
case EVENT_MOUSE_RELEASED : return "mousereleased";
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
|
||||
int event_poll(event_t *e) {
|
||||
|
||||
/* Poll keyboard */
|
||||
keyboard_Event ke;
|
||||
if (keyboard_poll(&ke)) {
|
||||
if (ke.type == KEYBOARD_PRESSED || ke.type == KEYBOARD_RELEASED) {
|
||||
if (ke.type == KEYBOARD_PRESSED) {
|
||||
e->type = EVENT_KEYBOARD_PRESSED;
|
||||
} else {
|
||||
e->type = EVENT_KEYBOARD_RELEASED;
|
||||
}
|
||||
e->keyboard.key = ke.key;
|
||||
e->keyboard.isrepeat = ke.isrepeat;
|
||||
|
||||
} else if (ke.type == KEYBOARD_TEXTINPUT) {
|
||||
e->type = EVENT_KEYBOARD_TEXTINPUT;
|
||||
strcpy(e->keyboard.text, ke.text);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Poll mouse */
|
||||
mouse_Event me;
|
||||
if (mouse_poll(&me)) {
|
||||
if (me.type == MOUSE_PRESSED || me.type == MOUSE_RELEASED) {
|
||||
if (me.type == MOUSE_PRESSED) {
|
||||
e->type = EVENT_MOUSE_PRESSED;
|
||||
} else {
|
||||
e->type = EVENT_MOUSE_RELEASED;
|
||||
}
|
||||
e->mouse.button = me.button;
|
||||
e->mouse.x = me.x;
|
||||
e->mouse.y = me.y;
|
||||
e->mouse.dx = me.dx;
|
||||
e->mouse.dy = me.dy;
|
||||
|
||||
} else if (me.type == MOUSE_MOVED) {
|
||||
e->type = EVENT_MOUSE_MOVED;
|
||||
e->mouse.x = me.x;
|
||||
e->mouse.y = me.y;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* No events */
|
||||
return 0;
|
||||
}
|
||||
44
src/event.h
Normal file
44
src/event.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef EVENT_H
|
||||
#define EVENT_H
|
||||
|
||||
enum {
|
||||
EVENT_NULL,
|
||||
EVENT_KEYBOARD_PRESSED,
|
||||
EVENT_KEYBOARD_RELEASED,
|
||||
EVENT_KEYBOARD_TEXTINPUT,
|
||||
EVENT_MOUSE_MOVED,
|
||||
EVENT_MOUSE_PRESSED,
|
||||
EVENT_MOUSE_RELEASED
|
||||
};
|
||||
|
||||
typedef union {
|
||||
int type;
|
||||
|
||||
struct {
|
||||
int type;
|
||||
int x, y;
|
||||
int dx, dy;
|
||||
int button;
|
||||
} mouse;
|
||||
|
||||
struct {
|
||||
int type;
|
||||
const char *key;
|
||||
char text[64];
|
||||
int isrepeat;
|
||||
} keyboard;
|
||||
|
||||
} event_t;
|
||||
|
||||
|
||||
const char* event_typestr(int type);
|
||||
int event_poll(event_t *e);
|
||||
|
||||
#endif
|
||||
56
src/modules/l_event.c
Normal file
56
src/modules/l_event.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* 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 "luaobj.h"
|
||||
#include "event.h"
|
||||
|
||||
|
||||
int l_event_poll(lua_State *L) {
|
||||
event_t e;
|
||||
if (event_poll(&e)) {
|
||||
lua_pushstring(L, event_typestr(e.type));
|
||||
|
||||
switch(e.type) {
|
||||
case EVENT_KEYBOARD_PRESSED:
|
||||
case EVENT_KEYBOARD_RELEASED:
|
||||
lua_pushstring(L, e.keyboard.key);
|
||||
lua_pushstring(L, e.keyboard.key);
|
||||
lua_pushboolean(L, e.keyboard.isrepeat);
|
||||
return 4;
|
||||
|
||||
case EVENT_KEYBOARD_TEXTINPUT:
|
||||
lua_pushstring(L, e.keyboard.text);
|
||||
return 2;
|
||||
|
||||
case EVENT_MOUSE_MOVED:
|
||||
lua_pushnumber(L, e.mouse.x);
|
||||
lua_pushnumber(L, e.mouse.y);
|
||||
lua_pushnumber(L, e.mouse.dx);
|
||||
lua_pushnumber(L, e.mouse.dy);
|
||||
return 5;
|
||||
|
||||
case EVENT_MOUSE_PRESSED:
|
||||
case EVENT_MOUSE_RELEASED:
|
||||
lua_pushnumber(L, e.mouse.x);
|
||||
lua_pushnumber(L, e.mouse.y);
|
||||
lua_pushnumber(L, e.mouse.button);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int luaopen_event(lua_State *L) {
|
||||
luaL_Reg reg[] = {
|
||||
{ "poll", l_event_poll },
|
||||
{ 0, 0 },
|
||||
};
|
||||
luaL_newlib(L, reg);
|
||||
return 1;
|
||||
}
|
||||
@@ -29,44 +29,8 @@ int l_keyboard_isDown(lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
int l_keyboard_poll(lua_State *L) {
|
||||
lua_newtable(L);
|
||||
keyboard_Event e;
|
||||
int idx = 1;
|
||||
|
||||
while (keyboard_poll(&e)) {
|
||||
|
||||
if (e.type == KEYBOARD_PRESSED || e.type == KEYBOARD_RELEASED) {
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, e.type == KEYBOARD_PRESSED ? "down" : "up");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushnumber(L, e.code);
|
||||
lua_setfield(L, -2, "code");
|
||||
lua_pushstring(L, e.key);
|
||||
lua_setfield(L, -2, "key");
|
||||
if (e.type == KEYBOARD_PRESSED) {
|
||||
lua_pushboolean(L, e.isrepeat);
|
||||
lua_setfield(L, -2, "isrepeat");
|
||||
}
|
||||
lua_rawseti(L, -2, idx++);
|
||||
|
||||
} else if (e.type == KEYBOARD_TEXTINPUT) {
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "text");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushstring(L, e.text);
|
||||
lua_setfield(L, -2, "text");
|
||||
lua_rawseti(L, -2, idx++);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int luaopen_keyboard(lua_State *L) {
|
||||
luaL_Reg reg[] = {
|
||||
{ "poll", l_keyboard_poll },
|
||||
{ "setKeyRepeat", l_keyboard_setKeyRepeat },
|
||||
{ "isDown", l_keyboard_isDown },
|
||||
{ 0, 0 },
|
||||
|
||||
@@ -20,6 +20,7 @@ int luaopen_image(lua_State *L);
|
||||
int luaopen_quad(lua_State *L);
|
||||
int luaopen_font(lua_State *L);
|
||||
int luaopen_system(lua_State *L);
|
||||
int luaopen_event(lua_State *L);
|
||||
int luaopen_filesystem(lua_State *L);
|
||||
int luaopen_graphics(lua_State *L);
|
||||
int luaopen_timer(lua_State *L);
|
||||
@@ -52,6 +53,7 @@ int luaopen_love(lua_State *L) {
|
||||
/* Init submodules */
|
||||
struct { char *name; int (*fn)(lua_State *L); } mods[] = {
|
||||
{ "system", luaopen_system },
|
||||
{ "event", luaopen_event },
|
||||
{ "filesystem", luaopen_filesystem },
|
||||
{ "graphics", luaopen_graphics },
|
||||
{ "timer", luaopen_timer },
|
||||
|
||||
@@ -10,23 +10,20 @@
|
||||
|
||||
|
||||
int l_mouse_getPosition(lua_State *L) {
|
||||
mouse_State *state = mouse_getState();
|
||||
lua_pushinteger(L, state->x);
|
||||
lua_pushinteger(L, state->y);
|
||||
lua_pushinteger(L, mouse_getX());
|
||||
lua_pushinteger(L, mouse_getY());
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
int l_mouse_getX(lua_State *L) {
|
||||
mouse_State *state = mouse_getState();
|
||||
lua_pushinteger(L, state->x);
|
||||
lua_pushinteger(L, mouse_getX());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int l_mouse_getY(lua_State *L) {
|
||||
mouse_State *state = mouse_getState();
|
||||
lua_pushinteger(L, state->y);
|
||||
lua_pushinteger(L, mouse_getY());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -35,11 +32,10 @@ int l_mouse_isDown(lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
int res = 0;
|
||||
int i;
|
||||
mouse_State *state = mouse_getState();
|
||||
for (i = 1; i <= n; i++) {
|
||||
int idx = luaL_checknumber(L, i) - 1;
|
||||
if (idx >= 0 && idx < MOUSE_BUTTON_MAX) {
|
||||
res |= state->buttonsDown[idx];
|
||||
res |= mouse_isDown(idx);
|
||||
}
|
||||
}
|
||||
lua_pushboolean(L, res);
|
||||
@@ -47,53 +43,9 @@ int l_mouse_isDown(lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
int l_mouse_poll(lua_State *L) {
|
||||
mouse_update();
|
||||
mouse_State *state = mouse_getState();
|
||||
|
||||
int i;
|
||||
int n = 1;
|
||||
lua_newtable(L);
|
||||
|
||||
/* Add motion event if mouse moved */
|
||||
if ( state->x != state->lastX || state->y != state->lastY ) {
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "motion");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushinteger(L, state->x);
|
||||
lua_setfield(L, -2, "x");
|
||||
lua_pushinteger(L, state->y);
|
||||
lua_setfield(L, -2, "y");
|
||||
lua_pushinteger(L, state->x - state->lastX);
|
||||
lua_setfield(L, -2, "dx");
|
||||
lua_pushinteger(L, state->y - state->lastY);
|
||||
lua_setfield(L, -2, "dy");
|
||||
lua_rawseti(L, -2, n++);
|
||||
}
|
||||
|
||||
/* Add `pressed` and `released` events */
|
||||
for (i = 0; i < MOUSE_BUTTON_MAX; i++) {
|
||||
if ( state->buttonsPressed[i] || state->buttonsReleased[i] ) {
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, state->buttonsPressed[i] ? "pressed" : "released");
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushinteger(L, i + 1);
|
||||
lua_setfield(L, -2, "button");
|
||||
lua_pushinteger(L, state->x);
|
||||
lua_setfield(L, -2, "x");
|
||||
lua_pushinteger(L, state->y);
|
||||
lua_setfield(L, -2, "y");
|
||||
lua_rawseti(L, -2, n++);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int luaopen_mouse(lua_State *L) {
|
||||
luaL_Reg reg[] = {
|
||||
{ "poll", l_mouse_poll },
|
||||
{ "getPosition", l_mouse_getPosition },
|
||||
{ "getX", l_mouse_getX },
|
||||
{ "getY", l_mouse_getY },
|
||||
|
||||
113
src/mouse.c
113
src/mouse.c
@@ -11,60 +11,107 @@
|
||||
#include "luaobj.h"
|
||||
#include "mouse.h"
|
||||
|
||||
mouse_State mouse_state;
|
||||
#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;
|
||||
|
||||
|
||||
void mouse_init(void) {
|
||||
union REGS regs = {};
|
||||
int86(0x33, ®s, ®s);
|
||||
mouse_state.inited = regs.x.ax ? 1 : 0;
|
||||
mouse_inited = regs.x.ax ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
void mouse_update(void) {
|
||||
if (!mouse_state.inited) {
|
||||
if (!mouse_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update last mouse position */
|
||||
mouse_state.lastX = mouse_state.x;
|
||||
mouse_state.lastY = mouse_state.y;
|
||||
|
||||
/* Update mouse position */
|
||||
union REGS regs = {};
|
||||
regs.x.ax = 3;
|
||||
int86(0x33, ®s, ®s);
|
||||
mouse_state.x = regs.x.cx >> 1;
|
||||
mouse_state.y = regs.x.dx;
|
||||
mouse_x = regs.x.cx >> 1;
|
||||
mouse_y = regs.x.dx;
|
||||
|
||||
/* Update button states */
|
||||
int i;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Update last position */
|
||||
mouse_lastX = mouse_x;
|
||||
mouse_lastY = mouse_y;
|
||||
|
||||
/* Update button states and push pressed/released events */
|
||||
int i, t;
|
||||
for (i = 0; i < MOUSE_BUTTON_MAX; i++) {
|
||||
/* Reset pressed/released */
|
||||
mouse_state.buttonsPressed[i] = 0;
|
||||
mouse_state.buttonsReleased[i] = 0;
|
||||
/* Handle mouse pressed */
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.x.ax = 5;
|
||||
regs.x.bx = i;
|
||||
int86(0x33, ®s, ®s);
|
||||
if (regs.x.bx) {
|
||||
mouse_state.buttonsPressed[i] = 1;
|
||||
mouse_state.buttonsDown[i] = 1;
|
||||
}
|
||||
/* Handle mouse released */
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.x.ax = 6;
|
||||
regs.x.bx = i;
|
||||
int86(0x33, ®s, ®s);
|
||||
if (regs.x.bx) {
|
||||
mouse_state.buttonsReleased[i] = 1;
|
||||
mouse_state.buttonsDown[i] = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mouse_State* mouse_getState(void) {
|
||||
return &mouse_state;
|
||||
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;
|
||||
}
|
||||
|
||||
25
src/mouse.h
25
src/mouse.h
@@ -5,20 +5,27 @@ enum {
|
||||
MOUSE_BUTTON_LEFT,
|
||||
MOUSE_BUTTON_RIGHT,
|
||||
MOUSE_BUTTON_MIDDLE,
|
||||
MOUSE_BUTTON_MAX,
|
||||
MOUSE_BUTTON_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
MOUSE_PRESSED,
|
||||
MOUSE_RELEASED,
|
||||
MOUSE_MOVED
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int inited;
|
||||
int type;
|
||||
int x, y;
|
||||
int lastX, lastY;
|
||||
int buttonsPressed[MOUSE_BUTTON_MAX];
|
||||
int buttonsReleased[MOUSE_BUTTON_MAX];
|
||||
int buttonsDown[MOUSE_BUTTON_MAX];
|
||||
} mouse_State;
|
||||
int dx, dy;
|
||||
int button;
|
||||
} mouse_Event;
|
||||
|
||||
|
||||
void mouse_init(void);
|
||||
void mouse_update(void);
|
||||
mouse_State* mouse_getState(void);
|
||||
int mouse_poll(mouse_Event *e);
|
||||
int mouse_isDown(int button);
|
||||
int mouse_getX(void);
|
||||
int mouse_getY(void);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user