hi
uikhj
This commit is contained in:
parent
f64b77ac21
commit
e856594741
|
@ -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
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <stdbool.h>
|
||||
|
||||
double GetTime();
|
||||
struct timespec TimeNow();
|
||||
|
||||
bool Wait(double seconds);
|
||||
double TimeNowDouble();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
||||
|
||||
void InputBufferTransfer(struct InputBuffer *tmp, struct InputBuffer *dest)
|
||||
{
|
||||
size_t n = IO_BUF_SIZE - (tmp->len > dest->len ? tmp->len : dest->len);
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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 (!PlatformBlockInput(&tmp_buf))
|
||||
if (!PlatformReadInput(&tmp_buf))
|
||||
return false;
|
||||
|
||||
pthread_mutex_lock(&in->access_mutex);
|
||||
pthread_mutex_lock(&in->mutex);
|
||||
{
|
||||
|
||||
InputBufferTransfer(&tmp_buf, buf);
|
||||
}
|
||||
pthread_mutex_unlock(&in->access_mutex);
|
||||
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);
|
||||
}
|
|
@ -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);
|
||||
|
|
0
source/io/platforms/platform.c
Normal file
0
source/io/platforms/platform.c
Normal file
4
source/io/platforms/platform.h
Normal file
4
source/io/platforms/platform.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#ifdef _WIN32
|
||||
#include "win.h"
|
||||
#endif
|
|
@ -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);
|
||||
|
||||
for (size_t i = 0; i < win.in_len; i++) {
|
||||
struct InputRecord *rec = &buf->records[buf->len];
|
||||
struct InputRecord rec = { .timestamp = TimeNow() };
|
||||
for (size_t i = 0; i < win.input_n; i++) {
|
||||
|
||||
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;
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue