sadf
agagfdagdfs
This commit is contained in:
parent
36fe01f783
commit
21a56c3566
|
@ -27,3 +27,18 @@ typedef int_fast32_t i32f;
|
|||
|
||||
typedef int64_t i64;
|
||||
typedef int_fast64_t i64f;
|
||||
|
||||
enum CtrlCode {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
SOFT_DROP,
|
||||
HARD_DROP,
|
||||
ROTATE_CCW,
|
||||
ROTATE_CW,
|
||||
ROTATE_180,
|
||||
SWAP,
|
||||
ESC,
|
||||
VSCROLL,
|
||||
HSCROLL,
|
||||
MOUSE
|
||||
};
|
|
@ -10,58 +10,7 @@
|
|||
|
||||
#include "fumotris.h"
|
||||
#include "hash.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 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);
|
||||
#include "input.h"
|
||||
|
||||
struct CtrlAxis {
|
||||
struct timespec last_pressed;
|
||||
|
@ -80,21 +29,6 @@ struct CtrlAxis {
|
|||
};
|
||||
};
|
||||
|
||||
enum CtrlCode {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
SOFT_DROP,
|
||||
HARD_DROP,
|
||||
ROTATE_CCW,
|
||||
ROTATE_CW,
|
||||
ROTATE_180,
|
||||
SWAP,
|
||||
ESC,
|
||||
VSCROLL,
|
||||
HSCROLL,
|
||||
MOUSE
|
||||
};
|
||||
|
||||
struct ctrl_dict {
|
||||
size_t capacity;
|
||||
size_t filled;
|
||||
|
|
|
@ -89,56 +89,34 @@ struct input_args {
|
|||
|
||||
void *block_input(struct input_args *args)
|
||||
{
|
||||
struct input_args async = *args;
|
||||
struct InputBuffer *buf = args->buf;
|
||||
pthread_mutex_t *mutex = args->mutex;
|
||||
free(args);
|
||||
|
||||
pthread_mutex_t *mutex = async.mutex;
|
||||
struct InputBuffer *ctrl_buf = async.buf;
|
||||
struct InputBuffer tmp_buf = { .len = 0, .start = 0 };
|
||||
|
||||
while (true) {
|
||||
if (!PlatformReadInput(&tmp_buf))
|
||||
return false;
|
||||
|
||||
pthread_mutex_lock(&args->mutex);
|
||||
pthread_mutex_lock(mutex);
|
||||
{
|
||||
InputBufferTransfer(&tmp_buf, async.buf);
|
||||
InputBufferTransfer(&tmp_buf, buf);
|
||||
}
|
||||
pthread_mutex_unlock(async.mutex);
|
||||
pthread_mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *thread_wrap(void *init_ptr)
|
||||
{
|
||||
struct thread_init *init = init_ptr;
|
||||
|
||||
block_input();
|
||||
}
|
||||
|
||||
bool ThreadWaitInit(void *(*func), size_t args_len, void *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 = {
|
||||
struct input_args *args = malloc(sizeof(struct input_args));
|
||||
*args = (struct input_args) {
|
||||
.buf = buf,
|
||||
.mutex = mutex,
|
||||
};
|
||||
|
||||
return ThreadWaitInit(block_input, &args);
|
||||
pthread_t thread;
|
||||
return pthread_create(&thread, nullptr, block_input, args) == 0;
|
||||
}
|
|
@ -5,16 +5,58 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ctrl.h"
|
||||
#include "fumotris.h"
|
||||
|
||||
struct Input {
|
||||
struct Controller ctrl;
|
||||
#define IO_BUF_SIZE 16
|
||||
|
||||
pthread_t thread;
|
||||
pthread_mutex_t mutex;
|
||||
enum InputType {
|
||||
BUTTON,
|
||||
AXIS,
|
||||
JOYSTICK,
|
||||
ESCAPE
|
||||
};
|
||||
|
||||
bool StartInput(struct Input *in);
|
||||
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;
|
||||
};
|
||||
|
||||
bool JoinInput(struct Input *in);
|
||||
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];
|
||||
};
|
||||
|
||||
void InputBufferTransfer(struct InputBuffer *tmp, struct InputBuffer *dest);
|
||||
|
||||
void InputBufferCopy(struct InputBuffer *buf, struct InputRecord *src);
|
||||
|
||||
bool InputStart(struct InputBuffer *buf, pthread_mutex_t *mutex);
|
|
@ -9,11 +9,9 @@
|
|||
#include "ctrl.h"
|
||||
#include "gametime.h"
|
||||
|
||||
static struct Windows {
|
||||
static struct windows {
|
||||
HANDLE timer;
|
||||
HANDLE input_handle;
|
||||
DWORD input_n;
|
||||
INPUT_RECORD input_buf[IO_BUF_SIZE];
|
||||
} win;
|
||||
|
||||
bool init_handles()
|
||||
|
@ -22,11 +20,7 @@ bool init_handles()
|
|||
if (win.input_handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
win.timer = CreateWaitableTimer(
|
||||
NULL, // Timer attributes
|
||||
TRUE, // Manual reset
|
||||
NULL // Name
|
||||
);
|
||||
win.timer = CreateWaitableTimerW(NULL, TRUE, NULL);
|
||||
if (win.timer == NULL)
|
||||
return false;
|
||||
|
||||
|
@ -40,6 +34,7 @@ bool init_console()
|
|||
| ENABLE_PROCESSED_OUTPUT
|
||||
| ENABLE_MOUSE_INPUT
|
||||
| ENABLE_WINDOW_INPUT;
|
||||
|
||||
return SetConsoleMode(win.input_handle, mode) != 0;
|
||||
}
|
||||
|
||||
|
@ -60,60 +55,53 @@ bool PlatformGetRefreshRate(u16f *out)
|
|||
mode.dmSize = sizeof(DEVMODE);
|
||||
mode.dmDriverExtra = 0;
|
||||
|
||||
if(!EnumDisplaySettingsA(
|
||||
NULL, // Device name (null for current)
|
||||
ENUM_CURRENT_SETTINGS, // Mode
|
||||
&mode // Out
|
||||
))
|
||||
if(!EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &mode))
|
||||
return false;
|
||||
|
||||
*out = mode.dmDisplayFrequency;
|
||||
return true;
|
||||
}
|
||||
|
||||
void read_key_rec(struct InputRecord *rec, KEY_EVENT_RECORD win_key)
|
||||
void copy_key_event(struct InputRecord *rec, KEY_EVENT_RECORD *win_key)
|
||||
{
|
||||
rec->type = BUTTON;
|
||||
rec->bind = win_key.wVirtualKeyCode;
|
||||
rec->bind = win_key->wVirtualKeyCode;
|
||||
|
||||
rec->is_down = win_key.bKeyDown;
|
||||
rec->is_up = !win_key.bKeyDown;
|
||||
rec->is_down = win_key->bKeyDown;
|
||||
rec->is_up = !win_key->bKeyDown;
|
||||
}
|
||||
|
||||
bool read_mouse_rec(struct InputRecord *rec, MOUSE_EVENT_RECORD win_mouse)
|
||||
bool copy_mouse_event(struct InputRecord *rec, MOUSE_EVENT_RECORD *win_mouse)
|
||||
{
|
||||
if (win_mouse.dwEventFlags == MOUSE_MOVED) {
|
||||
if (win_mouse->dwEventFlags == MOUSE_MOVED) {
|
||||
rec->type = JOYSTICK;
|
||||
rec->bind = 0;
|
||||
rec->js.x = win_mouse.dwMousePosition.X;
|
||||
rec->js.y = win_mouse.dwMousePosition.Y;
|
||||
rec->js.x = win_mouse->dwMousePosition.X;
|
||||
rec->js.y = win_mouse->dwMousePosition.Y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (win_mouse->dwEventFlags & (MOUSE_WHEELED | MOUSE_HWHEELED) != 0) {
|
||||
rec->type = AXIS;
|
||||
rec->bind = win_mouse->dwEventFlags == MOUSE_WHEELED;
|
||||
rec->axis.value = win_mouse->dwButtonState;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (win_mouse.dwEventFlags == MOUSE_WHEELED) {
|
||||
rec->bind = 0;
|
||||
} else if (win_mouse.dwEventFlags == MOUSE_HWHEELED) {
|
||||
rec->bind = 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
rec->type = AXIS;
|
||||
rec->axis.value = win_mouse.dwButtonState;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_rec(struct InputRecord *rec, INPUT_RECORD win_rec)
|
||||
bool copy_rec(struct InputRecord *rec, INPUT_RECORD *win_rec)
|
||||
{
|
||||
switch (win_rec.EventType) {
|
||||
switch (win_rec->EventType) {
|
||||
case KEY_EVENT:
|
||||
read_key_rec(rec, win_rec.Event.KeyEvent);
|
||||
copy_key_event(rec, &win_rec->Event.KeyEvent);
|
||||
return true;
|
||||
|
||||
case MOUSE_EVENT:
|
||||
return read_mouse_rec(rec, win_rec.Event.MouseEvent);
|
||||
return copy_mouse_event(rec, &win_rec->Event.MouseEvent);
|
||||
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
return false;
|
||||
|
@ -124,23 +112,22 @@ bool read_rec(struct InputRecord *rec, INPUT_RECORD win_rec)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PlatformReadInput(struct InputBuffer *tmp)
|
||||
bool PlatformReadInput(struct InputBuffer *buf)
|
||||
{
|
||||
if (!ReadConsoleInput(
|
||||
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
|
||||
))
|
||||
DWORD max_records = IO_BUF_SIZE - buf->len;
|
||||
INPUT_RECORD win_buf[max_records];
|
||||
|
||||
DWORD filled;
|
||||
if (!ReadConsoleInputW(win.input_handle, win_buf, max_records, &filled))
|
||||
return false;
|
||||
|
||||
struct InputRecord rec = { .timestamp = TimeNow() };
|
||||
for (size_t i = 0; i < win.input_n; i++) {
|
||||
|
||||
if (!read_rec(&rec, win.input_buf[i]))
|
||||
for (size_t i = 0; i < filled; i++) {
|
||||
if (!copy_rec(&rec, win_buf + i))
|
||||
continue;
|
||||
|
||||
InputBufferCopy(tmp, &rec);
|
||||
InputBufferCopy(buf, &rec);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -151,14 +138,7 @@ bool PlatformWait(struct timespec relative)
|
|||
LARGE_INTEGER duration;
|
||||
duration.QuadPart = -10000000 * relative.tv_sec - relative.tv_nsec / 100;
|
||||
|
||||
if (!SetWaitableTimer(
|
||||
win.timer, // Timer
|
||||
&duration, // Duration
|
||||
0, // Period
|
||||
NULL, // Completion coroutine
|
||||
NULL, // Completion coroutine arg
|
||||
FALSE // Resume
|
||||
))
|
||||
if (!SetWaitableTimer(win.timer, &duration, 0, NULL,NULL, FALSE))
|
||||
return false;
|
||||
|
||||
DWORD result = WaitForSingleObject(win.timer, INFINITE);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "ctrl.h"
|
||||
#include "input.h"
|
||||
#include "fumotris.h"
|
||||
#include "term.h"
|
||||
#include "tetr.h"
|
||||
|
@ -140,13 +141,11 @@ int main()
|
|||
if (!Start(&game))
|
||||
exit(1);
|
||||
|
||||
if(!PlatformInit(&game.term))
|
||||
if(!PlatformInit())
|
||||
exit(1);
|
||||
|
||||
StartInput(&game.ctrl);
|
||||
InputStart(&game.ctrl.input_buf, );
|
||||
Loop(&game);
|
||||
|
||||
JoinInput(&game.ctrl);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue