mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-06-01 09:02:08 +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;
|
typedef struct window_s *window_t;
|
||||||
|
|
||||||
void initialize (void) = #0;
|
void initialize (void) = #0;
|
||||||
|
@ -6,17 +8,32 @@ void destroy_window (window_t win) = #0;
|
||||||
void wprintf (window_t win, string fmt, ...) = #0;
|
void wprintf (window_t win, string fmt, ...) = #0;
|
||||||
int wgetch (window_t win) = #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 main (int argc, string *argv)
|
||||||
{
|
{
|
||||||
int ch;
|
int ch = 0;
|
||||||
|
qwaq_event_t event = { };
|
||||||
|
|
||||||
initialize ();
|
initialize ();
|
||||||
window_t win = create_window (20, 5, 50, 10);
|
window_t win = create_window (20, 5, 50, 10);
|
||||||
wprintf (win, "Hi there!\n");
|
wprintf (win, "Hi there!\n");
|
||||||
do {
|
do {
|
||||||
ch = wgetch (win);
|
process_input ();
|
||||||
if (ch) {
|
|
||||||
wprintf (win, "%d\n", ch);
|
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);
|
} while (ch != 27);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -40,8 +40,11 @@
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
|
|
||||||
#include "qwaq.h"
|
#include "qwaq.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
#define always_inline inline __attribute__((__always_inline__))
|
#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 {
|
typedef struct window_s {
|
||||||
WINDOW *win;
|
WINDOW *win;
|
||||||
|
@ -52,6 +55,9 @@ typedef struct qwaq_resources_s {
|
||||||
int initialized;
|
int initialized;
|
||||||
dstring_t *print_buffer;
|
dstring_t *print_buffer;
|
||||||
PR_RESMAP (window_t) window_map;
|
PR_RESMAP (window_t) window_map;
|
||||||
|
qwaq_event_t event_queue[QUEUE_SIZE];
|
||||||
|
unsigned queue_head;
|
||||||
|
unsigned queue_tail;
|
||||||
} qwaq_resources_t;
|
} qwaq_resources_t;
|
||||||
|
|
||||||
static window_t *
|
static window_t *
|
||||||
|
@ -116,6 +122,8 @@ bi_initialize (progs_t *pr)
|
||||||
keypad (stdscr, TRUE);
|
keypad (stdscr, TRUE);
|
||||||
noecho ();
|
noecho ();
|
||||||
nonl ();
|
nonl ();
|
||||||
|
nodelay (stdscr, TRUE);
|
||||||
|
mousemask(ALL_MOUSE_EVENTS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -166,6 +174,78 @@ bi_wgetch (progs_t *pr)
|
||||||
R_INT (pr) = wgetch (window->win);
|
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
|
static void
|
||||||
bi_qwaq_clear (progs_t *pr, void *data)
|
bi_qwaq_clear (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
@ -184,6 +264,8 @@ static builtin_t builtins[] = {
|
||||||
{"destroy_window", bi_destroy_window, -1},
|
{"destroy_window", bi_destroy_window, -1},
|
||||||
{"wprintf", bi_wprintf, -1},
|
{"wprintf", bi_wprintf, -1},
|
||||||
{"wgetch", bi_wgetch, -1},
|
{"wgetch", bi_wgetch, -1},
|
||||||
|
{"process_input", bi_process_input, -1},
|
||||||
|
{"get_event", bi_get_event, -1},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue