uikhj
This commit is contained in:
Julia 2024-04-16 17:14:53 -05:00
parent f64b77ac21
commit e856594741
15 changed files with 200 additions and 125 deletions

View file

@ -5,17 +5,17 @@
#include "win.h"
#endif
double GetTime()
struct timespec TimeNow()
{
struct timespec ts;
timespec_get(&ts, TIME_UTC);
return ts;
}
double TimeNowDouble()
{
struct timespec ts;
timespec_get(&ts, TIME_UTC);
return ts.tv_sec + (double)ts.tv_nsec / 1000000000.0;
}
bool Wait(double seconds)
{
#ifdef _WIN32
return WindowsWait(seconds);
#endif
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdbool.h>
double GetTime();
struct timespec TimeNow();
bool Wait(double seconds);
double TimeNowDouble();

View file

@ -9,50 +9,9 @@
#include "fumotris.h"
#include "hash.h"
#include "input.h"
#define IO_BUF_SIZE 16
enum InputType {
BUTTON,
AXIS,
JOYSTICK,
ESCAPE
};
struct Button {
u64 value;
};
struct Axis {
i64 value;
};
struct Joystick {
i32 x;
i32 y;
};
union InputData {
struct Button input_but;
struct Axis input_axis;
struct Joystick input_js;
};
struct InputRecord {
u16f bind;
struct timespec timestamp;
u8 type;
u8 is_down;
u8 is_held;
u8 is_up;
union {
struct Button but;
struct Axis axis;
struct Joystick js;
union InputData data;
};
};
struct InputAxis {
struct CtrlAxis {
struct timespec last_pressed;
struct timespec last_released;
@ -78,25 +37,20 @@ struct ctrl_dict {
u16 value;
u8 type;
struct InputAxis *axis;
struct CtrlAxis *axis;
} *bkts;
};
struct InputBuffer {
size_t len;
struct InputRecord records[IO_BUF_SIZE];
};
struct Controller {
struct ctrl_dict codes;
struct ctrl_dict binds;
struct InputAxis *axes;
struct CtrlAxis *axes;
struct InputBuffer input_buf;
struct {
size_t len;
struct InputAxis *axes[IO_BUF_SIZE];
struct CtrlAxis *axes[IO_BUF_SIZE];
} pending_buf;
};
@ -104,7 +58,7 @@ bool NewCtrl(struct Controller *ctrl, size_t code_cap, size_t bind_cap)
{
struct ctrl_bkt *code_bkts = calloc(code_cap, sizeof(struct ctrl_bkt));
struct ctrl_bkt *bind_bkts = calloc(bind_cap, sizeof(struct ctrl_bkt));
struct InputAxis *axes = calloc(code_cap, sizeof(struct InputAxis));
struct CtrlAxis *axes = calloc(code_cap, sizeof(struct CtrlAxis));
if (code_bkts == nullptr or bind_bkts == nullptr or axes == nullptr)
return false;
@ -126,7 +80,9 @@ bool NewCtrl(struct Controller *ctrl, size_t code_cap, size_t bind_cap)
},
.axes = axes,
.input_buf.len = 0,
.input_buf = (struct InputBuffer) {
.len = 0,
},
.pending_buf.len = 0,
};
return true;
@ -211,7 +167,7 @@ next:
return nullptr;
}
struct InputAxis *find_axis(struct ctrl_dict *dict, u16f value, u8f type)
struct CtrlAxis *find_axis(struct ctrl_dict *dict, u16f value, u8f type)
{
struct ctrl_bkt *bkt = find(dict, value, type);
if (bkt == nullptr)
@ -241,7 +197,7 @@ bool CtrlMap(struct Controller *ctrl, u16f code, u16f bind, u8f type)
return true;
}
struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type)
struct CtrlAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type)
{
struct ctrl_bkt *code_bkt = find(&ctrl->codes, code, type);
if (code_bkt == nullptr)
@ -250,7 +206,7 @@ struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type)
return code_bkt->axis;
}
void dispatch_update(struct InputAxis *axis, struct InputRecord *rec)
void dispatch_update(struct CtrlAxis *axis, struct InputRecord *rec)
{
if (rec->is_down and !axis->is_held) {
axis->is_down = true;
@ -268,7 +224,7 @@ void dispatch_update(struct InputAxis *axis, struct InputRecord *rec)
bool CtrlPoll(struct Controller *ctrl)
{
for (size_t i = 0; i < ctrl->pending_buf.len; i++) {
struct InputAxis *axis = ctrl->pending_buf.axes[i];
struct CtrlAxis *axis = ctrl->pending_buf.axes[i];
axis->is_up = false;
axis->is_down = false;
@ -277,7 +233,7 @@ bool CtrlPoll(struct Controller *ctrl)
for (size_t i = 0; i < ctrl->input_buf.len; i++) {
struct InputRecord *rec = &ctrl->input_buf.records[i];
struct InputAxis *axis = find_axis(&ctrl->binds, rec->bind, rec->type);
struct CtrlAxis *axis = find_axis(&ctrl->binds, rec->bind, rec->type);
if (axis == nullptr)
continue;
@ -308,7 +264,7 @@ int main()
CtrlPoll(&ctrl);
struct InputAxis *a = CtrlGet(&ctrl, 123, BUTTON);
struct CtrlAxis *a = CtrlGet(&ctrl, 123, BUTTON);
printf("%u\n", a->but.value);
printf("success");

View file

@ -53,7 +53,17 @@ struct InputRecord {
};
};
struct InputAxis {
struct InputBuffer {
size_t len;
size_t start;
struct InputRecord records[IO_BUF_SIZE];
};
void InputBufferTransfer(struct InputBuffer *tmp, struct InputBuffer *dest);
void InputBufferCopy(struct InputBuffer *buf, struct InputRecord *src);
struct CtrlAxis {
struct timespec last_pressed;
struct timespec last_released;
@ -94,25 +104,20 @@ struct ctrl_dict {
u16 value;
u8 type;
struct InputAxis *axis;
struct CtrlAxis *axis;
} *bkts;
};
struct InputBuffer {
size_t len;
struct InputRecord records[IO_BUF_SIZE];
};
struct Controller {
struct ctrl_dict codes;
struct ctrl_dict binds;
struct InputAxis *axes;
struct CtrlAxis *axes;
struct InputBuffer input_buf;
struct {
size_t len;
struct InputAxis *axes[IO_BUF_SIZE];
struct CtrlAxis *axes[IO_BUF_SIZE];
} pending_buf;
};
@ -122,6 +127,6 @@ void FreeCtrl(struct Controller *ctrl);
bool CtrlMap(struct Controller *ctrl, u16f code, u16f bind, u8f type);
struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type);
struct CtrlAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type);
bool CtrlPoll(struct Controller *ctrl);

View file

@ -5,45 +5,162 @@
#include <stdio.h>
#include <stdlib.h>
#include "ctrl.h"
#include "fumotris.h"
#include "platform.h"
#ifdef _WIN32
#include "win.h"
#endif
#define IO_BUF_SIZE 16
struct Input {
struct Controller ctrl;
pthread_t thread;
pthread_mutex_t access_mutex;
enum InputType {
BUTTON,
AXIS,
JOYSTICK,
ESCAPE
};
void *block_input(void *args_ptr)
struct Button {
u64 value;
};
struct Axis {
i64 value;
};
struct Joystick {
i32 x;
i32 y;
};
union InputData {
struct Button input_but;
struct Axis input_axis;
struct Joystick input_js;
};
struct InputRecord {
u16f bind;
struct timespec timestamp;
u8 type;
u8 is_down;
u8 is_held;
u8 is_up;
union {
struct Button but;
struct Axis axis;
struct Joystick js;
union InputData data;
};
};
struct InputBuffer {
size_t len;
size_t start;
struct InputRecord records[IO_BUF_SIZE];
};
struct InputRecord *in_buf_get(struct InputBuffer *buf, size_t i)
{
struct Input *in = args_ptr;
struct InputBuffer tmp_buf = { .len = 0 };
return buf->records + (buf->start + 1) % IO_BUF_SIZE;
}
while (true) {
if (!PlatformBlockInput(&tmp_buf))
return false;
void InputBufferTransfer(struct InputBuffer *tmp, struct InputBuffer *dest)
{
size_t n = IO_BUF_SIZE - (tmp->len > dest->len ? tmp->len : dest->len);
pthread_mutex_lock(&in->access_mutex);
for (size_t i = 0; i < n; i++) {
*in_buf_get(dest, dest->len + i) = *in_buf_get(tmp, i);
}
if (n < tmp->len)
tmp->start += n;
tmp->len -= n;
dest->len += n;
}
void InputBufferCopy(struct InputBuffer *buf, struct InputRecord *src)
{
buf->records[(buf->start + buf->len) % IO_BUF_SIZE] = *src;
buf->len += 1;
}
struct thread_init {
pthread_mutex_t mutex;
pthread_cond_t cond;
bool done;
void *args;
};
struct input_args {
struct InputBuffer *buf;
pthread_mutex_t *mutex;
};
bool ThreadSignalInit()
{
}
pthread_mutex_unlock(&in->access_mutex);
void *block_input(void *args)
{
struct input_args *args = args + 1;
pthread_mutex_lock(&args->init.mutex);
args->init.is_init = true;
pthread_cond_signal(&args->init.cond);
pthread_mutex_unlock(&args->init.mutex);
struct InputBuffer tmp_buf = { .len = 0, .start = 0 };
while (true) {
if (!PlatformReadInput(&tmp_buf))
return false;
pthread_mutex_lock(&in->mutex);
{
InputBufferTransfer(&tmp_buf, buf);
}
pthread_mutex_unlock(&in->mutex);
}
return nullptr;
}
bool StartInput(struct Input *in)
void *thread_wrap(void *init_ptr)
{
return pthread_create(&in->thread, nullptr, block_input, in) == 0;
struct thread_init *init = init_ptr;
block_input();
}
bool JoinInput(struct Input *in)
bool ThreadWaitInit(void *(*func), size_t args_len, void *args)
{
return pthread_join(in->thread, nullptr) == 0;
struct thread_init init = {
.mutex = PTHREAD_MUTEX_INITIALIZER,
.cond = PTHREAD_COND_INITIALIZER,
.done = false,
.args = &args,
};
pthread_t thread;
if (pthread_create(&thread, nullptr, thread_wrap, &init) != 0)
return false;
pthread_mutex_lock(&init.mutex);
{
while (!init.done)
pthread_cond_wait(&init.cond, &init.mutex);
}
pthread_mutex_unlock(&init.mutex);
pthread_mutex_destroy(&init.mutex);
pthread_cond_destroy(&init.cond);
}
bool InputStart(struct InputBuffer *buf, pthread_mutex_t *mutex)
{
struct input_args args = {
.buf = buf,
.mutex = mutex,
};
return ThreadWaitInit(block_input, &args);
}

View file

@ -12,7 +12,7 @@ struct Input {
struct Controller ctrl;
pthread_t thread;
pthread_mutex_t access_mutex;
pthread_mutex_t mutex;
};
bool StartInput(struct Input *in);

View file

View file

@ -0,0 +1,4 @@
#pragma once
#ifdef _WIN32
#include "win.h"
#endif

View file

@ -4,22 +4,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include "fumotris.h"
#include "ctrl.h"
#include "gametime.h"
static struct Windows {
HANDLE in_handle;
HANDLE timer;
DWORD in_len;
INPUT_RECORD in_buf[IO_BUF_SIZE];
HANDLE input_handle;
DWORD input_n;
INPUT_RECORD input_buf[IO_BUF_SIZE];
} win;
bool init_handles()
{
win.in_handle = GetStdHandle(STD_INPUT_HANDLE);
if (win.in_handle == INVALID_HANDLE_VALUE)
win.input_handle = GetStdHandle(STD_INPUT_HANDLE);
if (win.input_handle == INVALID_HANDLE_VALUE)
return false;
win.timer = CreateWaitableTimer(
@ -40,7 +40,7 @@ bool init_console()
| ENABLE_PROCESSED_OUTPUT
| ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT;
return SetConsoleMode(win.in_handle, mode) != 0;
return SetConsoleMode(win.input_handle, mode) != 0;
}
bool PlatformInit()
@ -124,27 +124,23 @@ bool read_rec(struct InputRecord *rec, INPUT_RECORD win_rec)
return false;
}
bool PlatformBlockInput(struct InputBuffer *buf)
bool PlatformReadInput(struct InputBuffer *tmp)
{
if (!ReadConsoleInput(
win.in_handle, // Input handle
win.in_buf + buf->len, // Record buffer
IO_BUF_SIZE - buf->len, // Record buffer length
&win.in_len // Out number of records
win.input_handle, // Input handle
&win.input_buf[tmp->len], // Record buffer
IO_BUF_SIZE - tmp->len, // Record buffer length
&win.input_n // Out number of records
))
return false;
struct timespec now;
timespec_get(&now, TIME_UTC);
struct InputRecord rec = { .timestamp = TimeNow() };
for (size_t i = 0; i < win.input_n; i++) {
for (size_t i = 0; i < win.in_len; i++) {
struct InputRecord *rec = &buf->records[buf->len];
if (!read_rec(rec, win.in_buf[i]))
if (!read_rec(&rec, win.input_buf[i]))
continue;
rec->timestamp = now;
buf->len += 1;
InputBufferCopy(tmp, &rec);
}
return true;

View file

@ -12,6 +12,6 @@ bool PlatformInit();
bool PlatformGetRefreshRate(u16f *out);
bool PlatformBlockInput(struct InputBuffer *buf);
bool PlatformReadInput(struct InputBuffer *buf);
bool PlatformWait(struct timespec relative);

View file

@ -11,10 +11,7 @@
#include "term.h"
#include "tetr.h"
#include "event.h"
#ifdef _WIN32
#include "win.h"
#endif
#include "platform.h"
struct Instance {
struct Controller ctrl;