From 82e720015ac6b66f5bad54179c995fdd97c95d57 Mon Sep 17 00:00:00 2001 From: Julia <145168563+julia-aph@users.noreply.github.com> Date: Wed, 8 May 2024 07:47:46 -0500 Subject: [PATCH] ALMOSTR ALMSO T eaaer --- source/fumoengine/fumoengine.c | 27 ++++++++-------- source/fumoengine/fumoengine.h | 2 -- source/fumoengine/include/event.c | 6 ++-- source/fumoengine/include/event.h | 10 +++--- source/fumoengine/input/ctrl.c | 50 ++++++++++++++++-------------- source/fumoengine/input/ctrl.h | 18 ++++++----- source/fumotris/fumotris.c | 47 ++++++++++++++++++---------- source/fumotris/fumotris.h | 6 +--- test.exe | Bin 87052 -> 86779 bytes 9 files changed, 88 insertions(+), 78 deletions(-) diff --git a/source/fumoengine/fumoengine.c b/source/fumoengine/fumoengine.c index 7f900cd..72c6e69 100644 --- a/source/fumoengine/fumoengine.c +++ b/source/fumoengine/fumoengine.c @@ -2,9 +2,6 @@ #include "platform.h" -VectorT FUMOSYS_VEC_T = VECTOR_T(struct FumoHook); - - void Panic(char *message) { printf(message); @@ -28,7 +25,7 @@ bool CreateFumoInstance(struct FumoInstance *instance) if (!CreateEvent(&instance->on_start)) Panic("Out of memory"); - if (!CreateEvent(FUMOSYS_VEC_T, &instance->on_update)) + if (!CreateEvent(&instance->on_update)) Panic("Out of memory"); instance->time = TimeNow(); @@ -36,28 +33,30 @@ bool CreateFumoInstance(struct FumoInstance *instance) return true; } -bool FumoInstanceRun(struct FumoInstance *instance) +bool FumoInstanceRun(struct FumoInstance *inst) { - usize buf_n = TerminalMaxOut(&instance->term); + EventInvoke(&inst->on_start, inst); + + usize buf_n = TerminalMaxOut(&inst->term); char *buf = malloc(buf_n); while (true) { - if (!InputAquire(&instance->input_hand)) + if (!InputAquire(&inst->input_hand)) Panic("Aquire failed"); - ControllerPoll(&instance->ctrl, &instance->input_hand.recs); + ControllerPoll(&inst->ctrl, &inst->input_hand.recs); - if (!InputRelease(&instance->input_hand)) + if (!InputRelease(&inst->input_hand)) Panic("Release failed"); nsec now = TimeNow(); - instance->frametime = now - instance->time; - FumoInvoke(instance, &instance->on_update); - instance->time = now; + inst->frametime = now - inst->time; + EventInvoke(&inst->on_update, inst); + inst->time = now; - TerminalPrint(&instance->term, buf, buf_n); + TerminalPrint(&inst->term, buf, buf_n); puts(buf); - _sleep(100); + //_sleep(100); } } \ No newline at end of file diff --git a/source/fumoengine/fumoengine.h b/source/fumoengine/fumoengine.h index 7997863..3c18458 100644 --- a/source/fumoengine/fumoengine.h +++ b/source/fumoengine/fumoengine.h @@ -24,6 +24,4 @@ void Panic(char *message); bool CreateFumoInstance(struct FumoInstance *game); -bool FumoInstanceHook(struct Vector *vec, update_func update, void *state); - bool FumoInstanceRun(struct FumoInstance *game); \ No newline at end of file diff --git a/source/fumoengine/include/event.c b/source/fumoengine/include/event.c index fecef60..8814345 100644 --- a/source/fumoengine/include/event.c +++ b/source/fumoengine/include/event.c @@ -22,7 +22,7 @@ void FreeEvent(struct Event *event) free(event->methods); } -bool EventRegister(struct Event *event, callback func, void *instance) +bool EventAdd(struct Event *event, handler callback, void *instance) { if (event->len == event->capacity) { usize new_size = event->capacity * 2 * sizeof(struct Method); @@ -36,7 +36,7 @@ bool EventRegister(struct Event *event, callback func, void *instance) } event->methods[event->len++] = (struct Method) { - .func = func, + .callback = callback, .instance = instance }; @@ -47,6 +47,6 @@ void EventInvoke(struct Event *event, void *state) { for (usize i = 0; i < event->len; i++) { struct Method *method = event->methods + i; - method->func(state, method->instance); + method->callback(state, method->instance); } } \ No newline at end of file diff --git a/source/fumoengine/include/event.h b/source/fumoengine/include/event.h index 1efd478..bb25b41 100644 --- a/source/fumoengine/include/event.h +++ b/source/fumoengine/include/event.h @@ -5,10 +5,10 @@ #include "fumocommon.h" -typedef void (*callback)(void *state, void *instance); +typedef void (*handler)(void *state, void *instance); struct Method { - callback func; + handler callback; void *instance; }; @@ -19,8 +19,8 @@ struct Event { }; -bool CreateEvent(struct Event *event, void *state); +bool CreateEvent(struct Event *event); -bool EventRegister(struct Event *event, callback func, void *instance); +bool EventAdd(struct Event *event, handler callback, void *instance); -void EventInvoke(struct Event *event); \ No newline at end of file +void EventInvoke(struct Event *event, void *state); \ No newline at end of file diff --git a/source/fumoengine/input/ctrl.c b/source/fumoengine/input/ctrl.c index b80440a..f75dc3d 100644 --- a/source/fumoengine/input/ctrl.c +++ b/source/fumoengine/input/ctrl.c @@ -1,5 +1,4 @@ #include "ctrl.h" - #include "ringbuffer.h" #define INIT_SIZE 16 @@ -9,7 +8,7 @@ bool CreateController(struct Controller *ctrl) { struct ctrl_bkt *code_bkts = calloc(INIT_SIZE, sizeof(struct ctrl_bkt)); struct ctrl_bkt *bind_bkts = calloc(INIT_SIZE, sizeof(struct ctrl_bkt)); - struct InputAxis *axes = calloc(INIT_SIZE, sizeof(struct InputAxis)); + struct ControlAxis *axes = calloc(INIT_SIZE, sizeof(struct ControlAxis)); if (code_bkts == nullptr or bind_bkts == nullptr or axes == nullptr) return false; @@ -43,19 +42,19 @@ void FreeController(struct Controller *ctrl) free(ctrl->axis_vec.axes); } -struct ctrl_bkt *get_bkt(struct ctrl_dict *dict, size_t i) { +struct ctrl_bkt *get_bkt(struct ctrl_dict *dict, usize i) { return &dict->bkts[i]; } -size_t wrap_index(size_t i, size_t max) { +usize wrap_index(usize i, usize max) { return i % (SIZE_MAX - max + 1); } struct ctrl_bkt *find_set(struct ctrl_dict *dict, union InputID id) { - size_t i = id.hash % dict->capacity; + usize i = id.hash % dict->capacity; - size_t last = wrap_index(i - 1, dict->capacity); + usize last = wrap_index(i - 1, dict->capacity); while (i != last) { struct ctrl_bkt *bkt = get_bkt(dict, i); @@ -77,9 +76,9 @@ struct ctrl_bkt *find_set(struct ctrl_dict *dict, union InputID id) struct ctrl_bkt *find(struct ctrl_dict *dict, union InputID id) { - size_t i = id.hash % dict->capacity; + usize i = id.hash % dict->capacity; - size_t last = wrap_index(i - 1, dict->capacity); + usize last = wrap_index(i - 1, dict->capacity); while (i != last) { struct ctrl_bkt *bkt = get_bkt(dict, i); @@ -92,7 +91,7 @@ struct ctrl_bkt *find(struct ctrl_dict *dict, union InputID id) return nullptr; } -struct InputAxis *find_axis(struct ctrl_dict *dict, union InputID id) +struct ControlAxis *find_axis(struct ctrl_dict *dict, union InputID id) { struct ctrl_bkt *bkt = find(dict, id); if (bkt == nullptr) @@ -105,10 +104,10 @@ union InputID as_id(u16f value, u16f type) { return (union InputID) { .value = value, .type = type }; } -bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type) +bool ControllerMap(struct Controller *ctrl, struct ControlMapping *mapping) { - struct ctrl_bkt *code_bkt = find_set(&ctrl->codes, as_id(code, type)); - struct ctrl_bkt *bind_bkt = find_set(&ctrl->binds, as_id(bind, type)); + struct ctrl_bkt *code_bkt = find_set(&ctrl->codes, as_id(mapping->code, mapping->type)); + struct ctrl_bkt *bind_bkt = find_set(&ctrl->binds, as_id(mapping->bind, mapping->type)); if (code_bkt->axis == nullptr) code_bkt->axis = &ctrl->axis_vec.axes[ctrl->axis_vec.len++]; @@ -116,25 +115,28 @@ bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type) return false; bind_bkt->axis = code_bkt->axis; - code_bkt->axis->id.type = type; + code_bkt->axis->id.type = mapping->type; + + mapping->axis = code_bkt->axis; return true; } bool ControllerMapMulti( struct Controller *ctrl, - usize n_maps, - struct ControlMapping *maps + usize n, + struct ControlMapping *mappings ) { - for (usize i = 0; i < n_maps; i++) { - struct ControlMapping *map = maps + i; - if (!ControllerMap(ctrl, map->code, map->bind, map->type)) + for (usize i = 0; i < n; i++) { + struct ControlMapping *mapping = mappings + i; + + if (!ControllerMap(ctrl, mapping)) return false; } return true; } -struct InputAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type) +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) @@ -143,7 +145,7 @@ struct InputAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type) return code_bkt->axis; } -void dispatch_update(struct InputAxis *axis, struct InputRecord *rec) +void dispatch_update(struct ControlAxis *axis, struct InputRecord *rec) { if (rec->is_down and !axis->is_held) { axis->is_down = true; @@ -160,8 +162,8 @@ void dispatch_update(struct InputAxis *axis, struct InputRecord *rec) void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs) { - for (size_t i = 0; i < ctrl->pending_buf.len; i++) { - struct InputAxis *axis = ctrl->pending_buf.axes[i]; + for (usize i = 0; i < ctrl->pending_buf.len; i++) { + struct ControlAxis *axis = ctrl->pending_buf.axes[i]; axis->is_up = false; axis->is_down = false; @@ -169,10 +171,10 @@ void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs) ctrl->pending_buf.len = 0; - for (size_t i = 0; i < recs->head.len; i++) { + for (usize i = 0; i < recs->head.len; i++) { struct InputRecord *rec = &recs->buf[i]; - struct InputAxis *axis = find_axis(&ctrl->binds, rec->id); + struct ControlAxis *axis = find_axis(&ctrl->binds, rec->id); if (axis == nullptr) continue; diff --git a/source/fumoengine/input/ctrl.h b/source/fumoengine/input/ctrl.h index 1399c7b..e8f6344 100644 --- a/source/fumoengine/input/ctrl.h +++ b/source/fumoengine/input/ctrl.h @@ -9,7 +9,7 @@ #include "input.h" -struct InputAxis { +struct ControlAxis { nsec last_pressed; nsec last_released; @@ -30,7 +30,7 @@ struct InputAxis { }; struct ctrl_bkt { - struct InputAxis *axis; + struct ControlAxis *axis; union InputID id; }; @@ -41,14 +41,14 @@ struct ctrl_dict { }; struct ctrl_axis_vec { - struct InputAxis *axes; + struct ControlAxis *axes; u16f size; u16f len; }; struct Controller { struct { - struct InputAxis *axes[IO_BUF_SIZE]; + struct ControlAxis *axes[IO_BUF_SIZE]; u8f len; } pending_buf; @@ -61,21 +61,23 @@ struct ControlMapping { u16 code; u16 bind; u16 type; + struct ControlAxis *axis; }; bool CreateController(struct Controller *ctrl); + void FreeController(struct Controller *ctrl); -bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type); +bool ControllerMap(struct Controller *ctrl, struct ControlMapping *mapping); bool ControllerMapMulti( struct Controller *ctrl, - usize n_maps, - struct ControlMapping *maps + usize n, + struct ControlMapping *mappings ); -struct InputAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type); +struct ControlAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type); void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs); diff --git a/source/fumotris/fumotris.c b/source/fumotris/fumotris.c index 89c1898..b7b3c6e 100644 --- a/source/fumotris/fumotris.c +++ b/source/fumotris/fumotris.c @@ -1,35 +1,48 @@ #include "fumotris.h" -void Update(struct FumoInstance *instance, void *args) -{ - struct Fumotris *game = args; +struct Fumotris { + struct TetrMap board; + struct TetrMap piece; +}; - TetrMapDraw(&game->board, &instance->term); + +void FumotrisStart(void *engine, void *app) +{ + struct FumoInstance *inst = engine; + struct Fumotris *game = app; + + ControllerMapMulti(&inst->ctrl, CODE_COUNT, mappings_global); + + CreateTetrMap(&game->board, 10, 10); + CreateTetrMap(&game->piece, 3, 3); + game->piece.blks = T; } -bool CreateFumotris(struct Fumotris *game) +void FumotrisUpdate(void *engine, void *app) { - if (!CreateTetrMap(&game->board, 10, 10)) - return false; + struct FumoInstance *inst = engine; + struct Fumotris *game = app; - return true; + if (mappings_global[LEFT].axis->is_down) + game->piece.x -= 1; + if (mappings_global[RIGHT].axis->is_down) + game->piece.x += 1; + + TetrMapDraw(&game->board, &inst->term); + TetrMapDraw(&game->piece, &inst->term); } int main() { - struct FumoInstance instance; - CreateFumoInstance(&instance); + struct FumoInstance inst; + CreateFumoInstance(&inst); struct Fumotris game; - CreateFumotris(&game); + EventAdd(&inst.on_start, FumotrisStart, &game); + EventAdd(&inst.on_update, FumotrisUpdate, &game); - ControllerMapMulti(&instance.ctrl, CODE_COUNT, MAPPINGS); - - FumoInstanceHook(&instance.on_update, Update, &game); - - - FumoInstanceRun(&instance); + FumoInstanceRun(&inst); return 0; } \ No newline at end of file diff --git a/source/fumotris/fumotris.h b/source/fumotris/fumotris.h index efedc28..bbdd4bc 100644 --- a/source/fumotris/fumotris.h +++ b/source/fumotris/fumotris.h @@ -20,7 +20,7 @@ enum ControlCode { MOUSE }; -struct ControlMapping MAPPINGS[12] = { +struct ControlMapping mappings_global[12] = { { LEFT, 0x25, BUTTON }, { RIGHT, 0x27, BUTTON }, { SOFT_DROP, 0x28, BUTTON }, @@ -36,10 +36,6 @@ struct ControlMapping MAPPINGS[12] = { }; -struct Fumotris { - struct TetrMap board; - struct TetrMap piece; -}; const u8 I[16] = { 0, 0, 0, 0, diff --git a/test.exe b/test.exe index 32de7d9626a68f1f3a390632cea2c89367f5e99c..f44ad46f559d7a8f387191feb8cf37917740351a 100644 GIT binary patch delta 22671 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 delta 23035 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