diff --git a/checksums.txt b/checksums.txt index 09411bb..49259eb 100644 --- a/checksums.txt +++ b/checksums.txt @@ -1 +1 @@ -{"source\\main.c": "3d2369e9333b52142cb9f019e877e434", "source\\io\\controller.c": "4459cc302f4b70b072f39b43e87a0c08", "source\\io\\input.c": "d3336a096a3ac2d792292d84dd20fb8f", "source\\io\\platforms\\win.c": "4eb14343a9cb40a7f6a9d9e43329c46e", "source\\io\\platforms\\winio.c": "b3a5e9d8f2e8ab4ec38d14007e4fc3f4"} \ No newline at end of file +{"source\\main.c": "82d4037af47edc6a1ef16f061e8980c2", "source\\game\\gametime.c": "40eedcb0dd0e0ebd42a09860aeb24517", "source\\game\\tetr.c": "fee38bad904b2053644fddf0ba08cd5e", "source\\io\\ctrl.c": "a838d22152710a4be156b5c90c41863c", "source\\io\\input.c": "aca98b0ac5983206b3fad774dc4d6146", "source\\io\\term.c": "b8fa47ec18810973c2123e7ec3a3cec6", "source\\io\\platforms\\win.c": "5f8d684bbaae885edf7505a1d90d91e8", "source\\io\\platforms\\winhandler.c": "b0c21fa0370350172987a3ec39be1d20"} \ No newline at end of file diff --git a/objects/controller.o b/objects/controller.o deleted file mode 100644 index 6eb9011..0000000 Binary files a/objects/controller.o and /dev/null differ diff --git a/objects/ctrl.o b/objects/ctrl.o new file mode 100644 index 0000000..e4e2a9f Binary files /dev/null and b/objects/ctrl.o differ diff --git a/objects/gametime.o b/objects/gametime.o new file mode 100644 index 0000000..82eb46f Binary files /dev/null and b/objects/gametime.o differ diff --git a/objects/input.o b/objects/input.o index bcac4d2..cc31114 100644 Binary files a/objects/input.o and b/objects/input.o differ diff --git a/objects/main.o b/objects/main.o index b3ddca7..e580177 100644 Binary files a/objects/main.o and b/objects/main.o differ diff --git a/objects/term.o b/objects/term.o new file mode 100644 index 0000000..5c22ee1 Binary files /dev/null and b/objects/term.o differ diff --git a/objects/tetr.o b/objects/tetr.o new file mode 100644 index 0000000..a47f702 Binary files /dev/null and b/objects/tetr.o differ diff --git a/objects/win.o b/objects/win.o index 515e292..0490208 100644 Binary files a/objects/win.o and b/objects/win.o differ diff --git a/objects/winhandler.o b/objects/winhandler.o new file mode 100644 index 0000000..0fb62c5 Binary files /dev/null and b/objects/winhandler.o differ diff --git a/source/io/ctrl.c b/source/io/ctrl.c index e9a635d..f5617da 100644 --- a/source/io/ctrl.c +++ b/source/io/ctrl.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,10 +6,11 @@ #include #include #include +#include #include "fumotris.h" -#define IO_BUF_SIZE 8 +#define IO_BUF_SIZE 16 enum InputType { KEY, @@ -19,8 +21,8 @@ enum InputType { }; struct InputRecord { - enum InputType type; u16 id; + u8 type; union { struct { @@ -35,7 +37,7 @@ struct InputRecord { } joystick; } data; - double timestamp; + struct timespec timestamp; }; struct InputBuffer { @@ -53,8 +55,6 @@ struct InputBuffer NewInputBuffer() } struct Axis { - u8 type; - union { struct { u32 value; @@ -70,8 +70,8 @@ struct Axis { } joystick; } data; - double last_pressed; - double last_released; + struct timespec last_pressed; + struct timespec last_released; }; enum KeyCode { @@ -112,208 +112,220 @@ hashtype Hash(void *item, size_t size) struct ident { u16 id; - enum InputType type; + u8 type; }; -hashtype hash_ident(u16f id, enum InputType type) +hashtype hash_ident(u16f value, u8f type) { - struct ident obj = { id, type }; - return Hash(&obj, sizeof(struct ident)); + struct ident id = { value, type }; + return Hash(&id, sizeof(struct ident)); } -struct code_bkt { +struct bkt { hashtype hash; - u16 code; - struct Axis axis; -}; - -struct bind_bkt { - hashtype hash; - u16 bind; + u16 value; + u8 type; struct Axis *axis; }; +struct dict { + size_t capacity; + size_t filled; + struct bkt *bkts; +}; + struct Ctrl { - struct { - size_t capacity; - size_t filled; - struct code_bkt *bkts; - } codes; - - struct { - size_t capacity; - size_t filled; - struct bind_bkt *bkts; - } binds; + struct dict codes; + struct dict binds; + pthread_t thread; pthread_mutex_t mutex; }; typedef struct Ctrl Ctrl; -Ctrl NewCtrl(struct code_bkt *codes, size_t c, struct bind_bkt *binds, size_t b) +Ctrl NewCtrl(struct bkt *codes, struct Axis *axes, size_t c, struct bkt *binds, size_t b) { - memset(codes, 0, sizeof(struct code_bkt) * c); - memset(binds, 0, sizeof(struct bind_bkt) * b); + memset(codes, 0, sizeof(struct bkt) * c); + memset(axes, 0, sizeof(struct Axis) * c); + memset(binds, 0, sizeof(struct bkt) * b); + + for (size_t i = 0; i < c; i++) { + codes[i].axis = &axes[i]; + } Ctrl ctrl; + + ctrl.codes.capacity = c; + ctrl.codes.filled = 0; ctrl.codes.bkts = codes; + + ctrl.binds.capacity = b; + ctrl.binds.filled = 0; ctrl.binds.bkts = binds; + ctrl.mutex = PTHREAD_MUTEX_INITIALIZER; return ctrl; } -void CtrlPoll(struct InputBuffer *buf) +struct bkt *get_bkt(struct dict *dict, size_t i) { - for (size_t i = 0; i < buf->count; i++) { - struct InputRecord *rec = &buf->records[i]; + assert(i < dict->capacity); + return &dict->bkts[i]; +} - switch (rec->type) { - case KEY: - key_update(); - break; - case AXIS: - axis_update(); - break; - case JOYSTICK: - joystick_update(); - break; +void set_bkt(struct bkt *bkt, hashtype hash, u16f value, u8f type) +{ + bkt->hash = hash; + bkt->value = value; + bkt->type = type; +} + +size_t wrap(size_t x, size_t wrap) +{ + return x % (SIZE_MAX - wrap + 1); +} + +bool find_or_set(struct dict *dict, struct bkt **out, u16f value, u8f type) +{ + hashtype hash = hash_ident(value, type); + const size_t index = hash % dict->capacity; + + size_t i = index; + while (i != wrap(index - 1, dict->capacity)) { + struct bkt *bkt = get_bkt(dict, i); + + if (bkt->hash == 0) { + set_bkt(bkt, hash, value, type); + dict->filled += 1; + *out = bkt; + return false; } - } -} -struct ctrl_bkt *get_code_bkt(Ctrl *ctrl, size_t i) -{ - assert(i < ctrl->codes.capacity); - return &ctrl->codes.bkts[i]; -} - -struct ctrl_bkt *get_bind_bkt(Ctrl *ctrl, size_t i) -{ - assert(i < ctrl->binds.capacity); - return &ctrl->binds.bkts[i]; -} - -struct code_bkt *find_code_or_set_empty(Ctrl *ctrl, u16 code, ) -{ - const size_t index = hash % ctrl->codes.capacity; - size_t i = index; - - while (i != index - 1) { - struct code_bkt *bkt = get_code_bkt(ctrl, i); - if (bkt->hash == search) - return bkt; - if (bkt->hash == 0) - return bkt; + if (bkt->value == value and bkt->type == type) { + *out = bkt; + return true; + } - i = (i + 1) % ctrl->codes.capacity; + i = (i + 1) % dict->capacity; } + + *out = nullptr; + return false; +} + +struct bkt *find(struct dict *dict, u16f value, u8f type) +{ + hashtype hash = hash_ident(value, type); + const size_t index = hash % dict->capacity; + + size_t i = index; + while (i != wrap(index - 1, dict->capacity)) { + struct bkt *bkt = get_bkt(dict, i); + if (bkt->hash == 0) + goto next; + + if (bkt->value == value and bkt->type == type) { + return bkt; + } +next: + i = (i + 1) % dict->capacity; + }; + return nullptr; } -struct ctrl_bkt *find_bind(Ctrl *ctrl, hashtype hash, hashtype search) +struct Axis *find_axis(struct dict *dict, u16f value, u8f type) { - const size_t index = hash % ctrl->binds.capacity; - size_t i = index; - - while (i != index - 1) { - struct bind_bkt *bkt = get_bind_bkt(ctrl, i); - if (bkt->hash == 0) - return bkt; - - i = (i + 1) % ctrl->binds.capacity; - } - return nullptr; -} - -bool CtrlMap(Ctrl *ctrl, u16f bind, u16f code, enum InputType type) -{ - if (ctrl->binds.filled == ctrl->binds.capacity) - return false; - - struct code_bkt *code_bkt = find_code_or_set_empty(ctrl, code, type); - assert(code_bkt != nullptr); - - hashtype bind_hash = hash_ident(bind, type); - struct bind_bkt *bind_bkt = find_bind(ctrl, bind_hash, bind_hash); - bind_bkt->hash = bind_hash; - bind_bkt->bind = bind; - bind_bkt->axis = &code_bkt->axis; - - ctrl->binds.filled += 1; - - return true; -} - -struct Axis *find_bind_axis(Ctrl *ctrl, u16f bind, enum InputType type) -{ - hashtype bind_hash = hash_ident(bind, KEY); - struct ctrl_bkt *bind_bkt = find_bind(ctrl, bind_hash, bind_hash); - if (bind_bkt == nullptr) + struct bkt *bkt = find(dict, value, type); + if (bkt == nullptr) return nullptr; - return &get_bkt(ctrl, bind_bkt->index)->axis; + return bkt->axis; +} + +bool CtrlMap(Ctrl *ctrl, u16f code, u16f bind, u8f type) +{ + assert(ctrl->codes.filled < ctrl->codes.capacity); + assert(ctrl->binds.filled < ctrl->binds.capacity); + + struct bkt *code_bkt; + find_or_set(&ctrl->codes, &code_bkt, code, type); + assert(code_bkt != nullptr); + + struct bkt *bind_bkt; + bool bind_existed = find_or_set(&ctrl->binds, &bind_bkt, bind, type); + assert(bind_bkt != nullptr); + + if(bind_existed and bind_bkt->axis == code_bkt->axis) + return false; + + bind_bkt->axis = code_bkt->axis; + return true; } struct Axis *CtrlGet(Ctrl *ctrl, u16f code, u8f type) { -= struct ctrl_bkt *code_bkt = find_code(ctrl, code, type); + struct bkt *code_bkt = find(&ctrl->codes, code, type); if (code_bkt == nullptr) return nullptr; - return &code_bkt->axis; + return code_bkt->axis; } -bool CtrlUpdateKey(Ctrl *ctrl, struct InputRecord *record) +void update_key(struct Axis *axis, struct InputRecord *record) { - struct Axis *axis = find_bind_axis(ctrl, record->id, KEY); - if (axis == nullptr) - return false; - - if (record->data.key.is_down) { + if (record->data.key.is_down) axis->last_pressed = record->timestamp; - } else { + else axis->last_released = record->timestamp; - } - axis->data.axis.value = record->data.key.is_down; - return true; + axis->data.key.is_down = record->data.key.is_down; } -bool CtrlUpdateAxis(Ctrl *ctrl, struct InputRecord *record) +void update_axis(struct Axis *axis, struct InputRecord *record) { - struct Axis *axis = find_bind_axis(ctrl, record->id, AXIS); - if (axis == nullptr) - return false; - axis->data.axis.value = record->data.axis.value; axis->last_pressed = record->timestamp; - - return true; } -bool CtrlUpdateJoystick(Ctrl *ctrl, struct InputRecord *record) +void update_joystick(struct Axis *axis, struct InputRecord *record) { - struct Axis *axis = find_bind_axis(ctrl, record->id, JOYSTICK); - if (axis == nullptr) - return false; - axis->data.joystick.x = record->data.joystick.x; axis->data.joystick.y = record->data.joystick.y; axis->last_pressed = record->timestamp; - - return true; } -bool CtrlUpdateWindow(Ctrl *ctrl, struct InputRecord *record) +bool CtrlPoll(Ctrl *ctrl, struct InputBuffer *buf) { - struct Axis *axis = find_bind_axis(ctrl, record->id, WINDOW); - if (axis == nullptr) - return false; + pthread_mutex_lock(&buf->mutex); + pthread_mutex_lock(&ctrl->mutex); - axis->data.joystick.x = record->data.joystick.x; - axis->data.joystick.y = record->data.joystick.y; - axis->last_pressed = record->timestamp; + for (size_t i = 0; i < buf->count; i++) { + struct InputRecord *rec = &buf->records[i]; + struct Axis *axis = find_axis(&ctrl->binds, rec->id, 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: + case WINDOW: + update_joystick(axis, rec); + break; + default: + return false; + } + } + + buf->count = 0; + pthread_mutex_unlock(&buf->mutex); + pthread_mutex_unlock(&ctrl->mutex); return true; } \ No newline at end of file diff --git a/source/io/ctrl.h b/source/io/ctrl.h index d13c3c5..0ace76e 100644 --- a/source/io/ctrl.h +++ b/source/io/ctrl.h @@ -6,10 +6,11 @@ #include #include #include +#include #include "fumotris.h" -#define IO_BUF_SIZE 8 +#define IO_BUF_SIZE 16 enum InputType { KEY, @@ -20,8 +21,8 @@ enum InputType { }; struct InputRecord { - enum InputType type; u16 id; + u8 type; union { struct { @@ -36,7 +37,7 @@ struct InputRecord { } joystick; } data; - double timestamp; + struct timespec timestamp; }; struct InputBuffer { @@ -63,8 +64,8 @@ struct Axis { } joystick; } data; - double last_pressed; - double last_released; + struct timespec last_pressed; + struct timespec last_released; }; enum KeyCode { @@ -90,37 +91,42 @@ enum JoystickCode { typedef u32 hashtype; -struct ctrl_bkt { - hashtype bind_hash; - u16 bind; - size_t index; +struct bkt { + hashtype hash; + u16 value; + u8 type; + struct Axis *axis; +}; - hashtype code_hash; - u16 code; - - struct Axis axis; +struct dict { + size_t capacity; + size_t filled; + struct bkt *bkts; }; struct Ctrl { - size_t capacity; - size_t filled; - struct ctrl_bkt *bkts; + struct dict codes; + struct dict binds; + pthread_t thread; pthread_mutex_t mutex; }; typedef struct Ctrl Ctrl; -Ctrl NewCtrl(struct ctrl_bkt *bkts_prealloc, size_t capacity); +#define NEW_CTRL(CTRL, CODES, BINDS) \ + struct bkt NEW_CTRL_CODES[CODES]; \ + struct bkt NEW_CTRL_BINDS[BINDS]; \ + struct Axis NEW_CTRL_AXES[CODES]; \ + CTRL = NewCtrl( \ + NEW_CTRL_CODES, \ + NEW_CTRL_AXES, CODES, \ + NEW_CTRL_BINDS, BINDS \ + ); \ -bool CtrlMap(Ctrl *ctrl, u16f bind, u16f code, enum InputType type); +Ctrl NewCtrl(struct bkt *codes, struct Axis *axes, size_t c, struct bkt *binds, size_t b); -struct Axis *CtrlGet(Ctrl *ctrl, u16f code, enum InputType type); +bool CtrlMap(Ctrl *ctrl, u16f code, u16f bind, u8f type); -bool CtrlUpdateKey(Ctrl *ctrl, struct InputRecord *record); - -bool CtrlUpdateAxis(Ctrl *ctrl, struct InputRecord *record); - -bool CtrlUpdateJoystick(Ctrl *ctrl, struct InputRecord *record); - -bool CtrlUpdateWindow(Ctrl *ctrl, struct InputRecord *record); +struct Axis *CtrlGet(Ctrl *ctrl, u16f code, u8f type); +bool CtrlPoll(Ctrl *ctrl, struct InputBuffer *buf); \ No newline at end of file diff --git a/source/io/input.c b/source/io/input.c index f017283..8713d82 100644 --- a/source/io/input.c +++ b/source/io/input.c @@ -12,36 +12,52 @@ #include "win.h" #endif -#define IO_BUF_SIZE 8 - struct input_args { Ctrl *ctrl; - struct InputBuffer *in_buf; + struct InputBuffer *buf; + pthread_mutex_t mutex; }; void *block_input(void *args_ptr) { struct input_args *args = args_ptr; Ctrl *ctrl = args->ctrl; - struct InputBuffer *in_buf = args->in_buf; + struct InputBuffer *buf = args->buf; + printf("RECIEVED BUF: %u, %u\n", args->ctrl, args->buf); -input_loop: - bool success; + while (true) { + printf("\tIN LOOP\n"); + bool success; - #ifdef _WIN32 - success = WindowsBlockInput(&in_buf); - #endif + #ifdef _WIN32 + success = WindowsBlockInput(buf); + #endif - if (!success) - exit(1); + printf("%llu\n", buf->records[0].timestamp.tv_sec); + + if (!success) { + printf("winfail"); + exit(1); + } + } - goto input_loop; return nullptr; } -void StartInput(Ctrl *ctrl) +void StartInput(Ctrl *ctrl, struct InputBuffer *buf) { - pthread_t input_thread; - pthread_create(&input_thread, nullptr, block_input, ctrl); - //pthread_join(input_thread, nullptr); + printf("START INPUT:%u\n", buf); + struct input_args args = { + .ctrl = ctrl, + .buf = buf, + .mutex = PTHREAD_MUTEX_INITIALIZER + }; + pthread_mutex_lock(&args.mutex); + pthread_create(&ctrl->thread, nullptr, block_input, &args); + pthread_mutex_destroy(); +} + +void JoinInput(Ctrl *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 1a75c3b..3253074 100644 --- a/source/io/input.h +++ b/source/io/input.h @@ -8,10 +8,6 @@ #include "ctrl.h" #include "fumotris.h" -struct InputBuffer { - struct InputRecord records[IO_BUF_SIZE]; - size_t count; - pthread_mutex_t mutex; -}; +void StartInput(Ctrl *ctrl, struct InputBuffer *buf); -void StartInput(Ctrl *ctrl); \ No newline at end of file +void JoinInput(Ctrl *ctrl); \ No newline at end of file diff --git a/source/io/platforms/winhandler.c b/source/io/platforms/winhandler.c index 343c9a6..b3b901c 100644 --- a/source/io/platforms/winhandler.c +++ b/source/io/platforms/winhandler.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "fumotris.h" #include "gametime.h" @@ -103,14 +104,20 @@ bool dispatch_record(struct InputRecord *record, INPUT_RECORD win_record) bool WinBlockInput(struct InputBuffer *buf) { + printf("\twin blocked: %u\n", buf); size_t win_size = IO_BUF_SIZE - buf->count; + printf("\twhar\n"); INPUT_RECORD win_buf[win_size]; DWORD count; + printf("\treading in..\n"); if (!ReadConsoleInput(windows.input_handle, win_buf, win_size, &count)) return false; + printf("\read done\n"); - double now = GetTime(); + struct timespec now; + timespec_get(&now, TIME_UTC); + pthread_mutex_lock(&buf->mutex); for (size_t i = 0; i < count; i++) { @@ -133,11 +140,12 @@ bool WinWait(double seconds) { LARGE_INTEGER duration; duration.QuadPart = (u64)(-10000000.0 * seconds); - if (!SetWaitableTimer(windows.timer, &duration, 0, NULL, NULL, FALSE)) return false; + printf("about to wait..\n"); DWORD result = WaitForSingleObject(windows.timer, INFINITE); + printf("waitforsingle\n"); if (result != WAIT_OBJECT_0) return false; diff --git a/source/io/term.c b/source/io/term.c index 2871b56..d920236 100644 --- a/source/io/term.c +++ b/source/io/term.c @@ -71,7 +71,8 @@ size_t TermBufToChars(struct TermBuf *term, char *buf, size_t max_chars) u8f last_bg = 0; u8f last_fg = 0; - size_t filled = snprintf(buf, max_chars, "\x1b[H\x1b[0m"); + //size_t filled = snprintf(buf, max_chars, "\x1b[H\x1b[0m"); + size_t filled = snprintf(buf, max_chars, "\x1b[0m"); for(size_t y = 0; y < term->hgt; y++) { for(size_t x = 0; x < term->wid; x++) { diff --git a/source/main.c b/source/main.c index e519d90..7541a47 100644 --- a/source/main.c +++ b/source/main.c @@ -51,7 +51,7 @@ u8 I[16] = { 0, 0, 0, 0 }; -void Loop(Ctrl *ctrl) +void Loop(Ctrl *ctrl, struct InputBuffer *in_buf) { struct TermBuf term = NewTermBuf(20, 20); struct CharBlk4 term_blks[term.area]; @@ -73,15 +73,16 @@ void Loop(Ctrl *ctrl) falling.blks = falling_blks; for (int i = 0; i < 7779997; i++) { - + CtrlPoll(ctrl, in_buf); + printf("polled\n"); TetrMapToTermBuf(&board, &term); TetrMapToTermBuf(&falling, &term); - size_t size = TermBufToChars(&term, out, out_max); - puts(out); + TermBufToChars(&term, out, out_max); + //puts(out); - WindowsWait(0.1); + printf("%u\n", WindowsWait(0.01)); } } @@ -89,8 +90,8 @@ int main() { WindowsInit(); - struct ctrl_bkt bkts[13]; - Ctrl ctrl = NewCtrl(bkts, 13); + Ctrl ctrl; + NEW_CTRL(ctrl, 13, 13); for (size_t i = 0; i < 9; i++) { CtrlMap(&ctrl, key_binds[i], key_codes[i], KEY); @@ -103,8 +104,15 @@ int main() printf("set controls\n"); - StartInput(&ctrl); - Loop(&ctrl); + struct InputBuffer in_buf = { + .count = 0, + .mutex = PTHREAD_MUTEX_INITIALIZER + }; + + StartInput(&ctrl, &in_buf); + Loop(&ctrl, &in_buf); + + JoinInput(&ctrl); return 0; } \ No newline at end of file diff --git a/test.exe b/test.exe index 8c36f1f..5c5a00c 100644 Binary files a/test.exe and b/test.exe differ