hhjkkj
jkhkj
This commit is contained in:
parent
5e23db78ce
commit
1064e95edc
|
@ -144,11 +144,7 @@ void dispatch_update(struct InputAxis *axis, struct InputRecord *rec)
|
||||||
axis->data = rec->data;
|
axis->data = rec->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_alphanumeric(char c) {
|
void read_input_buf(struct Controller *ctrl)
|
||||||
return c >=32 and c <= 126;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool read_input_buf(struct Controller *ctrl)
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < ctrl->pending_buf.len; i++) {
|
for (size_t i = 0; i < ctrl->pending_buf.len; i++) {
|
||||||
struct InputAxis *axis = ctrl->pending_buf.axes[i];
|
struct InputAxis *axis = ctrl->pending_buf.axes[i];
|
||||||
|
@ -159,10 +155,9 @@ bool read_input_buf(struct Controller *ctrl)
|
||||||
ctrl->pending_buf.len = 0;
|
ctrl->pending_buf.len = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < ctrl->buf.len; i++) {
|
for (size_t i = 0; i < ctrl->buf.len; i++) {
|
||||||
struct InputRecord *rec = &ctrl->buf.recs[i];
|
struct InputRecord *rec = &ctrl->buf.buf[i];
|
||||||
|
|
||||||
union InputID rec_id = to_id(rec->bind, rec->type);
|
struct InputAxis *axis = find_axis(&ctrl->binds, rec->id);
|
||||||
struct InputAxis *axis = find_axis(&ctrl->binds, rec_id);
|
|
||||||
|
|
||||||
if (axis == nullptr)
|
if (axis == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
@ -172,7 +167,11 @@ bool read_input_buf(struct Controller *ctrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl->buf.len = 0;
|
ctrl->buf.len = 0;
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
void read_str_buf(struct Controller *ctrl)
|
||||||
|
{
|
||||||
|
ctrl->string
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CtrlPoll(struct Controller *ctrl, struct InputThreadHandle *hand)
|
bool CtrlPoll(struct Controller *ctrl, struct InputThreadHandle *hand)
|
||||||
|
@ -181,6 +180,7 @@ bool CtrlPoll(struct Controller *ctrl, struct InputThreadHandle *hand)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
read_input_buf(ctrl);
|
read_input_buf(ctrl);
|
||||||
|
read_str_buf(ctrl);
|
||||||
|
|
||||||
if (pthread_cond_signal(&hand->buf_read) != 0)
|
if (pthread_cond_signal(&hand->buf_read) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -191,11 +191,6 @@ bool CtrlPoll(struct Controller *ctrl, struct InputThreadHandle *hand)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CtrlInputString(struct Controller *ctrl, size_t n, char *buf)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*int main()
|
/*int main()
|
||||||
{
|
{
|
||||||
struct Controller ctrl;
|
struct Controller ctrl;
|
||||||
|
|
|
@ -21,9 +21,12 @@ struct InputAxis {
|
||||||
};
|
};
|
||||||
|
|
||||||
union InputID id;
|
union InputID id;
|
||||||
u8 is_down;
|
|
||||||
u8 is_held;
|
struct {
|
||||||
u8 is_up;
|
u8f is_down : 1;
|
||||||
|
u8f is_held : 1;
|
||||||
|
u8f is_up : 1;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ctrl_bkt {
|
struct ctrl_bkt {
|
||||||
|
@ -45,6 +48,7 @@ struct ctrl_axis_vec {
|
||||||
|
|
||||||
struct Controller {
|
struct Controller {
|
||||||
struct InputBuffer buf;
|
struct InputBuffer buf;
|
||||||
|
struct InputString string;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct InputAxis *axes[IO_BUF_SIZE];
|
struct InputAxis *axes[IO_BUF_SIZE];
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
struct InputRecord *buf_get(struct InputBuffer *buf, size_t i) {
|
inline size_t min_size(size_t a, size_t b) {
|
||||||
return buf->recs + (buf->start + i) % IO_BUF_SIZE;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t min_size(size_t a, size_t b) {
|
inline size_t in_buf_empty(struct InputBuffer *in) {
|
||||||
return a < b ? a : b;
|
return IO_BUF_SIZE - in->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InputRecord *in_buf_get(struct InputBuffer *in, size_t i) {
|
||||||
|
return in->buf + (in->start + i) % IO_BUF_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputBufferTransfer(struct InputBuffer *dest, struct InputBuffer *src)
|
void InputBufferTransfer(struct InputBuffer *dest, struct InputBuffer *src)
|
||||||
{
|
{
|
||||||
size_t copy_amt = min_size(IO_BUF_SIZE - dest->len, src->len);
|
size_t copy_amt = min_size(in_buf_empty(dest), src->len);
|
||||||
|
|
||||||
for (size_t i = 0; i < copy_amt; i++)
|
for (size_t i = 0; i < copy_amt; i++)
|
||||||
*buf_get(dest, dest->len + i) = *buf_get(src, i);
|
*in_buf_get(dest, dest->len + i) = *in_buf_get(src, i);
|
||||||
|
|
||||||
if (copy_amt < src->len)
|
if (copy_amt < src->len)
|
||||||
src->start += copy_amt;
|
src->start += copy_amt;
|
||||||
|
@ -26,16 +31,35 @@ void InputBufferTransfer(struct InputBuffer *dest, struct InputBuffer *src)
|
||||||
|
|
||||||
void InputBufferAdd(struct InputBuffer *buf, struct InputRecord *rec)
|
void InputBufferAdd(struct InputBuffer *buf, struct InputRecord *rec)
|
||||||
{
|
{
|
||||||
*buf_get(buf, buf->len++) = *rec;
|
*in_buf_get(buf, buf->len++) = *rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t str_buf_empty(struct InputString *str) {
|
||||||
|
return STR_BUF_SIZE - str->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char *str_buf_get(struct InputString *str, size_t i) {
|
||||||
|
return (str->start + i) % STR_BUF_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputStringTransfer(struct InputString *dest, struct InputString *src)
|
||||||
|
{
|
||||||
|
size_t copy_amt = min_size(str_buf_empty(dest), src->len);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < copy_amt; i++) {
|
||||||
|
*str_buf_get(dest, dest->len + i) = *str_buf_get(src, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *input_thread_loop(void *arg)
|
void *input_thread_loop(void *arg)
|
||||||
{
|
{
|
||||||
struct InputThreadHandle *hand = arg;
|
struct InputThreadHandle *hand = arg;
|
||||||
struct InputBuffer tmp_buf = { .len = 0, .start = 0 };
|
|
||||||
|
struct InputBuffer tmp_in = { .len = 0, .start = 0 };
|
||||||
|
struct InputString tmp_str = { .len = 0, .start = 0 };
|
||||||
|
|
||||||
while (!hand->is_terminating) {
|
while (!hand->is_terminating) {
|
||||||
if (!PlatformReadInput(&tmp_buf)) {
|
if (!PlatformReadInput(&tmp_in, &tmp_str)) {
|
||||||
hand->err = true;
|
hand->err = true;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -44,13 +68,14 @@ void *input_thread_loop(void *arg)
|
||||||
if (hand->err)
|
if (hand->err)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
while (tmp_buf.len == IO_BUF_SIZE) {
|
while (tmp_in.len == IO_BUF_SIZE) {
|
||||||
hand->err = pthread_cond_wait(&hand->buf_read, &hand->mutex);
|
hand->err = pthread_cond_wait(&hand->buf_read, &hand->mutex);
|
||||||
if (hand->err)
|
if (hand->err)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputBufferTransfer(hand->buf, &tmp_buf);
|
InputBufferTransfer(hand->in, &tmp_in);
|
||||||
|
InputStringTransfer(hand->str, &tmp_str);
|
||||||
|
|
||||||
hand->err = pthread_mutex_unlock(&hand->mutex);
|
hand->err = pthread_mutex_unlock(&hand->mutex);
|
||||||
if (hand->err)
|
if (hand->err)
|
||||||
|
@ -62,7 +87,7 @@ void *input_thread_loop(void *arg)
|
||||||
|
|
||||||
bool BeginInputThread(struct InputThreadHandle *hand, struct InputBuffer *buf)
|
bool BeginInputThread(struct InputThreadHandle *hand, struct InputBuffer *buf)
|
||||||
{
|
{
|
||||||
hand->buf = buf;
|
hand->in = buf;
|
||||||
hand->mutex = PTHREAD_MUTEX_INITIALIZER;
|
hand->mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
hand->buf_read = PTHREAD_COND_INITIALIZER;
|
hand->buf_read = PTHREAD_COND_INITIALIZER;
|
||||||
hand->err = 0;
|
hand->err = 0;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "gametime.h"
|
#include "gametime.h"
|
||||||
|
|
||||||
#define IO_BUF_SIZE 16
|
#define IO_BUF_SIZE 16
|
||||||
|
#define STR_BUF_SIZE (IO_BUF_SIZE * 4)
|
||||||
|
|
||||||
enum InputType {
|
enum InputType {
|
||||||
BUTTON,
|
BUTTON,
|
||||||
|
@ -57,22 +58,36 @@ struct InputRecord {
|
||||||
union InputData data;
|
union InputData data;
|
||||||
};
|
};
|
||||||
|
|
||||||
u16f bind;
|
union InputID id;
|
||||||
|
|
||||||
u8 type;
|
struct {
|
||||||
u8 is_down;
|
u8f is_down : 1;
|
||||||
u8 is_held;
|
u8f is_held : 1;
|
||||||
u8 is_up;
|
u8f is_up : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct input_circ_buf {
|
||||||
|
u8f len;
|
||||||
|
u8f start;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputBuffer {
|
struct InputBuffer {
|
||||||
struct InputRecord recs[IO_BUF_SIZE];
|
struct InputRecord buf[IO_BUF_SIZE];
|
||||||
|
u8f len;
|
||||||
|
u8f start;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InputString {
|
||||||
|
char buf[STR_BUF_SIZE];
|
||||||
u8f len;
|
u8f len;
|
||||||
u8f start;
|
u8f start;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputThreadHandle {
|
struct InputThreadHandle {
|
||||||
struct InputBuffer *buf;
|
struct InputBuffer *in;
|
||||||
|
struct InputString *str;
|
||||||
|
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
|
@ -16,7 +16,7 @@ bool PlatformInit();
|
||||||
|
|
||||||
bool PlatformGetRefreshRate(u16f *out);
|
bool PlatformGetRefreshRate(u16f *out);
|
||||||
|
|
||||||
bool PlatformReadInput(struct InputBuffer *buf);
|
bool PlatformReadInput(struct InputBuffer *in, struct InputString *str);
|
||||||
|
|
||||||
bool PlatformStopInput();
|
bool PlatformStopInput();
|
||||||
|
|
||||||
|
|
|
@ -58,72 +58,82 @@ bool PlatformGetRefreshRate(u16f *out)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_key_event(struct InputRecord *rec, KEY_EVENT_RECORD *win_key)
|
inline size_t ucs2_to_utf8(u16f ucs2, size_t n, char *buf) {
|
||||||
|
return WideCharToMultiByte(CP_UTF8, 0, ucs2, 1, buf, n, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_key(
|
||||||
|
struct InputBuffer *in,
|
||||||
|
struct InputString *str,
|
||||||
|
KEY_EVENT_RECORD *key
|
||||||
|
) {
|
||||||
|
struct InputRecord *rec = &in->buf[in->len++];
|
||||||
|
|
||||||
|
rec->id.type = BUTTON;
|
||||||
|
rec->id.bind = key->wVirtualKeyCode;
|
||||||
|
|
||||||
|
rec->is_down = key->bKeyDown;
|
||||||
|
rec->is_up = !key->bKeyDown;
|
||||||
|
|
||||||
|
ucs2_to_utf8(key->uChar.UnicodeChar, IO_BUF_SIZE - str->len, str->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_mouse_wheel(DWORD event_flags) {
|
||||||
|
return (event_flags & (MOUSE_WHEELED | MOUSE_HWHEELED)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_mouse(struct InputBuffer *in, MOUSE_EVENT_RECORD *mouse)
|
||||||
{
|
{
|
||||||
rec->type = BUTTON;
|
if (mouse->dwEventFlags == MOUSE_MOVED) {
|
||||||
rec->bind = win_key->wVirtualKeyCode;
|
struct InputRecord *rec = &in->buf[in->len++];
|
||||||
|
|
||||||
rec->is_down = win_key->bKeyDown;
|
rec->id.type = JOYSTICK;
|
||||||
rec->is_up = !win_key->bKeyDown;
|
rec->id.bind = 0;
|
||||||
|
rec->js.x = mouse->dwMousePosition.X;
|
||||||
|
rec->js.y = mouse->dwMousePosition.Y;
|
||||||
|
} else if (is_mouse_wheel(mouse->dwEventFlags)) {
|
||||||
|
struct InputRecord *rec = &in->buf[in->len++];
|
||||||
|
|
||||||
|
rec->id.type = AXIS;
|
||||||
|
rec->id.bind = (mouse->dwEventFlags == MOUSE_WHEELED);
|
||||||
|
rec->axis.value = mouse->dwButtonState;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_mouse_event(struct InputRecord *rec, MOUSE_EVENT_RECORD *win_mouse)
|
bool read_rec(
|
||||||
{
|
struct InputBuffer *in,
|
||||||
if (win_mouse->dwEventFlags == MOUSE_MOVED) {
|
struct InputString *str,
|
||||||
rec->type = JOYSTICK;
|
INPUT_RECORD *rec
|
||||||
rec->bind = 0;
|
) {
|
||||||
rec->js.x = win_mouse->dwMousePosition.X;
|
switch (rec->EventType) {
|
||||||
rec->js.y = win_mouse->dwMousePosition.Y;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((win_mouse->dwEventFlags & (MOUSE_WHEELED | MOUSE_HWHEELED)) != 0) {
|
|
||||||
rec->type = AXIS;
|
|
||||||
rec->bind = win_mouse->dwEventFlags == MOUSE_WHEELED;
|
|
||||||
rec->axis.value = win_mouse->dwButtonState;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool read_rec(struct InputRecord *rec, INPUT_RECORD *win_rec)
|
|
||||||
{
|
|
||||||
switch (win_rec->EventType) {
|
|
||||||
case KEY_EVENT:
|
case KEY_EVENT:
|
||||||
read_key_event(rec, &win_rec->Event.KeyEvent);
|
read_key(in, str, &rec->Event.KeyEvent);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MOUSE_EVENT:
|
case MOUSE_EVENT:
|
||||||
return read_mouse_event(rec, &win_rec->Event.MouseEvent);
|
read_mouse(in, &rec->Event.MouseEvent);
|
||||||
|
return true;
|
||||||
|
|
||||||
case WINDOW_BUFFER_SIZE_EVENT:
|
case WINDOW_BUFFER_SIZE_EVENT:
|
||||||
return false;
|
return true;
|
||||||
// TODO: Handle window resizing
|
// TODO: Handle window resizing
|
||||||
}
|
}
|
||||||
|
|
||||||
rec->type = ESCAPE;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlatformReadInput(struct InputBuffer *buf)
|
bool PlatformReadInput(struct InputBuffer *in, struct InputString *str)
|
||||||
{
|
{
|
||||||
DWORD max_records = IO_BUF_SIZE - buf->len;
|
DWORD max_records = IO_BUF_SIZE - in->len;
|
||||||
INPUT_RECORD win_buf[max_records];
|
INPUT_RECORD win_buf[max_records];
|
||||||
DWORD filled;
|
DWORD filled;
|
||||||
|
|
||||||
if (!ReadConsoleInputW(win.input_hand, win_buf, max_records, &filled))
|
if (!ReadConsoleInputW(win.input_hand, win_buf, max_records, &filled))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct InputRecord rec = { .time = TimeNow() };
|
|
||||||
|
|
||||||
for (size_t i = 0; i < filled; i++) {
|
for (size_t i = 0; i < filled; i++) {
|
||||||
if (!read_rec(&rec, win_buf + i))
|
if (!read_rec(in, str, win_buf + i))
|
||||||
continue;
|
return false;
|
||||||
|
|
||||||
InputBufferAdd(buf, &rec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue