kjhjk
This commit is contained in:
Julia 2024-04-11 14:57:22 -05:00
parent 878fbdd934
commit 3767bfc036
9 changed files with 288 additions and 327 deletions

BIN
hi.exe

Binary file not shown.

View file

@ -13,44 +13,60 @@
#define IO_BUF_SIZE 16 #define IO_BUF_SIZE 16
enum InputType { enum InputType {
KEY, BUTTON,
AXIS, AXIS,
JOYSTICK, JOYSTICK,
ESCAPE ESCAPE
}; };
struct Input { 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 type;
u8 is_down; u8 is_down;
u8 is_held; u8 is_held;
u8 is_up; u8 is_up;
union { union {
struct Button { struct Button but;
u64 value; struct Axis axis;
} but; struct Joystick js;
struct Axis { union InputData data;
i64 value;
} axis;
struct Joystick {
i32 x;
i32 y;
} js;
}; };
}; };
struct InputRecord {
u16f bind;
struct Input dat;
struct timespec timestamp;
};
struct InputAxis { struct InputAxis {
struct Input dat;
struct timespec last_pressed; struct timespec last_pressed;
struct timespec last_released; struct timespec last_released;
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 ctrl_dict { struct ctrl_dict {
@ -66,20 +82,21 @@ struct ctrl_dict {
} *bkts; } *bkts;
}; };
struct InputBuffer {
size_t len;
struct InputRecord records[IO_BUF_SIZE];
};
struct Controller { struct Controller {
struct ctrl_dict codes; struct ctrl_dict codes;
struct ctrl_dict binds; struct ctrl_dict binds;
struct InputAxis *axes; struct InputAxis *axes;
struct InputBuffer { struct InputBuffer input_buf;
struct InputRecord records[IO_BUF_SIZE];
size_t len;
size_t start;
} input_buf;
struct { struct {
size_t indexes[IO_BUF_SIZE];
size_t len; size_t len;
struct InputAxis *axes[IO_BUF_SIZE];
} pending_buf; } pending_buf;
}; };
@ -109,13 +126,8 @@ bool NewCtrl(struct Controller *ctrl, size_t code_cap, size_t bind_cap)
}, },
.axes = axes, .axes = axes,
.input_buf = { .input_buf.len = 0,
.len = 0, .pending_buf.len = 0,
.start = 0,
},
.pending_buf = {
.len = 0,
},
}; };
return true; return true;
} }
@ -238,73 +250,67 @@ struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type)
return code_bkt->axis; return code_bkt->axis;
} }
void update_key(struct InputAxis *axis, struct InputRecord *rec) void dispatch_update(struct InputAxis *axis, struct InputRecord *rec)
{ {
if (rec->but.is_down) { if (rec->is_down and !axis->is_held) {
axis->is_down = true;
axis->is_held = true;
axis->last_pressed = rec->timestamp; axis->last_pressed = rec->timestamp;
axis->but.is_held = true; } else if (rec->is_up) {
} else { axis->is_up = true;
axis->is_held = false;
axis->last_released = rec->timestamp; axis->last_released = rec->timestamp;
axis->but.is_held = false;
} }
axis->but.is_down |= rec->but.is_down; axis->data = rec->data;
axis->but.is_up |= rec->but.is_up;
}
void update_axis(struct InputAxis *axis, struct InputRecord *rec)
{
axis->axis.value = rec->axis.value;
axis->last_pressed = rec->timestamp;
}
void update_joystick(struct InputAxis *axis, struct InputRecord *rec)
{
axis->js.x = rec->js.x;
axis->js.y = rec->js.y;
axis->last_pressed = rec->timestamp;
}
bool dispatch_update(struct InputAxis *axis, struct InputRecord *rec)
{
switch (rec->type) {
case KEY:
update_key(axis, rec);
printf("axis:%hu\n", axis->but.is_down);
return true;
case AXIS:
update_axis(axis, rec);
return true;
case JOYSTICK:
update_joystick(axis, rec);
return true;
}
return false;
} }
bool CtrlPoll(struct Controller *ctrl) bool 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];
axis->is_up = false;
axis->is_down = false;
} }
ctrl->pending_buf.len = ctrl->input_buf.len;
for (size_t i = 0; i < ctrl->input_buf.len; i++) { for (size_t i = 0; i < ctrl->input_buf.len; i++) {
struct InputRecord *rec = &ctrl->input_buf.records[i]; struct InputRecord *rec = &ctrl->input_buf.records[i];
printf("i:%hu\n", rec->bind);
struct InputAxis *axis = find_axis(&ctrl->binds, rec->bind, rec->type); struct InputAxis *axis = find_axis(&ctrl->binds, rec->bind, rec->type);
if (axis == nullptr) if (axis == nullptr)
continue; continue;
if (!dispatch_update(axis, rec)) dispatch_update(axis, rec);
return false;
}
ctrl->pending_buf.axes[i] = axis;
}
ctrl->input_buf.len = 0; ctrl->input_buf.len = 0;
return true; return true;
} }
int main()
{
struct Controller ctrl;
if (!NewCtrl(&ctrl, 3, 3))
return 1;
CtrlMap(&ctrl, 123, 111, BUTTON);
ctrl.input_buf.records[ctrl.input_buf.len++] = (struct InputRecord) {
.bind = 111,
.type = BUTTON,
.is_down = true,
.but.value = 69
};
CtrlPoll(&ctrl);
struct InputAxis *a = CtrlGet(&ctrl, 123, BUTTON);
printf("%u\n", a->but.value);
printf("success");
return 0;
}

View file

@ -9,54 +9,65 @@
#include <time.h> #include <time.h>
#include "fumotris.h" #include "fumotris.h"
#include "hash.h"
#define IO_BUF_SIZE 16 #define IO_BUF_SIZE 16
enum InputType { enum InputType {
KEY, BUTTON,
AXIS, AXIS,
JOYSTICK, JOYSTICK,
ESCAPE ESCAPE
}; };
struct Button { struct Button {
u32 value; u64 value;
bool is_down;
bool is_held;
bool is_up;
}; };
struct Axis { struct Axis {
i64 value; i64 value;
}; };
struct Joystick { struct Joystick {
i32 x; i32 x;
i32 y; i32 y;
}; };
union InputData {
struct Button input_but;
struct Axis input_axis;
struct Joystick input_js;
};
struct InputRecord { struct InputRecord {
u16 bind; u16f bind;
struct timespec timestamp;
u8 type; u8 type;
u8 is_down;
u8 is_held;
u8 is_up;
union { union {
struct Button but; struct Button but;
struct Axis axis; struct Axis axis;
struct Joystick js; struct Joystick js;
union InputData data;
}; };
struct timespec timestamp;
}; };
struct InputAxis { struct InputAxis {
struct timespec last_pressed;
struct timespec last_released;
u8 type;
u8 is_down;
u8 is_held;
u8 is_up;
union { union {
struct Button but; struct Button but;
struct Axis axis; struct Axis axis;
struct Joystick js; struct Joystick js;
union InputData data;
}; };
struct timespec last_pressed;
struct timespec last_released;
}; };
enum CtrlCode { enum CtrlCode {
@ -74,8 +85,6 @@ enum CtrlCode {
MOUSE MOUSE
}; };
typedef u32 hashtype;
struct ctrl_dict { struct ctrl_dict {
size_t capacity; size_t capacity;
size_t filled; size_t filled;
@ -89,20 +98,21 @@ struct ctrl_dict {
} *bkts; } *bkts;
}; };
struct InputBuffer {
size_t len;
struct InputRecord records[IO_BUF_SIZE];
};
struct Controller { struct Controller {
struct ctrl_dict codes; struct ctrl_dict codes;
struct ctrl_dict binds; struct ctrl_dict binds;
struct InputAxis *axes; struct InputAxis *axes;
struct InputBuffer { struct InputBuffer input_buf;
struct InputRecord records[IO_BUF_SIZE];
size_t len;
size_t start;
} input_buf;
struct { struct {
size_t indexes[IO_BUF_SIZE];
size_t len; size_t len;
struct InputAxis *axes[IO_BUF_SIZE];
} pending_buf; } pending_buf;
}; };

View file

@ -19,11 +19,6 @@ struct Input {
pthread_mutex_t access_mutex; pthread_mutex_t access_mutex;
}; };
struct InputRecord *get_at(struct InputBuffer *buf, size_t i)
{
return &buf->records[(buf->start + i) % IO_BUF_SIZE];
}
void *block_input(void *args_ptr) void *block_input(void *args_ptr)
{ {
struct Input *in = args_ptr; struct Input *in = args_ptr;

View file

@ -3,19 +3,72 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <windows.h>
#include <time.h> #include <time.h>
#include <math.h>
#include "input.h" #include "fumotris.h"
#include "winhandler.h" #include "ctrl.h"
#include "term.h" #include "term.h"
bool WindowsInit(struct Terminal *term) struct Windows {
HANDLE in_handle;
HANDLE timer;
DWORD in_len;
INPUT_RECORD in_buf[IO_BUF_SIZE];
};
typedef struct Windows *platform;
bool WinInitHandles(struct Windows *win)
{ {
if (!WinInitHandles()) win->in_handle = GetStdHandle(STD_INPUT_HANDLE);
if (win->in_handle == INVALID_HANDLE_VALUE)
return false; return false;
if (!WinInitConsole()) win->timer = CreateWaitableTimer(
NULL, // Timer attributes
TRUE, // Manual reset
NULL // Name
);
if (win->timer == NULL)
return false;
return true;
}
bool WinInitConsole(struct Windows *win)
{
DWORD mode = ENABLE_EXTENDED_FLAGS
| ENABLE_PROCESSED_INPUT
| ENABLE_PROCESSED_OUTPUT
| ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT;
return SetConsoleMode(win->in_handle, mode) != 0;
}
bool WinGetRefreshRate(u16f *out)
{
DEVMODE mode;
mode.dmSize = sizeof(DEVMODE);
mode.dmDriverExtra = 0;
if(!EnumDisplaySettingsA(
NULL, // Device name (null for current)
ENUM_CURRENT_SETTINGS, // Mode
&mode // Out
))
return false;
*out = mode.dmDisplayFrequency;
return true;
}
bool WindowsInit(platform win, struct Terminal *term)
{
if (!WinInitHandles(win))
return false;
if (!WinInitConsole(win))
return false; return false;
if (!WinGetRefreshRate(&term->refresh_rate)) if (!WinGetRefreshRate(&term->refresh_rate))
@ -24,17 +77,103 @@ bool WindowsInit(struct Terminal *term)
return true; return true;
} }
bool WindowsBlockInput(struct RecordBuffer *buf) void read_key_rec(struct InputRecord *rec, KEY_EVENT_RECORD win_key)
{ {
return WinBlockInput(buf); rec->type = BUTTON;
rec->bind = win_key.wVirtualKeyCode;
rec->is_down = win_key.bKeyDown;
rec->is_up = !win_key.bKeyDown;
} }
bool WindowsWait(double seconds) bool read_mouse_rec(struct InputRecord *rec, MOUSE_EVENT_RECORD win_mouse)
{ {
struct timespec duration = { if (win_mouse.dwEventFlags == MOUSE_MOVED) {
.tv_sec = seconds, rec->type = JOYSTICK;
.tv_nsec = fmod(seconds, 1) * 1e9 rec->bind = 0;
}; rec->js.x = win_mouse.dwMousePosition.X;
rec->js.y = win_mouse.dwMousePosition.Y;
return WinWait(duration); 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)
{
switch (win_rec.EventType) {
case KEY_EVENT:
read_key_rec(rec, win_rec.Event.KeyEvent);
return true;
case MOUSE_EVENT:
return read_mouse_rec(rec, win_rec.Event.MouseEvent);
case WINDOW_BUFFER_SIZE_EVENT:
return false;
// TODO: Handle window resizing
}
rec->type = ESCAPE;
return false;
}
bool WinBlockInput(platform win, struct InputBuffer *buf)
{
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
))
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];
if (!read_rec(rec, win->in_buf[i]))
continue;
rec->timestamp = now;
buf->len += 1;
}
return true;
}
bool WinWait(platform win, 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
))
return false;
DWORD result = WaitForSingleObject(win->timer, INFINITE);
if (result != WAIT_OBJECT_0)
return false;
return true;
} }

View file

@ -1,16 +1,18 @@
#pragma once #pragma once
#include <pthread.h>
#include <iso646.h> #include <iso646.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include "input.h" #include "fumotris.h"
#include "term.h" #include "term.h"
bool WindowsInit(struct Terminal *term); typedef struct Windows *platform;
bool WindowsBlockInput(struct RecordBuffer *buf); bool WindowsInit(platform win, struct Terminal *term);
bool WindowsWait(double seconds); bool WinBlockInput(platform win, struct InputBuffer *buf);
bool WinWait(platform win, struct timespec relative);

View file

