bingus
bingus
This commit is contained in:
parent
03094ec8cc
commit
40e2d7a312
|
@ -7,56 +7,44 @@ inline size_t min_size(size_t a, size_t b) {
|
||||||
return a < b ? a : 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)
|
void InputBufferTransfer(struct InputBuffer *dest, struct InputBuffer *src)
|
||||||
{
|
{
|
||||||
size_t copy_amt = min_size(in_buf_empty(dest), src->len);
|
size_t copy_amt = min_size(IO_BUF_SIZE - dest->len, src->len);
|
||||||
|
|
||||||
for (size_t i = 0; i < copy_amt; i++)
|
|
||||||
*in_buf_get(dest, dest->len + i) = *in_buf_get(src, i);
|
|
||||||
|
|
||||||
|
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)
|
if (copy_amt < src->len)
|
||||||
src->start += copy_amt;
|
src->len -= 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputStringTransfer(struct InputString *dest, struct InputString *src)
|
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++) {
|
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)
|
void *input_thread_loop(void *arg)
|
||||||
{
|
{
|
||||||
struct InputThreadHandle *hand = arg;
|
struct InputThreadHandle *hand = arg;
|
||||||
|
|
||||||
struct InputBuffer tmp_in = { .len = 0, .start = 0 };
|
struct InputBuffer tmp_in = { .len = 0 };
|
||||||
struct InputString tmp_str = { .len = 0, .start = 0 };
|
struct InputString tmp_str = { .len = 0 };
|
||||||
|
|
||||||
while (!hand->is_terminating) {
|
while (!hand->is_terminating) {
|
||||||
if (!PlatformReadInput(&tmp_in, &tmp_str)) {
|
if (!PlatformReadInput(&tmp_in, &tmp_str)) {
|
||||||
|
|
|
@ -67,19 +67,16 @@ struct InputRecord {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct input_circ_buf {
|
|
||||||
u8f len;
|
|
||||||
u8f start;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InputBuffer {
|
struct InputBuffer {
|
||||||
struct InputRecord buf[IO_BUF_SIZE];
|
struct InputRecord buf[IO_BUF_SIZE];
|
||||||
u8f len;
|
u8f len;
|
||||||
|
u8f start;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputString {
|
struct InputString {
|
||||||
char buf[STR_BUF_SIZE];
|
char buf[STR_BUF_SIZE];
|
||||||
u8f len;
|
u8f len;
|
||||||
|
u8f start;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputThreadHandle {
|
struct InputThreadHandle {
|
||||||
|
|
21
source/io/platforms/parseinput.c
Normal file
21
source/io/platforms/parseinput.c
Normal file
|
@ -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;
|
||||||
|
}
|
14
source/io/platforms/parseinput.h
Normal file
14
source/io/platforms/parseinput.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include <iso646.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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);
|
|
@ -4,12 +4,71 @@
|
||||||
|
|
||||||
#include "gametime.h"
|
#include "gametime.h"
|
||||||
#include "input.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 {
|
struct windows {
|
||||||
HANDLE input_hand;
|
HANDLE input_hand;
|
||||||
HANDLE timer;
|
HANDLE timer;
|
||||||
} win;
|
} 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()
|
bool init_handles()
|
||||||
{
|
{
|
||||||
win.input_hand = GetStdHandle(STD_INPUT_HANDLE);
|
win.input_hand = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
@ -58,64 +117,51 @@ bool PlatformGetRefreshRate(u16f *out)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t ucs2_to_utf8(u16f ucs2, size_t n, char *buf) {
|
size_t ucs2_to_utf8(char *buf, u16f ucs2)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (mouse->dwEventFlags == MOUSE_MOVED) {
|
if (ucs2 < 0xFF) {
|
||||||
struct InputRecord *rec = &in->buf[in->len++];
|
buf[0] = ucs2;
|
||||||
|
return 1;
|
||||||
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 < 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(
|
bool read_rec(
|
||||||
struct InputBuffer *in,
|
struct InputRecord *out,
|
||||||
struct InputString *str,
|
struct InputString *str,
|
||||||
INPUT_RECORD *rec
|
struct win_rec *in
|
||||||
) {
|
) {
|
||||||
switch (rec->EventType) {
|
switch (win_rec_type(in)) {
|
||||||
case KEY_EVENT:
|
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;
|
return true;
|
||||||
|
|
||||||
case MOUSE_EVENT:
|
case MOUSE_MOVE:
|
||||||
read_mouse(in, &rec->Event.MouseEvent);
|
ParseJoystick(out, 0, in->mouse.pos.x, in->mouse.pos.y);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case MOUSE_VWHEEL:
|
||||||
|
case MOUSE_HWHEEL:
|
||||||
|
ParseAxis(out, in->mouse.is_hwheel, in->mouse.but);
|
||||||
|
return true;
|
||||||
|
|
||||||
case WINDOW_BUFFER_SIZE_EVENT:
|
case WINDOW_BUFFER_SIZE_EVENT:
|
||||||
return true;
|
return false;
|
||||||
// TODO: Handle window resizing
|
// TODO: Handle window resizing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,15 +171,15 @@ bool read_rec(
|
||||||
bool PlatformReadInput(struct InputBuffer *in, struct InputString *str)
|
bool PlatformReadInput(struct InputBuffer *in, struct InputString *str)
|
||||||
{
|
{
|
||||||
DWORD max_records = IO_BUF_SIZE - in->len;
|
DWORD max_records = IO_BUF_SIZE - in->len;
|
||||||
INPUT_RECORD win_buf[max_records];
|
struct win_rec 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;
|
||||||
|
|
||||||
for (size_t i = 0; i < filled; i++) {
|
for (size_t i = 0; i < filled; i++) {
|
||||||
if (!read_rec(in, str, win_buf + i))
|
if (read_rec(in, str, win_buf + i))
|
||||||
return false;
|
in->len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue