From 7c58e46fc4268a527c67aac81ca9fd384f0819ad Mon Sep 17 00:00:00 2001 From: Julia <145168563+julia-aph@users.noreply.github.com> Date: Thu, 9 May 2024 00:32:58 -0500 Subject: [PATCH] dict dicks --- source/fumoengine/include/dictionary.c | 19 ++-- source/fumoengine/input/ctrl.c | 82 +++++++++--------- source/fumoengine/input/ctrl.h | 28 +++--- source/fumoengine/input/input.h | 28 ++---- .../fumoengine/input/platforms/parseinput.c | 14 ++- source/fumoengine/input/platforms/win.c | 1 - source/fumoengine/input/platforms/win.h | 1 - source/fumotris/fumotris.c | 2 +- test.exe | Bin 86779 -> 88290 bytes 9 files changed, 80 insertions(+), 95 deletions(-) diff --git a/source/fumoengine/include/dictionary.c b/source/fumoengine/include/dictionary.c index 3eae7c6..dbfb39e 100644 --- a/source/fumoengine/include/dictionary.c +++ b/source/fumoengine/include/dictionary.c @@ -1,4 +1,5 @@ #include "dictionary.h" +#include #include @@ -12,7 +13,7 @@ bool CreateDictionary(DictT T, struct Dictionary *dict) *dict = (struct Dictionary) { .filled = 0, .capacity = 16, - .bkts = bkts, + .bkts = bkts }; return true; @@ -28,9 +29,9 @@ void *index_bkt(DictT T, struct Dictionary *dict, usize i) return (u8 *)dict->bkts + i * T->BKT_SIZE; } -u32 get_key(DictT T, void *bkt) +u32 *get_key(DictT T, void *bkt) { - return *(u32 *)bkt; + return (u32 *)bkt; } void *get_val(DictT T, void *bkt) @@ -38,12 +39,18 @@ void *get_val(DictT T, void *bkt) return (u8 *)bkt + T->VAL_OFS; } +void set_bkt(DictT T, void *bkt, u32 key, void *val) +{ + *get_key(T, bkt) = key; + memcpy(get_val(T, bkt), val, T->VAL_SIZE); +} + void *probe_bkt(DictT T, struct Dictionary *dict, usize index, u32 key) { for (usize i = 0; i < dict->capacity; i++) { void *bkt = index_bkt(T, dict, (index + i) % dict->capacity); - if (get_key(T, bkt) == key) + if (*get_key(T, bkt) == key) return bkt; } @@ -55,7 +62,7 @@ void *probe_empty_bkt(DictT T, struct Dictionary *dict, usize index, u32 key) for (usize i = 0; i < dict->capacity; i++) { void *bkt = index_bkt(T, dict, (index + i) % dict->capacity); - u32 k = get_key(T, bkt); + u32 k = *get_key(T, bkt); if (k == 0 or k == key) return bkt; } @@ -75,7 +82,7 @@ void *DictionarySet(DictT T, struct Dictionary *dict, u32 key, void *val) usize index = key % dict->capacity; void *bkt = probe_empty_bkt(T, dict, index, key); - if (get_key(T, bkt) == 0) + if (*get_key(T, bkt) == 0) set_bkt(T, bkt, key, val); return bkt; diff --git a/source/fumoengine/input/ctrl.c b/source/fumoengine/input/ctrl.c index 150bf19..b7f994a 100644 --- a/source/fumoengine/input/ctrl.c +++ b/source/fumoengine/input/ctrl.c @@ -4,84 +4,78 @@ #define INIT_SIZE 16 -DictT CODES_T = DICT_T(struct ControlAxis); -DictT BINDS_T = DICT_T(struct ControlAxis *); +DictT BIND_T = DICT_T(struct InputAxis *); bool CreateController(struct Controller *ctrl) { - if (!CreateDictionary(CODES_T, &ctrl->codes)) + struct InputAxis *axes = calloc(16, sizeof(struct InputAxis)); + + if (axes == nullptr) return false; - if (!CreateDictionary(BINDS_T, &ctrl->binds)) + if (!CreateDictionary(BIND_T, &ctrl->binds)) return false; - *ctrl = (struct Controller) { .pending.len = 0 }; + *ctrl = (struct Controller) { + .pending_len = 0, + .axes = axes, + .axes_len = 0 + }; return true; } void FreeController(struct Controller *ctrl) { - FreeDictionary(&ctrl->codes); + free(ctrl->axes); FreeDictionary(&ctrl->binds); } -struct ControlAxis *find_axis(struct ctrl_dict *dict, union InputID id) +u32 hash_bind(u16f bind, u16f type) { - struct ctrl_bkt *bkt = find(dict, id); - if (bkt == nullptr) - return nullptr; - - return bkt->axis; + return bind + (type << 16); } -struct ControlAxis *ControllerMap( +struct InputAxis *ControllerMap( struct Controller *ctrl, struct ControlMapping *map ) { - struct ControlAxis *axis = DictionarySet(CODES_T, &ctrl->codes, map->code); - struct ctrl_bkt *bind_bkt = set(&ctrl->binds, map->bind, map->type); - - if (code_bkt->axis == nullptr) - code_bkt->axis = &ctrl->axis_vec.axes[ctrl->axis_vec.len++]; - else if (code_bkt->axis == bind_bkt->axis) - return nullptr; - - bind_bkt->axis = code_bkt->axis; - code_bkt->axis->id.type = map->type; + struct InputAxis *axis = &ctrl->axes[map->code]; - return code_bkt->axis; + u32 hash = hash_bind(map->bind, map->type); + struct InputAxis **bind = DictionarySet(BIND_T, &ctrl->binds, hash, axis); + + if (bind == nullptr) { + printf("whar"); + exit(1); + } + + *bind = axis; + axis->type = map->type; + + return axis; } bool ControllerMapMulti( struct Controller *ctrl, usize n, struct ControlMapping *maps, - struct ControlAxis **axis_ptrs + struct InputAxis **binds ) { for (usize i = 0; i < n; i++) { - struct ControlAxis *axis = ControllerMap(ctrl, maps + i); + struct InputAxis *axis = ControllerMap(ctrl, maps + i); if (axis == nullptr) return false; - axis_ptrs[i] = axis; + binds[i] = axis; } return true; } -struct ControlAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type) -{ - struct ctrl_bkt *code_bkt = find(&ctrl->codes, as_id(code, type)); - if (code_bkt == nullptr) - return nullptr; - - return code_bkt->axis; -} - -void dispatch_update(struct ControlAxis *axis, struct InputRecord *rec) +void dispatch_update(struct InputAxis *axis, struct InputRecord *rec) { if (rec->is_down and !axis->is_held) { axis->is_down = true; @@ -98,24 +92,26 @@ void dispatch_update(struct ControlAxis *axis, struct InputRecord *rec) void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs) { - for (usize i = 0; i < ctrl->pending.len; i++) { - struct ControlAxis *axis = ctrl->pending.buf[i]; + for (usize i = 0; i < ctrl->pending_len; i++) { + struct InputAxis *axis = ctrl->pending[i]; axis->is_up = false; axis->is_down = false; } - ctrl->pending.len = 0; + ctrl->pending_len = 0; for (usize i = 0; i < recs->head.len; i++) { - struct InputRecord *rec = &recs->buf[i]; + struct InputRecord *rec = recs->buf + i; + + u32 hash = hash_bind(rec->bind, rec->type); + struct InputAxis *axis = DictionaryFind(BIND_T, &ctrl->binds, hash); - struct ControlAxis *axis = find_axis(&ctrl->binds, rec->id); if (axis == nullptr) continue; dispatch_update(axis, rec); - ctrl->pending.buf[ctrl->pending.len++] = axis; + ctrl->pending[ctrl->pending_len++] = axis; } recs->head.len = 0; diff --git a/source/fumoengine/input/ctrl.h b/source/fumoengine/input/ctrl.h index ff49c58..24030c9 100644 --- a/source/fumoengine/input/ctrl.h +++ b/source/fumoengine/input/ctrl.h @@ -10,7 +10,7 @@ struct ControlMapping { u16 type; }; -struct ControlAxis { +struct InputAxis { nsec last_pressed; nsec last_released; @@ -21,22 +21,20 @@ struct ControlAxis { union InputData data; }; - union InputID id; + u16 type; - struct { - u8f is_down : 1; - u8f is_held : 1; - u8f is_up : 1; - }; + bool is_down; + bool is_held; + bool is_up; }; struct Controller { - struct { - struct ControlAxis *buf[IO_BUF_SIZE]; - u8f len; - } pending; + struct InputAxis *pending[IO_BUF_SIZE]; + usize pending_len; + + struct InputAxis *axes; + usize axes_len; - struct Dictionary codes; struct Dictionary binds; }; @@ -45,7 +43,7 @@ bool CreateController(struct Controller *ctrl); void FreeController(struct Controller *ctrl); -struct ControlAxis *ControllerMap( +struct InputAxis *ControllerMap( struct Controller *ctrl, struct ControlMapping *map ); @@ -54,10 +52,8 @@ bool ControllerMapMulti( struct Controller *ctrl, usize n, struct ControlMapping *maps, - struct ControlAxis **axis_ptrs + struct InputAxis **axis_ptrs ); -struct ControlAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type); - void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs); diff --git a/source/fumoengine/input/input.h b/source/fumoengine/input/input.h index dd4bb08..ae4e158 100644 --- a/source/fumoengine/input/input.h +++ b/source/fumoengine/input/input.h @@ -5,7 +5,6 @@ #include #include #include - #include "fumocommon.h" #include "ringbuffer.h" @@ -20,21 +19,6 @@ enum InputType { ESCAPE }; -union InputID { - u32 hash; - - struct { - union { - u16 code; - u16 bind; - u16 value; - }; - - u16 type; - }; -}; - - struct Button { u64 value; }; @@ -54,7 +38,6 @@ union InputData { struct Joystick input_js; }; - struct InputRecord { nsec time; @@ -65,13 +48,12 @@ struct InputRecord { union InputData data; }; - union InputID id; + u16 bind; + u16 type; - struct { - u8f is_down : 1; - u8f is_held : 1; - u8f is_up : 1; - }; + bool is_down; + bool is_held; + bool is_up; }; struct RecordBuffer { diff --git a/source/fumoengine/input/platforms/parseinput.c b/source/fumoengine/input/platforms/parseinput.c index 089fb02..b92717e 100644 --- a/source/fumoengine/input/platforms/parseinput.c +++ b/source/fumoengine/input/platforms/parseinput.c @@ -3,26 +3,32 @@ void ReadButton(struct InputRecord *rec, u16f bind, bool is_down) { - rec->id = (union InputID) { .bind = bind, .type = BUTTON }; + rec->bind = bind; + rec->type = BUTTON; + rec->is_down = is_down; rec->is_up = !is_down; } void ReadAxis(struct InputRecord *rec, u16f bind, u64 value) { - rec->id = (union InputID) { .bind = bind, .type = AXIS }; + rec->bind = bind; + rec->type = AXIS; + rec->axis.value = value; } void ReadJoystick(struct InputRecord *rec, u16f bind, i32 x, i32 y) { - rec->id = (union InputID) { .bind = bind, .type = JOYSTICK }; + rec->bind = bind; + rec->type = JOYSTICK; + rec->js.x = x; rec->js.y = y; } size_t UCS2ToUTF8(char *buf, u16f ucs2) -{ +{ if (ucs2 < 0xFF) { buf[0] = ucs2; return 1; diff --git a/source/fumoengine/input/platforms/win.c b/source/fumoengine/input/platforms/win.c index 314e789..b638b35 100644 --- a/source/fumoengine/input/platforms/win.c +++ b/source/fumoengine/input/platforms/win.c @@ -1,6 +1,5 @@ #include "win.h" #include - #include "parseinput.h" #include "ringbuffer.h" diff --git a/source/fumoengine/input/platforms/win.h b/source/fumoengine/input/platforms/win.h index 8625da5..835cf64 100644 --- a/source/fumoengine/input/platforms/win.h +++ b/source/fumoengine/input/platforms/win.h @@ -4,5 +4,4 @@ #include #include #include - #include "fumocommon.h" \ No newline at end of file diff --git a/source/fumotris/fumotris.c b/source/fumotris/fumotris.c index 028de4b..155efd1 100644 --- a/source/fumotris/fumotris.c +++ b/source/fumotris/fumotris.c @@ -3,7 +3,7 @@ struct Fumotris { struct ControlMapping mappings[BINDS_N]; - struct ControlAxis *input[BINDS_N]; + struct InputAxis *input[BINDS_N]; struct TetrMap board; struct TetrMap piece; diff --git a/test.exe b/test.exe index f44ad46f559d7a8f387191feb8cf37917740351a..4ff9e847e8cdb50732f5dd540788e87fd745ac6d 100644 GIT binary patch delta 19675 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 Rf#a7fsC@I^gV|k4{{y-}=kx#o delta 19292 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 ZsjMeUc8yJCz5Oy4Oy9jal}%{(e*o=TP*VT^