From 3767bfc0364b1488145a1ee09c569888441962dd Mon Sep 17 00:00:00 2001 From: Julia <145168563+julia-aph@users.noreply.github.com> Date: Thu, 11 Apr 2024 14:57:22 -0500 Subject: [PATCH] plartfgh kjhjk --- hi.exe | Bin 63344 -> 66475 bytes source/io/ctrl.c | 168 +++++++++++++++--------------- source/io/ctrl.h | 52 ++++++---- source/io/input.c | 5 - source/io/platforms/win.c | 167 ++++++++++++++++++++++++++--- source/io/platforms/win.h | 12 ++- source/io/platforms/winhandler.c | 173 ------------------------------- source/io/platforms/winhandler.h | 18 ---- source/main.c | 20 ++-- 9 files changed, 288 insertions(+), 327 deletions(-) delete mode 100644 source/io/platforms/winhandler.c delete mode 100644 source/io/platforms/winhandler.h diff --git a/hi.exe b/hi.exe index 1eb5afa7f1ea6fcb6419ec8b6e3d438944b0ccde..e4ef518335611d168b2d6647f1718d82dd6f9ed6 100644 GIT binary patch delta 15110 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 Gng0vwM_T;= delta 12004 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 } -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->but.is_held = true; - } else { + } else if (rec->is_up) { + axis->is_up = true; + axis->is_held = false; axis->last_released = rec->timestamp; - axis->but.is_held = false; - } - - axis->but.is_down |= rec->but.is_down; - 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; + axis->data = rec->data; } bool CtrlPoll(struct Controller *ctrl) { 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++) { 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); + if (axis == nullptr) continue; - if (!dispatch_update(axis, rec)) - return false; - } + dispatch_update(axis, rec); + ctrl->pending_buf.axes[i] = axis; + } ctrl->input_buf.len = 0; + 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; } \ No newline at end of file diff --git a/source/io/ctrl.h b/source/io/ctrl.h index 7baefe3..e98260c 100644 --- a/source/io/ctrl.h +++ b/source/io/ctrl.h @@ -9,54 +9,65 @@ #include #include "fumotris.h" +#include "hash.h" #define IO_BUF_SIZE 16 enum InputType { - KEY, + BUTTON, AXIS, JOYSTICK, ESCAPE }; struct Button { - u32 value; - bool is_down; - bool is_held; - bool is_up; + 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 { - u16 bind; + 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 timespec timestamp; }; struct InputAxis { + struct timespec last_pressed; + 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 timespec last_pressed; - struct timespec last_released; }; enum CtrlCode { @@ -74,8 +85,6 @@ enum CtrlCode { MOUSE }; -typedef u32 hashtype; - struct ctrl_dict { size_t capacity; size_t filled; @@ -89,20 +98,21 @@ struct ctrl_dict { } *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 InputBuffer { - struct InputRecord records[IO_BUF_SIZE]; - size_t len; - size_t start; - } input_buf; + struct InputBuffer input_buf; struct { - size_t indexes[IO_BUF_SIZE]; size_t len; + struct InputAxis *axes[IO_BUF_SIZE]; } pending_buf; }; diff --git a/source/io/input.c b/source/io/input.c index ab8e8e1..d47437e 100644 --- a/source/io/input.c +++ b/source/io/input.c @@ -19,11 +19,6 @@ struct Input { 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) { struct Input *in = args_ptr; diff --git a/source/io/platforms/win.c b/source/io/platforms/win.c index 37944b1..0a8ff30 100644 --- a/source/io/platforms/win.c +++ b/source/io/platforms/win.c @@ -3,19 +3,72 @@ #include #include #include +#include #include -#include -#include "input.h" -#include "winhandler.h" +#include "fumotris.h" +#include "ctrl.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; - 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; if (!WinGetRefreshRate(&term->refresh_rate)) @@ -24,17 +77,103 @@ bool WindowsInit(struct Terminal *term) 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 = { - .tv_sec = seconds, - .tv_nsec = fmod(seconds, 1) * 1e9 - }; + 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; + + return true; + } - return WinWait(duration); + 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; } \ No newline at end of file diff --git a/source/io/platforms/win.h b/source/io/platforms/win.h index fdebbae..8e0015b 100644 --- a/source/io/platforms/win.h +++ b/source/io/platforms/win.h @@ -1,16 +1,18 @@ #pragma once -#include #include #include #include #include #include +#include -#include "input.h" +#include "fumotris.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); \ No newline at end of file +bool WinBlockInput(platform win, struct InputBuffer *buf); + +bool WinWait(platform win, struct timespec relative); \ No newline at end of file diff --git a/source/io/platforms/winhandler.c b/source/io/platforms/winhandler.c deleted file mode 100644 index 9865469..0000000 --- a/source/io/platforms/winhandler.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#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; -} \ No newline at end of file diff --git a/source/io/platforms/winhandler.h b/source/io/platforms/winhandler.h deleted file mode 100644 index 61d4fae..0000000 --- a/source/io/platforms/winhandler.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -#include "fumotris.h" - -bool WinInitHandles(); - -bool WinInitConsole(); - -bool WinGetRefreshRate(u16f *out); - -bool WinBlockInput(struct RecordBuffer *buf); - -bool WinWait(struct timespec relative); \ No newline at end of file diff --git a/source/main.c b/source/main.c index 8a2396c..8113cd0 100644 --- a/source/main.c +++ b/source/main.c @@ -75,15 +75,15 @@ struct CtrlBind { const size_t code_count = 12; const struct CtrlBind ctrl_binds[12] = { - { LEFT, 0x25, KEY }, - { RIGHT, 0x27, KEY }, - { SOFT_DROP, 0x28, KEY }, - { HARD_DROP, 0x20, KEY }, - { ROTATE_CCW, 'Z', KEY }, - { ROTATE_CW, 'X', KEY }, - { ROTATE_180, 'A', KEY }, - { SWAP, 'C', KEY }, - { ESC, 0x1B, KEY }, + { LEFT, 0x25, BUTTON }, + { RIGHT, 0x27, BUTTON }, + { SOFT_DROP, 0x28, BUTTON }, + { HARD_DROP, 0x20, BUTTON }, + { ROTATE_CCW, 'Z', BUTTON }, + { ROTATE_CW, 'X', BUTTON }, + { ROTATE_180, 'A', BUTTON }, + { SWAP, 'C', BUTTON }, + { ESC, 0x1B, BUTTON }, { VSCROLL, 0, AXIS }, { HSCROLL, 1, AXIS }, { MOUSE, 0, JOYSTICK } @@ -96,7 +96,7 @@ void *Update(void *args) while (true) { // Input 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"); // Game logic