input for the hundreth time

PLEASE I JUSR WANT TO BE DONE WITH IT
This commit is contained in:
Julia 2024-04-25 02:04:43 -05:00
parent 40e2d7a312
commit bc0007b588
12 changed files with 146 additions and 144 deletions

View file

@ -54,6 +54,8 @@
"stdbool.h": "c", "stdbool.h": "c",
"gametime.h": "c", "gametime.h": "c",
"stdlib.h": "c", "stdlib.h": "c",
"stdio.h": "c" "stdio.h": "c",
"platform.h": "c",
"ringbuffer.h": "c"
} }
} }

6
source/fumotris.c Normal file
View file

@ -0,0 +1,6 @@
#include "fumotris.h"
inline size_t min_size(size_t a, size_t b)
{
return a < b ? a : b;
}

View file

@ -28,6 +28,8 @@ typedef int_fast32_t i32f;
typedef int64_t i64; typedef int64_t i64;
typedef int_fast64_t i64f; typedef int_fast64_t i64f;
inline size_t min_size(size_t a, size_t b);
/*const u8 I[16] = { /*const u8 I[16] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,

View file

@ -1,7 +1,5 @@
#include "ctrl.h" #include "ctrl.h"
#include <pthread.h>
#define INIT_SIZE 16 #define INIT_SIZE 16
bool CreateCtrl(struct Controller *ctrl) bool CreateCtrl(struct Controller *ctrl)
@ -14,7 +12,7 @@ bool CreateCtrl(struct Controller *ctrl)
return false; return false;
*ctrl = (struct Controller) { *ctrl = (struct Controller) {
.buf.len = 0, .recs.len = 0,
.pending_buf.len = 0, .pending_buf.len = 0,
.axis_vec = (struct ctrl_axis_vec) { .axis_vec = (struct ctrl_axis_vec) {
@ -144,7 +142,7 @@ void dispatch_update(struct InputAxis *axis, struct InputRecord *rec)
axis->data = rec->data; axis->data = rec->data;
} }
void read_input_buf(struct Controller *ctrl) void CtrlPoll(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];
@ -154,8 +152,8 @@ void 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->recs.len; i++) {
struct InputRecord *rec = &ctrl->buf.buf[i]; struct InputRecord *rec = &ctrl->recs.buf[i];
struct InputAxis *axis = find_axis(&ctrl->binds, rec->id); struct InputAxis *axis = find_axis(&ctrl->binds, rec->id);
@ -166,29 +164,12 @@ void read_input_buf(struct Controller *ctrl)
ctrl->pending_buf.axes[ctrl->pending_buf.len++] = axis; ctrl->pending_buf.axes[ctrl->pending_buf.len++] = axis;
} }
ctrl->buf.len = 0; ctrl->recs.len = 0;
} }
void read_str_buf(struct Controller *ctrl) size_t CtrlInputString(struct Controller *ctrl, size_t n, char *buf)
{ {
ctrl->string size_t copy_max = min_size(ctrl->str.len, n);
}
bool CtrlPoll(struct Controller *ctrl, struct InputThreadHandle *hand)
{
if (pthread_mutex_lock(&hand->mutex) != 0)
return false;
read_input_buf(ctrl);
read_str_buf(ctrl);
if (pthread_cond_signal(&hand->buf_read) != 0)
return false;
if (pthread_mutex_unlock(&hand->mutex) != 0)
return false;
return true;
} }
/*int main() /*int main()

View file

@ -47,8 +47,8 @@ struct ctrl_axis_vec {
}; };
struct Controller { struct Controller {
struct InputBuffer buf; struct RecordBuffer recs;
struct InputString string; struct StringBuffer str;
struct { struct {
struct InputAxis *axes[IO_BUF_SIZE]; struct InputAxis *axes[IO_BUF_SIZE];

View file

@ -3,82 +3,82 @@
#include "platform.h" #include "platform.h"
inline size_t min_size(size_t a, size_t b) { void InputBufferTransfer(struct RecordBuffer *dest, struct RecordBuffer *src)
return a < b ? a : b;
}
void InputBufferTransfer(struct InputBuffer *dest, struct InputBuffer *src)
{ {
size_t copy_amt = min_size(IO_BUF_SIZE - dest->len, src->len); size_t copy_max = min_size(IO_BUF_SIZE - dest->len, src->len);
for (size_t i = 0; i < dest->start; i++) { for (size_t i = 0; i < copy_max; i++) {
size_t dest_i = (dest->start + dest->len + i) % IO_BUF_SIZE; size_t dest_i = (dest->start + dest->len + i) % IO_BUF_SIZE;
size_t src_i = (src->start + i) % IO_BUF_SIZE; size_t src_i = (src->start + i) % IO_BUF_SIZE;
dest->buf[dest_i] = src->buf[src_i]; dest->buf[dest_i] = src->buf[src_i];
} }
dest->start += copy_amt; dest->start += copy_max;
if (copy_amt < src->len) if (copy_max < src->len)
src->len -= copy_amt; src->len -= copy_max;
} }
void InputStringTransfer(struct InputString *dest, struct InputString *src) void StringBufferTransfer(struct StringBuffer *dest, struct StringBuffer *src)
{ {
size_t copy_amt = min_size(STR_BUF_SIZE - dest->len, src->len); size_t copy_max = 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_max; i++) {
size_t dest_i = (dest->start + dest->len + i) % STR_BUF_SIZE; size_t dest_i = (dest->start + dest->len + i) % STR_BUF_SIZE;
size_t src_i = (src->start + i) % STR_BUF_SIZE; size_t src_i = (src->start + i) % STR_BUF_SIZE;
dest->buf[dest_i] = src->buf[src_i]; dest->buf[dest_i] = src->buf[src_i];
} }
dest->start += copy_amt; dest->start += copy_max;
if (copy_amt < src->len) if (copy_max < src->len)
src->len -= copy_amt; src->len -= copy_max;
} }
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 }; struct RecordBuffer tmp_in = { .len = 0, .start = 0 };
struct InputString tmp_str = { .len = 0 }; struct StringBuffer tmp_str = { .len = 0, .start = 0 };
while (!hand->is_terminating) { while (!hand->is_terminating) {
if (!PlatformReadInput(&tmp_in, &tmp_str)) { if (!PlatformReadInput(&tmp_in, &tmp_str))
hand->err = true;
return nullptr; return nullptr;
}
hand->err = pthread_mutex_lock(&hand->mutex); if (hand->err = pthread_mutex_lock(&hand->mutex))
if (hand->err)
return nullptr; return nullptr;
while (tmp_in.len == IO_BUF_SIZE) { while (tmp_in.len == IO_BUF_SIZE) {
hand->err = pthread_cond_wait(&hand->buf_read, &hand->mutex); if (hand->err = pthread_cond_wait(&hand->consume, &hand->mutex))
if (hand->err)
return nullptr; return nullptr;
} }
InputBufferTransfer(hand->in, &tmp_in); InputBufferTransfer(hand->in, &tmp_in);
InputStringTransfer(hand->str, &tmp_str); StringBufferTransfer(hand->str, &tmp_str);
hand->err = pthread_mutex_unlock(&hand->mutex); if (hand->err = pthread_mutex_unlock(&hand->mutex))
if (hand->err)
return nullptr; return nullptr;
} }
return nullptr; return nullptr;
} }
bool BeginInputThread(struct InputThreadHandle *hand, struct InputBuffer *buf) bool BeginInputThread(
{ struct InputThreadHandle *hand,
hand->in = buf; struct RecordBuffer *in,
hand->mutex = PTHREAD_MUTEX_INITIALIZER; struct StringBuffer *str
hand->buf_read = PTHREAD_COND_INITIALIZER; ) {
hand->err = 0; *hand = (struct InputThreadHandle) {
.in = in,
.str = str,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.consume = PTHREAD_COND_INITIALIZER,
.err = 0,
.is_terminating = false,
};
return pthread_create(&hand->thread, nullptr, input_thread_loop, hand) == 0; return pthread_create(&hand->thread, nullptr, input_thread_loop, hand) == 0;
} }

View file

@ -67,34 +67,36 @@ struct InputRecord {
}; };
}; };
struct InputBuffer { struct RecordBuffer {
struct InputRecord buf[IO_BUF_SIZE]; struct InputRecord buf[IO_BUF_SIZE];
u8f len; u8f len;
u8f start; u8f start;
}; };
struct InputString { struct StringBuffer {
char buf[STR_BUF_SIZE]; char buf[STR_BUF_SIZE];
u8f len; u8f len;
u8f start; u8f start;
}; };
struct InputThreadHandle { struct InputThreadHandle {
struct InputBuffer *in; struct RecordBuffer *in;
struct InputString *str; struct StringBuffer *str;
pthread_t thread; pthread_t thread;
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t buf_read; pthread_cond_t consume;
int err; int err;
bool is_terminating; bool is_terminating;
}; };
void InputBufferTransfer(struct InputBuffer *tmp, struct InputBuffer *dest); void InputBufferTransfer(struct RecordBuffer *tmp, struct RecordBuffer *dest);
void InputBufferAdd(struct InputBuffer *buf, struct InputRecord *src); bool BeginInputThread(
struct InputThreadHandle *hand,
bool BeginInputThread(struct InputThreadHandle *hand, struct InputBuffer *buf); struct RecordBuffer *in,
struct StringBuffer *str
);
bool EndInputThread(struct InputThreadHandle *hand); bool EndInputThread(struct InputThreadHandle *hand);

View file

@ -1,21 +1,40 @@
#include "parseinput.h" #include "parseinput.h"
void ParseButton(struct InputRecord *rec, u16f bind, bool is_down) void ReadButton(struct InputRecord *rec, u16f bind, bool is_down)
{ {
rec->id = (union InputID) { .bind = bind, .type = BUTTON }; rec->id = (union InputID) { .bind = bind, .type = BUTTON };
rec->is_down = is_down; rec->is_down = is_down;
rec->is_up = !is_down; rec->is_up = !is_down;
} }
void ParseAxis(struct InputRecord *rec, u16f bind, u64 value) void ReadAxis(struct InputRecord *rec, u16f bind, u64 value)
{ {
rec->id = (union InputID) { .bind = bind, .type = AXIS }; rec->id = (union InputID) { .bind = bind, .type = AXIS };
rec->axis.value = value; rec->axis.value = value;
} }
void ParseJoystick(struct InputRecord *rec, u16f bind, i32 x, i32 y) void ReadJoystick(struct InputRecord *rec, u16f bind, i32 x, i32 y)
{ {
rec->id = (union InputID) { .bind = bind, .type = JOYSTICK }; rec->id = (union InputID) { .bind = bind, .type = JOYSTICK };
rec->js.x = x; rec->js.x = x;
rec->js.y = y; rec->js.y = y;
} }
size_t UCS2ToUTF8(char *buf, u16f ucs2)
{
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;
}

View file

@ -7,8 +7,10 @@
#include "fumotris.h" #include "fumotris.h"
#include "input.h" #include "input.h"
void ParseButton(struct InputRecord *rec, u16f bind, bool is_down); void ReadButton(struct InputRecord *rec, u16f bind, bool is_down);
void ParseAxis(struct InputRecord *rec, u16f bind, u64 value); void ReadAxis(struct InputRecord *rec, u16f bind, u64 value);
void ParseJoystick(struct InputRecord *rec, u16f bind, i32 x, i32 y); void ReadJoystick(struct InputRecord *rec, u16f bind, i32 x, i32 y);
size_t UCS2ToUTF8(char *buf, u16f ucs2);

View file

@ -16,7 +16,7 @@ bool PlatformInit();
bool PlatformGetRefreshRate(u16f *out); bool PlatformGetRefreshRate(u16f *out);
bool PlatformReadInput(struct InputBuffer *in, struct InputString *str); bool PlatformReadInput(struct RecordBuffer *in, struct StringBuffer *str);
bool PlatformStopInput(); bool PlatformStopInput();

View file

@ -20,30 +20,16 @@ struct win_coord {
SHORT y; SHORT y;
}; };
struct win_rec { struct win_key {
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; BOOL is_down;
WORD repeat; WORD repeat;
WORD vk_code; WORD vk_code;
WORD vs_code; WORD vs_code;
WCHAR ucs2_char; WCHAR ucs2_char;
DWORD state; DWORD state;
} key; };
struct { struct win_mouse {
struct win_coord pos; struct win_coord pos;
DWORD but; DWORD but;
DWORD state; DWORD state;
@ -63,8 +49,24 @@ struct win_rec {
DWORD wheel : 2; DWORD wheel : 2;
}; };
}; };
} mouse; };
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 win_key key;
struct win_mouse mouse;
struct win_coord window; struct win_coord window;
}; };
}; };
@ -117,47 +119,26 @@ bool PlatformGetRefreshRate(u16f *out)
return true; return true;
} }
size_t ucs2_to_utf8(char *buf, u16f ucs2) bool dispatch_rec(
{
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 InputRecord *out, struct InputRecord *out,
struct InputString *str, struct StringBuffer *str,
struct win_rec *in struct win_rec *rec
) { ) {
switch (win_rec_type(in)) { u8f type = rec->type | (rec->is_mouse & rec->mouse.flags);
switch (type) {
case KEY_EVENT: case KEY_EVENT:
ParseButton(out, in->key.vk_code, in->key.is_down); ReadButton(out, rec->key.vk_code, rec->key.is_down);
str->len += ucs2_to_utf8(&str->buf[str->len], in->key.ucs2_char); str->len += UCS2ToUTF8(&str->buf[str->len], rec->key.ucs2_char);
return true; return true;
case MOUSE_MOVE: case MOUSE_MOVE:
ParseJoystick(out, 0, in->mouse.pos.x, in->mouse.pos.y); ReadJoystick(out, 0, rec->mouse.pos.x, rec->mouse.pos.y);
return true; return true;
case MOUSE_VWHEEL: case MOUSE_VWHEEL:
case MOUSE_HWHEEL: case MOUSE_HWHEEL:
ParseAxis(out, in->mouse.is_hwheel, in->mouse.but); ReadAxis(out, rec->mouse.is_hwheel, rec->mouse.but);
return true; return true;
case WINDOW_BUFFER_SIZE_EVENT: case WINDOW_BUFFER_SIZE_EVENT:
@ -168,7 +149,7 @@ bool read_rec(
return false; return false;
} }
bool PlatformReadInput(struct InputBuffer *in, struct InputString *str) bool PlatformReadInput(struct RecordBuffer *in, struct StringBuffer *str)
{ {
DWORD max_records = IO_BUF_SIZE - in->len; DWORD max_records = IO_BUF_SIZE - in->len;
struct win_rec win_buf[max_records]; struct win_rec win_buf[max_records];
@ -177,10 +158,17 @@ bool PlatformReadInput(struct InputBuffer *in, struct InputString *str)
if (!ReadConsoleInputW(win.input_hand, win_buf, max_records, &filled)) if (!ReadConsoleInputW(win.input_hand, win_buf, max_records, &filled))
return false; return false;
Time now = TimeNow();
for (size_t i = 0; i < filled; i++) { for (size_t i = 0; i < filled; i++) {
if (read_rec(in, str, win_buf + i)) size_t rec_i = (in->start + in->len) % IO_BUF_SIZE;
struct InputRecord *rec = &in->buf[rec_i];
if (dispatch_rec(rec, str, win_buf + i)) {
rec->time = now;
in->len += 1; in->len += 1;
} }
}
return true; return true;
} }

View file

@ -40,7 +40,7 @@ int main()
CreateEvent(&game.Update); CreateEvent(&game.Update);
struct InputThreadHandle input_hand; struct InputThreadHandle input_hand;
if (!BeginInputThread(&input_hand, &ctrl.buf)) if (!BeginInputThread(&input_hand, &ctrl.recs, &ctrl.str))
ErrorExit("Input handle failed to initialize"); ErrorExit("Input handle failed to initialize");
CtrlMap(&ctrl, 0, BUTTON, 'A'); CtrlMap(&ctrl, 0, BUTTON, 'A');