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 int64_t i64;
|
||||||
typedef int_fast64_t i64f;
|
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 "fumotris.h"
|
||||||
#include "hash.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 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 CtrlAxis {
|
||||||
struct timespec last_pressed;
|
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 {
|
struct ctrl_dict {
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
size_t filled;
|
size_t filled;
|
||||||
|
|
|
@ -89,56 +89,34 @@ struct input_args {
|
||||||
|
|
||||||
void *block_input(struct input_args *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 };
|
struct InputBuffer tmp_buf = { .len = 0, .start = 0 };
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!PlatformReadInput(&tmp_buf))
|
if (!PlatformReadInput(&tmp_buf))
|
||||||
return false;
|
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;
|
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)
|
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,
|
.buf = buf,
|
||||||
.mutex = mutex,
|
.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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "ctrl.h"
|
|
||||||
#include "fumotris.h"
|
#include "fumotris.h"
|
||||||
|
|
||||||
struct Input {
|
#define IO_BUF_SIZE 16
|
||||||
struct Controller ctrl;
|
|
||||||
|
|
||||||
pthread_t thread;
|
enum InputType {
|
||||||
pthread_mutex_t mutex;
|
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 "ctrl.h"
|
||||||
#include "gametime.h"
|
#include "gametime.h"
|
||||||
|
|
||||||
static struct Windows {
|
static struct windows {
|
||||||
HANDLE timer;
|
HANDLE timer;
|
||||||
HANDLE input_handle;
|
HANDLE input_handle;
|
||||||
DWORD input_n;
|
|
||||||
INPUT_RECORD input_buf[IO_BUF_SIZE];
|
|
||||||
} win;
|
} win;
|
||||||
|
|
||||||
bool init_handles()
|
bool init_handles()
|
||||||
|
@ -22,11 +20,7 @@ bool init_handles()
|
||||||
if (win.input_handle == INVALID_HANDLE_VALUE)
|
if (win.input_handle == INVALID_HANDLE_VALUE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
win.timer = CreateWaitableTimer(
|
win.timer = CreateWaitableTimerW(NULL, TRUE, NULL);
|
||||||
NULL, // Timer attributes
|
|
||||||
TRUE, // Manual reset
|
|
||||||
NULL // Name
|
|
||||||
);
|
|
||||||
if (win.timer == NULL)
|
if (win.timer == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -40,6 +34,7 @@ bool init_console()
|
||||||
| ENABLE_PROCESSED_OUTPUT
|
| ENABLE_PROCESSED_OUTPUT
|
||||||
| ENABLE_MOUSE_INPUT
|
| ENABLE_MOUSE_INPUT
|
||||||
| ENABLE_WINDOW_INPUT;
|
| ENABLE_WINDOW_INPUT;
|
||||||
|
|
||||||
return SetConsoleMode(win.input_handle, mode) != 0;
|
return SetConsoleMode(win.input_handle, mode) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,60 +55,53 @@ bool PlatformGetRefreshRate(u16f *out)
|
||||||
mode.dmSize = sizeof(DEVMODE);
|
mode.dmSize = sizeof(DEVMODE);
|
||||||
mode.dmDriverExtra = 0;
|
mode.dmDriverExtra = 0;
|
||||||
|
|
||||||
if(!EnumDisplaySettingsA(
|
if(!EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &mode))
|
||||||
NULL, // Device name (null for current)
|
|
||||||
ENUM_CURRENT_SETTINGS, // Mode
|
|
||||||
&mode // Out
|
|
||||||
))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*out = mode.dmDisplayFrequency;
|
*out = mode.dmDisplayFrequency;
|
||||||
return true;
|
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->type = BUTTON;
|
||||||
rec->bind = win_key.wVirtualKeyCode;
|
rec->bind = win_key->wVirtualKeyCode;
|
||||||
|
|
||||||
rec->is_down = win_key.bKeyDown;
|
rec->is_down = win_key->bKeyDown;
|
||||||
rec->is_up = !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->type = JOYSTICK;
|
||||||
rec->bind = 0;
|
rec->bind = 0;
|
||||||
rec->js.x = win_mouse.dwMousePosition.X;
|
rec->js.x = win_mouse->dwMousePosition.X;
|
||||||
rec->js.y = win_mouse.dwMousePosition.Y;
|
rec->js.y = win_mouse->dwMousePosition.Y;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win_mouse.dwEventFlags == MOUSE_WHEELED) {
|
if (win_mouse->dwEventFlags & (MOUSE_WHEELED | MOUSE_HWHEELED) != 0) {
|
||||||
rec->bind = 0;
|
rec->type = AXIS;
|
||||||
} else if (win_mouse.dwEventFlags == MOUSE_HWHEELED) {
|
rec->bind = win_mouse->dwEventFlags == MOUSE_WHEELED;
|
||||||
rec->bind = 1;
|
rec->axis.value = win_mouse->dwButtonState;
|
||||||
} else {
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec->type = AXIS;
|
return false;
|
||||||
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:
|
case KEY_EVENT:
|
||||||
read_key_rec(rec, win_rec.Event.KeyEvent);
|
copy_key_event(rec, &win_rec->Event.KeyEvent);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MOUSE_EVENT:
|
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:
|
case WINDOW_BUFFER_SIZE_EVENT:
|
||||||
return false;
|
return false;
|
||||||
|
@ -124,23 +112,22 @@ bool read_rec(struct InputRecord *rec, INPUT_RECORD win_rec)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlatformReadInput(struct InputBuffer *tmp)
|
bool PlatformReadInput(struct InputBuffer *buf)
|
||||||
{
|
{
|
||||||
if (!ReadConsoleInput(
|
DWORD max_records = IO_BUF_SIZE - buf->len;
|
||||||
win.input_handle, // Input handle
|
INPUT_RECORD win_buf[max_records];
|
||||||
&win.input_buf[tmp->len], // Record buffer
|
|
||||||
IO_BUF_SIZE - tmp->len, // Record buffer length
|
DWORD filled;
|
||||||
&win.input_n // Out number of records
|
if (!ReadConsoleInputW(win.input_handle, win_buf, max_records, &filled))
|
||||||
))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct InputRecord rec = { .timestamp = TimeNow() };
|
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;
|
continue;
|
||||||
|
|
||||||
InputBufferCopy(tmp, &rec);
|
InputBufferCopy(buf, &rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -151,14 +138,7 @@ bool PlatformWait(struct timespec relative)
|
||||||
LARGE_INTEGER duration;
|
LARGE_INTEGER duration;
|
||||||
duration.QuadPart = -10000000 * relative.tv_sec - relative.tv_nsec / 100;
|
duration.QuadPart = -10000000 * relative.tv_sec - relative.tv_nsec / 100;
|
||||||
|
|
||||||
if (!SetWaitableTimer(
|
if (!SetWaitableTimer(win.timer, &duration, 0, NULL,NULL, FALSE))
|
||||||
win.timer, // Timer
|
|
||||||
&duration, // Duration
|
|
||||||
0, // Period
|
|
||||||
NULL, // Completion coroutine
|
|
||||||
NULL, // Completion coroutine arg
|
|
||||||
FALSE // Resume
|
|
||||||
))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DWORD result = WaitForSingleObject(win.timer, INFINITE);
|
DWORD result = WaitForSingleObject(win.timer, INFINITE);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "ctrl.h"
|
#include "ctrl.h"
|
||||||
|
#include "input.h"
|
||||||
#include "fumotris.h"
|
#include "fumotris.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "tetr.h"
|
#include "tetr.h"
|
||||||
|
@ -140,13 +141,11 @@ int main()
|
||||||
if (!Start(&game))
|
if (!Start(&game))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
if(!PlatformInit(&game.term))
|
if(!PlatformInit())
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
StartInput(&game.ctrl);
|
InputStart(&game.ctrl.input_buf, );
|
||||||
Loop(&game);
|
Loop(&game);
|
||||||
|
|
||||||
JoinInput(&game.ctrl);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in a new issue