diff --git a/source/fumotris.h b/source/fumotris.h index e747a8a..6bfc324 100644 --- a/source/fumotris.h +++ b/source/fumotris.h @@ -13,4 +13,17 @@ typedef uint32_t u32; typedef uint_fast32_t u32f; typedef uint64_t u64; -typedef uint_fast64_t u64f; \ No newline at end of file +typedef uint_fast64_t u64f; + + +typedef int8_t i8; +typedef int_fast8_t i8f; + +typedef int16_t i16; +typedef int_fast16_t i16f; + +typedef int32_t i32; +typedef int_fast32_t i32f; + +typedef int64_t i64; +typedef int_fast64_t i64f; \ No newline at end of file diff --git a/source/game/event.c b/source/game/event.c index 1365202..a8ac7ad 100644 --- a/source/game/event.c +++ b/source/game/event.c @@ -17,13 +17,19 @@ size_t delegate_size(size_t capacity) return sizeof(void(*)(void *)) * capacity; } -struct Delegate NewDelegate(size_t capacity) +bool NewDelegate(struct Delegate *d, size_t capacity) { - return (struct Delegate) { + void (**events)(void *args) = malloc(delegate_size(capacity)); + + if (events == nullptr) + return false; + + *d = (struct Delegate) { .len = 0, .capacity = capacity, .events = malloc(delegate_size(capacity)) }; + return true; } void Subscribe(struct Delegate *d, void (*event)(void *args)) diff --git a/source/game/event.h b/source/game/event.h index 03e47bc..a3ae0cf 100644 --- a/source/game/event.h +++ b/source/game/event.h @@ -13,7 +13,7 @@ struct Delegate { void (**events)(void *args); }; -struct Delegate NewDelegate(size_t capacity); +bool NewDelegate(struct Delegate *d, size_t capacity); void Subscribe(struct Delegate *d, void (*event)(void *args)); diff --git a/source/io/ctrl.c b/source/io/ctrl.c index 2a851ea..604d0b4 100644 --- a/source/io/ctrl.c +++ b/source/io/ctrl.c @@ -11,54 +11,48 @@ #define IO_BUF_SIZE 16 -enum CtrlType { +enum InputType { KEY, AXIS, JOYSTICK, ESCAPE }; -struct Record { - u16 id; +struct Button { + u32 value; + bool is_down; + bool is_held; + bool is_up; +}; + +struct Axis { + i64 value; +}; + +struct Joystick { + i32 x; + i32 y; +}; + +struct InputRecord { + u16 bind; u8 type; union { - struct { - bool is_down; - } key; - struct { - u64 value; - } axis; - struct { - u32 x; - u32 y; - } joystick; - } data; + struct Button but; + struct Axis axis; + struct Joystick js; + }; struct timespec timestamp; }; -struct RecordBuffer { - struct Record records[IO_BUF_SIZE]; - size_t count; - pthread_mutex_t mutex; -}; - -struct Axis { +struct InputAxis { union { - struct { - u32 value; - u32 is_down : 1; - u32 is_up : 1; - } key; - struct { - u64 value; - } axis; - struct { - u32 x; - u32 y; - } joystick; - } data; + struct Button but; + struct Axis axis; + struct Joystick js; + }; struct timespec last_pressed; struct timespec last_released; @@ -81,41 +75,44 @@ hashtype Hash(void *item, size_t size) hashtype hash_id(u16f value, u8f type) { - struct id { - u16 id; - u8 type; - }; - - struct id id = { value, type }; - return Hash(&id, sizeof(struct id)); + struct { u16 id; u8 type; } id = { value, type }; + return Hash(&id, sizeof(id)); } -struct ctrl_bkt { - hashtype hash; - u16 value; - u8 type; - struct Axis *axis; -}; - struct ctrl_dict { size_t capacity; size_t filled; - struct ctrl_bkt *bkts; + + struct ctrl_bkt { + hashtype hash; + u16 value; + u8 type; + + struct InputAxis *axis; + } *bkts; }; -struct Ctrl { +struct Controller { struct ctrl_dict codes; struct ctrl_dict binds; + struct InputAxis *axes; - struct RecordBuffer buf; - pthread_t thread; + struct { + struct InputRecord records[IO_BUF_SIZE]; + size_t len; + } input_buf; + + struct { + size_t indexes[IO_BUF_SIZE]; + size_t len; + } pending_state_buf; }; -bool NewCtrl(struct Ctrl *ctrl, size_t code_cap, size_t bind_cap) +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 Axis *axes = calloc(code_cap, sizeof(struct Axis)); + struct InputAxis *axes = calloc(code_cap, sizeof(struct InputAxis)); if (code_bkts == nullptr or bind_bkts == nullptr or axes == nullptr) return false; @@ -124,7 +121,7 @@ bool NewCtrl(struct Ctrl *ctrl, size_t code_cap, size_t bind_cap) code_bkts[i].axis = axes + i; } - *ctrl = (struct Ctrl) { + *ctrl = (struct Controller) { .codes = (struct ctrl_dict) { .capacity = code_cap, .filled = 0, @@ -135,19 +132,23 @@ bool NewCtrl(struct Ctrl *ctrl, size_t code_cap, size_t bind_cap) .filled = 0, .bkts = bind_bkts, }, + .axes = axes, - .buf = (struct RecordBuffer) { - .count = 0, - .mutex = PTHREAD_MUTEX_INITIALIZER, + .input_buf = { + .len = 0, + }, + .pending_state_buf = { + .len = 0, }, }; return true; } -void FreeCtrl(struct Ctrl *ctrl) +void FreeCtrl(struct Controller *ctrl) { free(ctrl->codes.bkts); free(ctrl->binds.bkts); + free(ctrl->axes); } struct ctrl_bkt *get_bkt(struct ctrl_dict *dict, size_t i) @@ -216,7 +217,7 @@ next: return nullptr; } -struct Axis *find_axis(struct ctrl_dict *dict, u16f value, u8f type) +struct InputAxis *find_axis(struct ctrl_dict *dict, u16f value, u8f type) { struct ctrl_bkt *bkt = find(dict, value, type); if (bkt == nullptr) @@ -225,7 +226,7 @@ struct Axis *find_axis(struct ctrl_dict *dict, u16f value, u8f type) return bkt->axis; } -bool CtrlMap(struct Ctrl *ctrl, u16f code, u16f bind, u8f type) +bool CtrlMap(struct Controller *ctrl, u16f code, u16f bind, u8f type) { if (ctrl->codes.filled >= ctrl->codes.capacity or ctrl->binds.filled >= ctrl->binds.capacity) { printf("fatal error"); @@ -245,7 +246,7 @@ bool CtrlMap(struct Ctrl *ctrl, u16f code, u16f bind, u8f type) return true; } -struct Axis *CtrlGet(struct Ctrl *ctrl, u16f code, u8f type) +struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type) { struct ctrl_bkt *code_bkt = find(&ctrl->codes, code, type); if (code_bkt == nullptr) @@ -254,53 +255,69 @@ struct Axis *CtrlGet(struct Ctrl *ctrl, u16f code, u8f type) return code_bkt->axis; } -void update_key(struct Axis *axis, struct Record *record) +void update_key(struct InputAxis *axis, struct InputRecord *rec) { - if (record->data.key.is_down) - axis->last_pressed = record->timestamp; - else - axis->last_released = record->timestamp; - - axis->data.key.is_down = record->data.key.is_down; + if (rec->but.is_down) { + axis->last_pressed = rec->timestamp; + axis->but.is_held = true; + } else { + 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 Axis *axis, struct Record *record) +void update_axis(struct InputAxis *axis, struct InputRecord *rec) { - axis->data.axis.value = record->data.axis.value; - axis->last_pressed = record->timestamp; + axis->axis.value = rec->axis.value; + + axis->last_pressed = rec->timestamp; } -void update_joystick(struct Axis *axis, struct Record *record) +void update_joystick(struct InputAxis *axis, struct InputRecord *rec) { - axis->data.joystick.x = record->data.joystick.x; - axis->data.joystick.y = record->data.joystick.y; - axis->last_pressed = record->timestamp; + axis->js.x = rec->js.x; + axis->js.y = rec->js.y; + + axis->last_pressed = rec->timestamp; } -bool CtrlPoll(struct Ctrl *ctrl) +bool dispatch_update(struct InputAxis *axis, struct InputRecord *rec) { - for (size_t i = 0; i < ctrl->buf.count; i++) { - struct Record *rec = &ctrl->buf.records[i]; + switch (rec->type) { + case KEY: + update_key(axis, rec); + printf("axis:%hu\n", axis->but.is_down); + return true; - struct Axis *axis = find_axis(&ctrl->binds, rec->id, rec->type); + case AXIS: + update_axis(axis, rec); + return true; + + case JOYSTICK: + update_joystick(axis, rec); + return true; + } + + return false; +} + +bool CtrlPoll(struct Controller *ctrl) +{ + 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; - switch (rec->type) { - case KEY: - update_key(axis, rec); - break; - case AXIS: - update_axis(axis, rec); - break; - case JOYSTICK: - update_joystick(axis, rec); - break; - default: + if (!dispatch_update(axis, rec)) return false; - } } - ctrl->buf.count = 0; + ctrl->input_buf.len = 0; return true; } \ No newline at end of file diff --git a/source/io/ctrl.h b/source/io/ctrl.h index 0e6635b..01cc646 100644 --- a/source/io/ctrl.h +++ b/source/io/ctrl.h @@ -12,21 +12,22 @@ #define IO_BUF_SIZE 16 -enum CtrlType { +enum InputType { KEY, AXIS, JOYSTICK, ESCAPE }; -struct Record { - u16 id; +struct InputRecord { + u16 bind; u8 type; union { struct { bool is_down; - } key; + bool is_up; + } button; struct { u64 value; } axis; @@ -34,24 +35,25 @@ struct Record { u32 x; u32 y; } joystick; - } data; + }; struct timespec timestamp; }; struct RecordBuffer { - struct Record records[IO_BUF_SIZE]; + struct InputRecord records[IO_BUF_SIZE]; size_t count; pthread_mutex_t mutex; }; -struct Axis { +struct InputAxis { union { struct { u32 value; - u32 is_down : 1; - u32 is_up : 1; - } key; + bool is_down; + bool is_held; + bool is_up; + } button; struct { u64 value; } axis; @@ -59,7 +61,7 @@ struct Axis { u32 x; u32 y; } joystick; - } data; + }; struct timespec last_pressed; struct timespec last_released; @@ -86,7 +88,7 @@ struct ctrl_bkt { hashtype hash; u16 value; u8 type; - struct Axis *axis; + struct InputAxis *axis; }; struct ctrl_dict { @@ -95,20 +97,21 @@ struct ctrl_dict { struct ctrl_bkt *bkts; }; -struct Ctrl { +struct Controller { struct ctrl_dict codes; struct ctrl_dict binds; + struct InputAxis *axes; struct RecordBuffer buf; pthread_t thread; }; -bool NewCtrl(struct Ctrl *ctrl, size_t code_cap, size_t bind_cap); +bool NewCtrl(struct Controller *ctrl, size_t code_cap, size_t bind_cap); -void FreeCtrl(struct Ctrl *ctrl); +void FreeCtrl(struct Controller *ctrl); -bool CtrlMap(struct Ctrl *ctrl, u16f code, u16f bind, u8f type); +bool CtrlMap(struct Controller *ctrl, u16f code, u16f bind, u8f type); -struct Axis *CtrlGet(struct Ctrl *ctrl, u16f code, u8f type); +struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u8f type); -bool CtrlPoll(struct Ctrl *ctrl); \ No newline at end of file +bool CtrlPoll(struct Controller *ctrl); \ No newline at end of file diff --git a/source/io/input.c b/source/io/input.c index 87ddc34..3af6458 100644 --- a/source/io/input.c +++ b/source/io/input.c @@ -32,12 +32,12 @@ void *block_input(void *args_ptr) return nullptr; } -void StartInput(struct Ctrl *ctrl) +void StartInput(struct Controller *ctrl) { pthread_create(&ctrl->thread, nullptr, block_input, &ctrl->buf); } -void JoinInput(struct Ctrl *ctrl) +void JoinInput(struct Controller *ctrl) { pthread_join(ctrl->thread, nullptr); } \ No newline at end of file diff --git a/source/io/input.h b/source/io/input.h index c9b3732..3b9ba11 100644 --- a/source/io/input.h +++ b/source/io/input.h @@ -8,6 +8,6 @@ #include "ctrl.h" #include "fumotris.h" -void StartInput(struct Ctrl *ctrl); +void StartInput(struct Controller *ctrl); -void JoinInput(struct Ctrl *ctrl); \ No newline at end of file +void JoinInput(struct Controller *ctrl); \ No newline at end of file diff --git a/source/io/platforms/win.c b/source/io/platforms/win.c index 18ffe6c..37944b1 100644 --- a/source/io/platforms/win.c +++ b/source/io/platforms/win.c @@ -10,22 +10,17 @@ #include "winhandler.h" #include "term.h" -#include - bool WindowsInit(struct Terminal *term) { if (!WinInitHandles()) return false; - printf("shid "); - if (!WinInitConsole()) { - printf("%u\n", GetLastError()); + if (!WinInitConsole()) return false; - } - printf("console"); + if (!WinGetRefreshRate(&term->refresh_rate)) return false; - printf("???"); + return true; } diff --git a/source/io/platforms/winhandler.c b/source/io/platforms/winhandler.c index 066bf4c..d813b30 100644 --- a/source/io/platforms/winhandler.c +++ b/source/io/platforms/winhandler.c @@ -39,9 +39,9 @@ bool WinInitConsole() { DWORD mode = ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT + | ENABLE_PROCESSED_OUTPUT | ENABLE_MOUSE_INPUT - | ENABLE_WINDOW_INPUT - | ENABLE_VIRTUAL_TERMINAL_PROCESSING; + | ENABLE_WINDOW_INPUT; return SetConsoleMode(win.input_handle, mode) != 0; } @@ -62,34 +62,36 @@ bool WinGetRefreshRate(u16f *out) return true; } -void set_key_record(struct Record *record, KEY_EVENT_RECORD win_key) +void set_key_record(struct InputRecord *rec, KEY_EVENT_RECORD win_key) { - record->type = KEY; - record->id = win_key.wVirtualKeyCode; - record->data.key.is_down = win_key.bKeyDown; + rec->type = KEY; + rec->bind = win_key.wVirtualKeyCode; + + rec->button.is_down = win_key.bKeyDown; + rec->button.is_up = !win_key.bKeyDown; if (win_key.wVirtualKeyCode == VK_ESCAPE) - record->type = ESCAPE; + rec->type = ESCAPE; } -bool set_mouse_record(struct Record *record, MOUSE_EVENT_RECORD win_mouse) +bool set_mouse_record(struct InputRecord *rec, MOUSE_EVENT_RECORD win_mouse) { switch (win_mouse.dwEventFlags) { case MOUSE_WHEELED: - record->type = AXIS; - record->id = 0; - record->data.axis.value = win_mouse.dwButtonState; + rec->type = AXIS; + rec->bind = 0; + rec->axis.value = win_mouse.dwButtonState; break; case MOUSE_HWHEELED: - record->type = AXIS; - record->id = 1; - record->data.axis.value = win_mouse.dwButtonState; + rec->type = AXIS; + rec->bind = 1; + rec->axis.value = win_mouse.dwButtonState; break; case MOUSE_MOVED: - record->type = JOYSTICK; - record->id = 0; - record->data.joystick.x = win_mouse.dwMousePosition.X; - record->data.joystick.y = win_mouse.dwMousePosition.Y; + rec->type = JOYSTICK; + rec->bind = 0; + rec->joystick.x = win_mouse.dwMousePosition.X; + rec->joystick.y = win_mouse.dwMousePosition.Y; break; default: return false; @@ -97,19 +99,19 @@ bool set_mouse_record(struct Record *record, MOUSE_EVENT_RECORD win_mouse) return true; } -bool dispatch_record(struct Record *record, INPUT_RECORD win_record) +bool dispatch_record(struct InputRecord *rec, INPUT_RECORD win_rec) { - switch (win_record.EventType) { + switch (win_rec.EventType) { case KEY_EVENT: - set_key_record(record, win_record.Event.KeyEvent); + set_key_record(rec, win_rec.Event.KeyEvent); break; case MOUSE_EVENT: - return set_mouse_record(record, win_record.Event.MouseEvent); + return set_mouse_record(rec, win_rec.Event.MouseEvent); case WINDOW_BUFFER_SIZE_EVENT: // TODO: Handle window resizing return false; default: - record->type = ESCAPE; + rec->type = ESCAPE; } return true; } @@ -134,14 +136,14 @@ bool WinBlockInput(struct RecordBuffer *buf) pthread_mutex_lock(&buf->mutex); for (size_t i = 0; i < count; i++) { - struct Record record; - record.timestamp = now; + struct InputRecord rec; + rec.timestamp = now; - bool include = dispatch_record(&record, win_buf[i]); + bool include = dispatch_record(&rec, win_buf[i]); if (!include) continue; - buf->records[buf->count++] = record; + buf->records[buf->count++] = rec; } pthread_mutex_unlock(&buf->mutex); diff --git a/source/main.c b/source/main.c index 77c0442..8a2396c 100644 --- a/source/main.c +++ b/source/main.c @@ -16,6 +16,15 @@ #include "win.h" #endif +struct Instance { + struct Controller ctrl; + struct Terminal term; + + struct Delegate on_start; + struct Delegate on_update; + struct Delegate on_draw; +}; + const u8 I[16] = { 0, 0, 0, 0, 0, 0, 0, 0, @@ -58,16 +67,6 @@ const u8 L[9] = { 0, 0, 0 }; -struct Instance { - struct Ctrl ctrl; - - struct Delegate on_start; - struct Delegate on_update; - struct Delegate on_draw; - - struct Terminal term; -}; - struct CtrlBind { enum CtrlCode code; u16 bind; @@ -94,19 +93,18 @@ void *Update(void *args) { struct Instance *game = args; - struct TChar4 blks[game->term.area]; - game->term.blks = blks; - while (true) { // Input CtrlPoll(&game->ctrl); + if (CtrlGet(&game->ctrl, LEFT, KEY)->button.is_down) + printf("left down this frame\n"); // Game logic - Invoke(&game->on_update, game); + //Invoke(&game->on_update, game); // Draw - TermOut(&game->term); - puts(game->term.buf); + //TermOut(&game->term); + //puts(game->term.buf); } } @@ -128,6 +126,13 @@ bool Start(struct Instance *game) if (!NewTerm(&game->term, 20, 20)) return false; + + if (!NewDelegate(&game->on_start, 16)) + return false; + if (!NewDelegate(&game->on_update, 16)) + return false; + if (!NewDelegate(&game->on_draw, 16)) + return false; return true; } @@ -135,15 +140,13 @@ bool Start(struct Instance *game) int main() { struct Instance game; - Start(&game); + if (!Start(&game)) + exit(1); #ifdef _WIN32 - if(!WindowsInit(&game.term)) { - printf("FUCK"); + if(!WindowsInit(&game.term)) exit(1); - } #endif - printf("does it work"); StartInput(&game.ctrl); Loop(&game); diff --git a/source/term/term.c b/source/term/term.c index 6f7dc38..c829669 100644 --- a/source/term/term.c +++ b/source/term/term.c @@ -35,9 +35,14 @@ size_t term_buf_size(size_t area, size_t hgt) return reset_str_len + (max_color_str_len + 1) * area + hgt + 1; } -size_t blks_size(size_t area) +struct TChar4 *alloc_blks(size_t area) { - return area * sizeof(struct TChar4); + return calloc(area, sizeof(struct TChar4)); +} + +char *alloc_buf(size_t buf_size) +{ + return malloc(buf_size); } bool NewTerm(struct Terminal *term, size_t wid, size_t hgt) @@ -45,17 +50,17 @@ bool NewTerm(struct Terminal *term, size_t wid, size_t hgt) size_t area = wid * hgt; size_t buf_size = term_buf_size(area, hgt); - struct TChar4 *tchs = malloc(blks_size(area)); - char *buf = malloc(buf_size); + struct TChar4 *blks = alloc_blks(area); + char *buf = alloc_buf(buf_size); - if (tchs == nullptr or buf == nullptr) + if (blks == nullptr or buf == nullptr) return false; *term = (struct Terminal) { .wid = wid, .hgt = hgt, .area = area, - .blks = tchs, + .blks = blks, .buf_size = buf_size, .buf = buf, @@ -70,8 +75,9 @@ bool ResizeTerm(struct Terminal *term, size_t wid, size_t hgt) size_t area = wid * hgt; size_t buf_size = term_buf_size(area, hgt); - struct TChar4 *tchs = realloc(term->blks, blks_size(area)); + struct TChar4 *tchs = realloc(term->blks, area * sizeof(struct TChar4)); char *buf = realloc(term->buf, buf_size); + if (tchs == nullptr or buf == nullptr) return false; diff --git a/test.exe b/test.exe index e084d5b..3e4986b 100644 Binary files a/test.exe and b/test.exe differ