@ -1,173 +0,0 @@
#include <iso646.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#include "fumotris.h"
#include "gametime.h"
#include "input.h"
#include "term.h"
struct Windows {
HANDLE input_handle;
HANDLE timer;
};
static struct Windows win;
bool WinInitHandles()
{
win.input_handle = GetStdHandle(STD_INPUT_HANDLE);
if (win.input_handle == INVALID_HANDLE_VALUE)
return false;
win.timer = CreateWaitableTimer(
NULL, // Timer attributes
TRUE, // Manual reset
NULL // Name
);
if (!win.timer)
return false;
return true;
}
bool WinInitConsole()
{
DWORD mode = ENABLE_EXTENDED_FLAGS
| ENABLE_PROCESSED_INPUT
| ENABLE_PROCESSED_OUTPUT
| ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT;
return SetConsoleMode(win.input_handle, mode) != 0;
}
bool WinGetRefreshRate(u16f *out)
{
DEVMODE mode;
mode.dmSize = sizeof(DEVMODE);
mode.dmDriverExtra = 0;
if(!EnumDisplaySettingsA(
NULL, // Device name (null for current)
ENUM_CURRENT_SETTINGS, // Mode
&mode // Out
))
return false;
*out = mode.dmDisplayFrequency;
return true;
}
void set_key_record(struct InputRecord *rec, KEY_EVENT_RECORD win_key)
{
rec->type = KEY;
rec->bind = win_key.wVirtualKeyCode;
rec->but.is_down = win_key.bKeyDown;
rec->but.is_up = !win_key.bKeyDown;
if (win_key.wVirtualKeyCode == VK_ESCAPE)
rec->type = ESCAPE;
}
bool set_mouse_record(struct InputRecord *rec, MOUSE_EVENT_RECORD win_mouse)
{
switch (win_mouse.dwEventFlags) {
case MOUSE_WHEELED:
rec->type = AXIS;
rec->bind = 0;
rec->axis.value = win_mouse.dwButtonState;
break;
case MOUSE_HWHEELED:
rec->type = AXIS;
rec->bind = 1;
rec->axis.value = win_mouse.dwButtonState;
break;
case MOUSE_MOVED:
rec->type = JOYSTICK;
rec->bind = 0;
rec->js.x = win_mouse.dwMousePosition.X;
rec->js.y = win_mouse.dwMousePosition.Y;
break;
default:
return false;
}
return true;
}
bool dispatch_record(struct InputRecord *rec, INPUT_RECORD win_rec)
{
switch (win_rec.EventType) {
case KEY_EVENT:
set_key_record(rec, win_rec.Event.KeyEvent);
break;
case MOUSE_EVENT:
return set_mouse_record(rec, win_rec.Event.MouseEvent);
case WINDOW_BUFFER_SIZE_EVENT:
// TODO: Handle window resizing
return false;
default:
rec->type = ESCAPE;
}
return true;
}
bool WinBlockInput(struct Controller *ctrl)
{
size_t win_size = IO_BUF_SIZE - ctrl->input_buf.len;
INPUT_RECORD win_buf[win_size];
DWORD count;
if (!ReadConsoleInput(
win.input_handle, // Input handle
win_buf, // Record buffer
win_size, // Record buffer length
&count // Out number of records
))
return false;
struct timespec now;
timespec_get(&now, TIME_UTC);
pthread_mutex_lock(&buf->mutex);
for (size_t i = 0; i < count; i++) {
struct InputRecord rec;
rec.timestamp = now;
bool include = dispatch_record(&rec, win_buf[i]);
if (!include)
continue;
buf->records[buf->count++] = rec;
}
pthread_mutex_unlock(&buf->mutex);
return true;
}
bool WinWait(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
))
return false;
DWORD result = WaitForSingleObject(win.timer, INFINITE);
if (result != WAIT_OBJECT_0)
return false;
return true;
}

View file

@ -1,18 +0,0 @@
#pragma once
#include <iso646.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "fumotris.h"
bool WinInitHandles();
bool WinInitConsole();
bool WinGetRefreshRate(u16f *out);
bool WinBlockInput(struct RecordBuffer *buf);
bool WinWait(struct timespec relative);

View file

@ -75,15 +75,15 @@ struct CtrlBind {
const size_t code_count = 12; const size_t code_count = 12;
const struct CtrlBind ctrl_binds[12] = { const struct CtrlBind ctrl_binds[12] = {
{ LEFT, 0x25, KEY }, { LEFT, 0x25, BUTTON },
{ RIGHT, 0x27, KEY }, { RIGHT, 0x27, BUTTON },
{ SOFT_DROP, 0x28, KEY }, { SOFT_DROP, 0x28, BUTTON },
{ HARD_DROP, 0x20, KEY }, { HARD_DROP, 0x20, BUTTON },
{ ROTATE_CCW, 'Z', KEY }, { ROTATE_CCW, 'Z', BUTTON },
{ ROTATE_CW, 'X', KEY }, { ROTATE_CW, 'X', BUTTON },
{ ROTATE_180, 'A', KEY }, { ROTATE_180, 'A', BUTTON },
{ SWAP, 'C', KEY }, { SWAP, 'C', BUTTON },
{ ESC, 0x1B, KEY }, { ESC, 0x1B, BUTTON },
{ VSCROLL, 0, AXIS }, { VSCROLL, 0, AXIS },
{ HSCROLL, 1, AXIS }, { HSCROLL, 1, AXIS },
{ MOUSE, 0, JOYSTICK } { MOUSE, 0, JOYSTICK }
@ -96,7 +96,7 @@ void *Update(void *args)
while (true) { while (true) {
// Input // Input
CtrlPoll(&game->ctrl); CtrlPoll(&game->ctrl);
if (CtrlGet(&game->ctrl, LEFT, KEY)->button.is_down) if (CtrlGet(&game->ctrl, LEFT, BUTTON)->button.is_down)
printf("left down this frame\n"); printf("left down this frame\n");
// Game logic // Game logic