From 40e2d7a312fe35edc851aad48adb9bd1e778db84 Mon Sep 17 00:00:00 2001 From: Julia <145168563+julia-aph@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:37:47 -0500 Subject: [PATCH] bingus bingus --- source/io/input.c | 54 +++++------- source/io/input.h | 7 +- source/io/platforms/parseinput.c | 21 +++++ source/io/platforms/parseinput.h | 14 +++ source/io/platforms/win.c | 142 ++++++++++++++++++++----------- 5 files changed, 152 insertions(+), 86 deletions(-) create mode 100644 source/io/platforms/parseinput.c create mode 100644 source/io/platforms/parseinput.h diff --git a/source/io/input.c b/source/io/input.c index 8765955..827cb8e 100644 --- a/source/io/input.c +++ b/source/io/input.c @@ -7,56 +7,44 @@ inline size_t min_size(size_t a, size_t b) { return a < b ? a : b; } -inline size_t in_buf_empty(struct InputBuffer *in) { - 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) { - size_t copy_amt = min_size(in_buf_empty(dest), src->len); - - for (size_t i = 0; i < copy_amt; i++) - *in_buf_get(dest, dest->len + i) = *in_buf_get(src, i); + size_t copy_amt = min_size(IO_BUF_SIZE - dest->len, src->len); + for (size_t i = 0; i < dest->start; i++) { + size_t dest_i = (dest->start + dest->len + i) % IO_BUF_SIZE; + size_t src_i = (src->start + i) % IO_BUF_SIZE; + + dest->buf[dest_i] = src->buf[src_i]; + } + + dest->start += copy_amt; if (copy_amt < src->len) - src->start += copy_amt; - - src->len -= copy_amt; - dest->len += copy_amt; -} - -void InputBufferAdd(struct InputBuffer *buf, struct InputRecord *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; + src->len -= copy_amt; } void InputStringTransfer(struct InputString *dest, struct InputString *src) { - size_t copy_amt = min_size(str_buf_empty(dest), src->len); + size_t copy_amt = min_size(STR_BUF_SIZE - dest->len, src->len); for (size_t i = 0; i < copy_amt; i++) { - *str_buf_get(dest, dest->len + i) = *str_buf_get(src, i); + size_t dest_i = (dest->start + dest->len + i) % STR_BUF_SIZE; + size_t src_i = (src->start + i) % STR_BUF_SIZE; + + dest->buf[dest_i] = src->buf[src_i]; } + + dest->start += copy_amt; + if (copy_amt < src->len) + src->len -= copy_amt; } void *input_thread_loop(void *arg) { struct InputThreadHandle *hand = arg; - struct InputBuffer tmp_in = { .len = 0, .start = 0 }; - struct InputString tmp_str = { .len = 0, .start = 0 }; + struct InputBuffer tmp_in = { .len = 0 }; + struct InputString tmp_str = { .len = 0 }; while (!hand->is_terminating) { if (!PlatformReadInput(&tmp_in, &tmp_str)) { diff --git a/source/io/input.h b/source/io/input.h index 7f14ce9..a3a8f04 100644 --- a/source/io/input.h +++ b/source/io/input.h @@ -67,19 +67,16 @@ struct InputRecord { }; }; -struct input_circ_buf { - u8f len; - u8f start; -}; - struct InputBuffer { struct InputRecord buf[IO_BUF_SIZE]; u8f len; + u8f start; }; struct InputString { char buf[STR_BUF_SIZE]; u8f len; + u8f start; }; struct InputThreadHandle { diff --git a/source/io/platforms/parseinput.c b/source/io/platforms/parseinput.c new file mode 100644 index 0000000..7320f25 --- /dev/null +++ b/source/io/platforms/parseinput.c @@ -0,0 +1,21 @@ +#include "parseinput.h" + +void ParseButton(struct InputRecord *rec, u16f bind, bool is_down) +{ + rec->id = (union InputID) { .bind = bind, .type = BUTTON }; + rec->is_down = is_down; + rec->is_up = !is_down; +} + +void ParseAxis(struct InputRecord *rec, u16f bind, u64 value) +{ + rec->id = (union InputID) { .bind = bind, .type = AXIS }; + rec->axis.value = value; +} + +void ParseJoystick(struct InputRecord *rec, u16f bind, i32 x, i32 y) +{ + rec->id = (union InputID) { .bind = bind, .type = JOYSTICK }; + rec->js.x = x; + rec->js.y = y; +} \ No newline at end of file diff --git a/source/io/platforms/parseinput.h b/source/io/platforms/parseinput.h new file mode 100644 index 0000000..4e97352 --- /dev/null +++ b/source/io/platforms/parseinput.h @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + +#include "fumotris.h" +#include "input.h" + +void ParseButton(struct InputRecord *rec, u16f bind, bool is_down); + +void ParseAxis(struct InputRecord *rec, u16f bind, u64 value); + +void ParseJoystick(struct InputRecord *rec, u16f bind, i32 x, i32 y); \ No newline at end of file diff --git a/source/io/platforms/win.c b/source/io/platforms/win.c index 0f6a3cf..63a238d 100644 --- a/source/io/platforms/win.c +++ b/source/io/platforms/win.c @@ -4,12 +4,71 @@ #include "gametime.h" #include "input.h" +#include "parseinput.h" + +#define MOUSE_MOVE (MOUSE_EVENT | MOUSE_MOVED) +#define MOUSE_VWHEEL (MOUSE_EVENT | MOUSE_WHEELED) +#define MOUSE_HWHEEL (MOUSE_EVENT | MOUSE_HWHEELED) struct windows { HANDLE input_hand; HANDLE timer; } win; +struct win_coord { + SHORT x; + SHORT y; +}; + +struct win_rec { + union { + WORD type; + + struct { + WORD is_key : 1; + WORD is_mouse : 1; + WORD is_window : 1; + WORD is_menu : 1; + WORD is_focus : 1; + }; + }; + + union { + struct { + BOOL is_down; + WORD repeat; + WORD vk_code; + WORD vs_code; + WCHAR ucs2_char; + DWORD state; + } key; + + struct { + struct win_coord pos; + DWORD but; + DWORD state; + + union { + DWORD flags; + + struct { + DWORD is_moved : 1; + DWORD is_dbl_clk : 1; + DWORD is_vwheel : 1; + DWORD is_hwheel : 1; + }; + + struct { + DWORD : 2; + DWORD wheel : 2; + }; + }; + } mouse; + + struct win_coord window; + }; +}; + bool init_handles() { win.input_hand = GetStdHandle(STD_INPUT_HANDLE); @@ -58,64 +117,51 @@ bool PlatformGetRefreshRate(u16f *out) return true; } -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) +size_t ucs2_to_utf8(char *buf, u16f ucs2) { - if (mouse->dwEventFlags == MOUSE_MOVED) { - struct InputRecord *rec = &in->buf[in->len++]; - - rec->id.type = JOYSTICK; - 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; + if (ucs2 < 0xFF) { + buf[0] = ucs2; + return 1; } + + if (ucs2 < 0x7FF) { + buf[0] = 0xC0 + (ucs2 >> 6); + buf[1] = 0x80 + (ucs2 & 0x3F); + return 2; + } + + buf[0] = 0xE0 + (ucs2 >> 12); + buf[1] = 0x80 + ((ucs2 >> 6) & 0x3F); + buf[2] = 0x80 + (ucs2 & 0x3F); + return 3; +} + +inline u8f win_rec_type(struct win_rec *rec) { + return rec->type | (rec->is_mouse & rec->mouse.flags); } bool read_rec( - struct InputBuffer *in, + struct InputRecord *out, struct InputString *str, - INPUT_RECORD *rec + struct win_rec *in ) { - switch (rec->EventType) { + switch (win_rec_type(in)) { case KEY_EVENT: - read_key(in, str, &rec->Event.KeyEvent); + ParseButton(out, in->key.vk_code, in->key.is_down); + str->len += ucs2_to_utf8(&str->buf[str->len], in->key.ucs2_char); return true; - case MOUSE_EVENT: - read_mouse(in, &rec->Event.MouseEvent); + case MOUSE_MOVE: + ParseJoystick(out, 0, in->mouse.pos.x, in->mouse.pos.y); return true; + case MOUSE_VWHEEL: + case MOUSE_HWHEEL: + ParseAxis(out, in->mouse.is_hwheel, in->mouse.but); + return true; + case WINDOW_BUFFER_SIZE_EVENT: - return true; + return false; // TODO: Handle window resizing } @@ -125,15 +171,15 @@ bool read_rec( bool PlatformReadInput(struct InputBuffer *in, struct InputString *str) { DWORD max_records = IO_BUF_SIZE - in->len; - INPUT_RECORD win_buf[max_records]; + struct win_rec win_buf[max_records]; DWORD filled; if (!ReadConsoleInputW(win.input_hand, win_buf, max_records, &filled)) return false; for (size_t i = 0; i < filled; i++) { - if (!read_rec(in, str, win_buf + i)) - return false; + if (read_rec(in, str, win_buf + i)) + in->len += 1; } return true;