mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-23 19:01:06 +00:00
[qwaq] Implement an event queue
It seems to have an issue with a bogus clearing of the screen, but the basics seem to be working.
This commit is contained in:
parent
b4aebc120e
commit
08bf8a04e4
3 changed files with 128 additions and 4 deletions
25
tools/qwaq/event.h
Normal file
25
tools/qwaq/event.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef __qwaq_event_h
|
||||
#define __qwaq_event_h
|
||||
|
||||
typedef enum {
|
||||
qe_idle,
|
||||
qe_key,
|
||||
qe_mouse,
|
||||
} qwaq_etype;
|
||||
|
||||
// right now, this is just a copy of ncurses MEVENT, but all int
|
||||
typedef struct qwaq_mevent_s {
|
||||
int id; // XXX does it matter?
|
||||
int x, y, z; // z? what?
|
||||
int buttons;
|
||||
} qwaq_mevent_t;
|
||||
|
||||
typedef struct qwaq_event_s {
|
||||
qwaq_etype event_type;
|
||||
union {
|
||||
int key;
|
||||
qwaq_mevent_t mouse;
|
||||
} e;
|
||||
} qwaq_event_t;
|
||||
|
||||
#endif//__qwaq_event_h
|
|
@ -1,3 +1,5 @@
|
|||
#include "event.h"
|
||||
|
||||
typedef struct window_s *window_t;
|
||||
|
||||
void initialize (void) = #0;
|
||||
|
@ -6,17 +8,32 @@ void destroy_window (window_t win) = #0;
|
|||
void wprintf (window_t win, string fmt, ...) = #0;
|
||||
int wgetch (window_t win) = #0;
|
||||
|
||||
void process_input (void) = #0;
|
||||
int get_event (qwaq_event_t *event) = #0;
|
||||
|
||||
int main (int argc, string *argv)
|
||||
{
|
||||
int ch;
|
||||
int ch = 0;
|
||||
qwaq_event_t event = { };
|
||||
|
||||
initialize ();
|
||||
window_t win = create_window (20, 5, 50, 10);
|
||||
wprintf (win, "Hi there!\n");
|
||||
do {
|
||||
ch = wgetch (win);
|
||||
if (ch) {
|
||||
wprintf (win, "%d\n", ch);
|
||||
process_input ();
|
||||
|
||||
if (get_event (&event)) {
|
||||
if (event.event_type == qe_key) {
|
||||
ch = event.e.key;
|
||||
wprintf (win, "key: %d\n", ch);
|
||||
} else if (event.event_type == qe_mouse) {
|
||||
wprintf (win, "mouse: %d %d %d %d %d\n",
|
||||
event.e.mouse.id,
|
||||
event.e.mouse.x,
|
||||
event.e.mouse.y,
|
||||
event.e.mouse.z,
|
||||
event.e.mouse.buttons);
|
||||
}
|
||||
}
|
||||
} while (ch != 27);
|
||||
return 0;
|
||||
|
|
|
@ -40,8 +40,11 @@
|
|||
#include "QF/sys.h"
|
||||
|
||||
#include "qwaq.h"
|
||||
#include "event.h"
|
||||
|
||||
#define always_inline inline __attribute__((__always_inline__))
|
||||
#define QUEUE_SIZE 16 // must be power of 2 greater than 1
|
||||
#define QUEUE_MASK (QUEUE_SIZE - 1)
|
||||
|
||||
typedef struct window_s {
|
||||
WINDOW *win;
|
||||
|
@ -52,6 +55,9 @@ typedef struct qwaq_resources_s {
|
|||
int initialized;
|
||||
dstring_t *print_buffer;
|
||||
PR_RESMAP (window_t) window_map;
|
||||
qwaq_event_t event_queue[QUEUE_SIZE];
|
||||
unsigned queue_head;
|
||||
unsigned queue_tail;
|
||||
} qwaq_resources_t;
|
||||
|
||||
static window_t *
|
||||
|
@ -116,6 +122,8 @@ bi_initialize (progs_t *pr)
|
|||
keypad (stdscr, TRUE);
|
||||
noecho ();
|
||||
nonl ();
|
||||
nodelay (stdscr, TRUE);
|
||||
mousemask(ALL_MOUSE_EVENTS, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -166,6 +174,78 @@ bi_wgetch (progs_t *pr)
|
|||
R_INT (pr) = wgetch (window->win);
|
||||
}
|
||||
|
||||
static void
|
||||
add_event (qwaq_resources_t *res, qwaq_event_t *event)
|
||||
{
|
||||
if (((res->queue_head - res->queue_tail) & QUEUE_MASK) != QUEUE_MASK) {
|
||||
res->event_queue[res->queue_head] = *event;
|
||||
res->queue_head = (res->queue_head + 1) & QUEUE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
get_event (qwaq_resources_t *res, qwaq_event_t *event)
|
||||
{
|
||||
if (res->queue_head != res->queue_tail) {
|
||||
if (event) {
|
||||
*event = res->event_queue[res->queue_tail];
|
||||
res->queue_tail = (res->queue_tail + 1) & QUEUE_MASK;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mouse_event (qwaq_resources_t *res, MEVENT *mevent)
|
||||
{
|
||||
qwaq_event_t event = {};
|
||||
event.event_type = qe_mouse;
|
||||
event.e.mouse.id = mevent->id;
|
||||
event.e.mouse.x = mevent->x;
|
||||
event.e.mouse.y = mevent->y;
|
||||
event.e.mouse.z = mevent->z;
|
||||
event.e.mouse.buttons = mevent->bstate;
|
||||
add_event (res, &event);
|
||||
}
|
||||
|
||||
static void
|
||||
key_event (qwaq_resources_t *res, int key)
|
||||
{
|
||||
qwaq_event_t event = {};
|
||||
event.event_type = qe_key;
|
||||
event.e.key = key;
|
||||
add_event (res, &event);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_process_input (progs_t *pr)
|
||||
{
|
||||
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
|
||||
if (Sys_CheckInput (1, -1)) {
|
||||
int ch;
|
||||
while ((ch = getch ()) != ERR && ch) {
|
||||
fflush (stderr);
|
||||
if (ch == KEY_MOUSE) {
|
||||
MEVENT mevent;
|
||||
getmouse (&mevent);
|
||||
mouse_event (res, &mevent);
|
||||
} else {
|
||||
key_event (res, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bi_get_event (progs_t *pr)
|
||||
{
|
||||
qwaq_resources_t *res = PR_Resources_Find (pr, "qwaq");
|
||||
qwaq_event_t *event = &G_STRUCT (pr, qwaq_event_t, P_INT (pr, 0));
|
||||
|
||||
R_INT (pr) = get_event (res, event);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_qwaq_clear (progs_t *pr, void *data)
|
||||
{
|
||||
|
@ -184,6 +264,8 @@ static builtin_t builtins[] = {
|
|||
{"destroy_window", bi_destroy_window, -1},
|
||||
{"wprintf", bi_wprintf, -1},
|
||||
{"wgetch", bi_wgetch, -1},
|
||||
{"process_input", bi_process_input, -1},
|
||||
{"get_event", bi_get_event, -1},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue