f
This commit is contained in:
Julia 2024-05-02 17:17:37 -05:00
parent 1dcea1a2cf
commit 118e832a21
15 changed files with 253 additions and 207 deletions

View file

@ -88,7 +88,7 @@ def build(source_path, obj_path, out_path, recompile = False):
os.system(f"gcc -c {path} -I {' -I '.join(subdirs)} -o {obj_path}\\{name}.o -pthread -Wall -std=c17 -pedantic")
write_checksum_file(checksums_now)
print(os.system(f"gcc {obj_path}\\*.o -o {out_path} -pthread -Wall -std=c17 -pedantic"))
print(os.system(f"gcc {obj_path}\\*.o -o {out_path} -pthread -Wall -std=c17 -pedantic -g"))
build(sys.argv[1], sys.argv[2], sys.argv[3], True)

BIN
hi.exe

Binary file not shown.

View file

@ -1,7 +1,5 @@
#include "ctrl.h"
#include "event.h"
#include "fumocommon.h"
#include "fumoengine.h"
#include "platform.h"
void ErrorExit(char *message)
@ -10,43 +8,19 @@ void ErrorExit(char *message)
exit(1);
}
struct FumoGame {
struct Controller ctrl;
struct InputHandle input_hand;
struct Event start;
struct Event draw;
struct Event update;
Time time;
};
bool FumoEngineInit(struct FumoGame *game)
bool FumoInit(struct FumoGame *game)
{
if (!PlatformInit())
ErrorExit("Platform failed to initialize");
if (!CreateCtrl(&game->ctrl))
if (!CreateController(&game->ctrl))
ErrorExit("Out of memory");
//CtrlMap(&ctrl, 0, BUTTON, 'A');
if (!CreateEvent(&game->update))
ErrorExit("Out of memory");
CreateEvent(&game->update);
if (!BeginInputThread(&game->input_hand, &game->input_hand.recs, &ctrl.str))
if (!BeginInputThread(&game->input_hand))
ErrorExit("Input handle failed to initialize");
while (true) {
if (!InputAquire(&input_hand))
ErrorExit("Aquire failed");
CtrlPoll(&ctrl);
if (!InputRelease(&input_hand))
ErrorExit("Release failed");
EventInvokeUpdate(&game.update, 0);
}
return 0;
}

View file

@ -0,0 +1,23 @@
#pragma once
#include "ctrl.h"
#include "event.h"
#include "fumocommon.h"
#include "input.h"
struct FumoGame {
struct Controller ctrl;
struct InputHandle input_hand;
struct Event start;
struct Event draw;
struct Event update;
Time time;
};
void ErrorExit(char *message);
bool FumoInit(struct FumoGame *game);

View file

@ -50,7 +50,7 @@ void EventInvoke(struct Event *event, void *arg)
}
}
void EventInvokeUpdate(struct Event *event, u64 dt)
void EventInvokeUpdate(struct Event *event, Time dt)
{
for (size_t i = 0; i < event->len; i++) {
event->clbks[i].update(dt);

View file

@ -17,6 +17,13 @@ struct RingBufferHead {
size_t start;
};
#define RINGBUF_T_INIT(RBUF_STRUCT, RBUF_ITEM, RBUF_LEN) \
(&(struct RingBufferT) { \
.OFFSET = offsetof(RBUF_STRUCT, buf), \
.SIZE = sizeof(RBUF_ITEM), \
.LEN = RBUF_LEN \
}) \
#define RINGBUF_HEAD_INIT ((struct RingBufferHead) { 0, 0 })
size_t RingBufferEmpty(RingBufferT T, struct RingBufferHead *head);

View file

@ -5,7 +5,7 @@
#define INIT_SIZE 16
bool CreateCtrl(struct Controller *ctrl)
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));
@ -36,7 +36,7 @@ bool CreateCtrl(struct Controller *ctrl)
return true;
}
void FreeCtrl(struct Controller *ctrl)
void FreeController(struct Controller *ctrl)
{
free(ctrl->codes.bkts);
free(ctrl->binds.bkts);
@ -105,7 +105,7 @@ union InputID as_id(u16f value, u16f type) {
return (union InputID) { .value = value, .type = type };
}
bool CtrlMap(struct Controller *ctrl, u16f code, u16f type, u16f bind)
bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type)
{
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));
@ -120,7 +120,7 @@ bool CtrlMap(struct Controller *ctrl, u16f code, u16f type, u16f bind)
return true;
}
struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u16f type)
struct InputAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type)
{
struct ctrl_bkt *code_bkt = find(&ctrl->codes, as_id(code, type));
if (code_bkt == nullptr)
@ -144,15 +144,15 @@ void dispatch_update(struct InputAxis *axis, struct InputRecord *rec)
axis->data = rec->data;
}
void CtrlPoll(struct Controller *ctrl, struct InputRecordBuf *recs)
void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs)
{
for (size_t i = 0; i < ctrl->pending_buf.len; i++) {
/*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 = 0;
ctrl->pending_buf.len = 0;*/
for (size_t i = 0; i < recs->head.len; i++) {
struct InputRecord *rec = &recs->buf[i];
@ -171,31 +171,37 @@ void CtrlPoll(struct Controller *ctrl, struct InputRecordBuf *recs)
/*int main()
{
struct Controller ctrl;
if (!CreateCtrl(&ctrl))
if (!CreateController(&ctrl))
return 1;
CtrlMap(&ctrl, 123, BUTTON, 111);
CtrlMap(&ctrl, 0, BUTTON, 8);
ControllerMap(&ctrl, 123, 111, BUTTON);
ControllerMap(&ctrl, 0, 8, BUTTON);
struct RecordBuffer recs = { .head.len = 0, .head.start = 0 };
recs.buf[recs.head.len++] = (struct InputRecord) {
.but.value = 69,
ctrl.buf.recs[ctrl.buf.len++] = (struct InputRecord) {
.bind = 111,
.type = BUTTON,
.is_down = true,
.but.value = 69
.id.bind = 111,
.id.type = BUTTON
};
ctrl.buf.recs[ctrl.buf.len++] = (struct InputRecord) {
.bind = 8,
.type = BUTTON,
recs.buf[recs.head.len++] = (struct InputRecord) {
.but.value = 1000,
.is_down = true,
.but.value = 1000
.id.bind = 8,
.id.type = BUTTON
};
CtrlPoll(&ctrl);
ControllerPoll(&ctrl, &recs);
struct InputAxis *a = CtrlGet(&ctrl, 123, BUTTON);
struct InputAxis *a = ControllerGet(&ctrl, 123, BUTTON);
printf("%u\n", a->but.value);
struct InputAxis *b = CtrlGet(&ctrl, 0, BUTTON);
struct InputAxis *b = ControllerGet(&ctrl, 0, BUTTON);
printf("%u\n", b->but.value);
printf("success");

View file

@ -57,49 +57,19 @@ struct Controller {
struct ctrl_dict binds;
};
bool CreateCtrl(struct Controller *ctrl);
void FreeCtrl(struct Controller *ctrl);
bool CtrlMap(struct Controller *ctrl, u16f code, u16f type, u16f bind);
struct InputAxis *CtrlGet(struct Controller *ctrl, u16f code, u16f type);
void CtrlPoll(struct Controller *ctrl, struct InputRecordBuf *recs);
enum ControlCode {
LEFT,
RIGHT,
SOFT_DROP,
HARD_DROP,
ROTATE_CCW,
ROTATE_CW,
ROTATE_180,
SWAP,
ESC,
VSCROLL,
HSCROLL,
MOUSE
};
struct ControlBind {
enum ControlCode code;
int code;
u16 bind;
u8 type;
u16 type;
};
#define CODE_COUNT 12
/*const struct ControlBind ctrl_binds[12] = {
{ 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 }
};*/
bool CreateController(struct Controller *ctrl);
void FreeController(struct Controller *ctrl);
bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type);
struct InputAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type);
void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs);

View file

@ -4,25 +4,25 @@
#include "platform.h"
const struct RingBufferT IO_BUF_T = {
.OFFSET = offsetof(struct InputRecordBuf, buf),
.SIZE = sizeof(struct InputRecord),
.LEN = IO_BUF_SIZE
};
RingBufferT IO_BUF_T = RINGBUF_T_INIT(
struct RecordBuffer,
struct InputRecord,
IO_BUF_SIZE
);
const struct RingBufferT STR_BUF_T = {
.OFFSET = offsetof(struct InputStringBuf, buf),
.SIZE = sizeof(char),
.LEN = STR_BUF_SIZE
};
RingBufferT STR_BUF_T = RINGBUF_T_INIT(
struct StringBuffer,
char,
STR_BUF_SIZE
);
void *input_worker(void *arg)
{
struct InputHandle *hand = arg;
struct InputRecordBuf tmp_recs = { .head.len = 0, .head.start = 0 };
struct InputStringBuf tmp_str = { .head.len = 0, .head.start = 0 };
struct RecordBuffer tmp_recs = { .head.len = 0, .head.start = 0 };
struct StringBuffer tmp_str = { .head.len = 0, .head.start = 0 };
while (!hand->is_terminating) {
if (!PlatformReadInput(&tmp_recs, &tmp_str)) {
@ -42,8 +42,8 @@ void *input_worker(void *arg)
}
}
RingBufferTransfer(&IO_BUF_T, &hand->recs->head, &tmp_recs.head);
RingBufferTransfer(&STR_BUF_T, &hand->str->head, &tmp_str.head);
RingBufferTransfer(IO_BUF_T, &hand->recs.head, &tmp_recs.head);
RingBufferTransfer(STR_BUF_T, &hand->str.head, &tmp_str.head);
if (pthread_mutex_unlock(&hand->mutex) != 0) {
hand->err = true;
@ -54,14 +54,11 @@ void *input_worker(void *arg)
return nullptr;
}
bool BeginInputThread(
struct InputHandle *hand,
struct InputRecordBuf *in,
struct InputStringBuf *str
) {
bool BeginInputThread(struct InputHandle *hand)
{
*hand = (struct InputHandle) {
.recs = in,
.str = str,
.recs.head = RINGBUF_HEAD_INIT,
.str.head = RINGBUF_HEAD_INIT,
.err = 0,
.is_terminating = false,
@ -114,7 +111,7 @@ bool InputRelease(struct InputHandle *hand)
return true;
}
size_t InputString(struct InputStringBuf *str, size_t n, char *buf)
size_t InputString(struct InputHandle *hand, size_t n, char *buf)
{
return RingBufferOut(&STR_BUF_T, n, buf, &str->head);
return RingBufferOut(STR_BUF_T, n, buf, &hand->str.head);
}

View file

@ -13,8 +13,8 @@
#define STR_BUF_SIZE (IO_BUF_SIZE * 4)
extern const struct RingBufferT IO_BUF_T;
extern const struct RingBufferT STR_BUF_T;
extern RingBufferT IO_BUF_T;
extern RingBufferT STR_BUF_T;
enum InputType {
@ -25,15 +25,17 @@ enum InputType {
};
union InputID {
u32 hash;
struct {
union {
u16 code;
u16 bind;
u16 value;
};
u16 type;
};
u32 hash;
};
@ -76,20 +78,19 @@ struct InputRecord {
};
};
struct InputBuffer {
struct {
struct RingBufferHead head;
struct InputRecord buf[IO_BUF_SIZE];
} recs;
struct RecordBuffer {
struct RingBufferHead head;
struct InputRecord buf[IO_BUF_SIZE];
};
struct {
struct RingBufferHead head;
char buf[STR_BUF_SIZE];
} str;
struct StringBuffer {
struct RingBufferHead head;
char buf[STR_BUF_SIZE];
};
struct InputHandle {
struct InputBuffer in;
struct RecordBuffer recs;
struct StringBuffer str;
pthread_t thread;
pthread_mutex_t mutex;
@ -99,10 +100,7 @@ struct InputHandle {
bool is_terminating;
};
bool BeginInputThread(
struct InputHandle *hand,
struct InputBuffer *in,
);
bool BeginInputThread(struct InputHandle *hand);
bool EndInputThread(struct InputHandle *hand);
@ -110,4 +108,4 @@ bool InputAquire(struct InputHandle *hand);
bool InputRelease(struct InputHandle *hand);
size_t InputString(struct Controller *ctrl, size_t n, char *buf);
size_t InputString(struct InputHandle *hand, size_t n, char *buf);

View file

@ -16,7 +16,7 @@ bool PlatformInit();
bool PlatformGetRefreshRate(u16f *out);
bool PlatformReadInput(struct InputRecordBuf *in, struct InputStringBuf *str);
bool PlatformReadInput(struct RecordBuffer *recs, struct StringBuffer *str);
bool PlatformStopInput();

View file

@ -69,11 +69,6 @@ struct win_rec {
};
};
union record {
struct win_rec native;
INPUT_RECORD win;
};
bool init_handles()
{
win.input_hand = GetStdHandle(STD_INPUT_HANDLE);
@ -123,33 +118,33 @@ bool PlatformGetRefreshRate(u16f *out)
}
bool dispatch_rec(
struct InputRecord *out,
struct InputStringBuf *str,
struct win_rec *rec
struct InputRecord *rec,
struct StringBuffer *str,
struct win_rec *win
) {
u8f type = rec->type | (rec->is_mouse & rec->mouse.flags);
u8f type = win->type | (win->is_mouse & win->mouse.flags);
switch (type) {
case KEY_EVENT: {
ReadButton(out, rec->key.vk_code, rec->key.is_down);
ReadButton(rec, win->key.vk_code, win->key.is_down);
if (rec->key.is_down)
str->head.len += UCS2ToUTF8(str->buf, rec->key.ucs2_char);
if (win->key.is_down)
str->head.len += UCS2ToUTF8(str->buf, win->key.ucs2_char);
return true;
}
case MOUSE_MOVE: {
ReadJoystick(out, 0, rec->mouse.pos.x, rec->mouse.pos.y);
ReadJoystick(rec, 0, win->mouse.pos.x, win->mouse.pos.y);
return true;
}
case MOUSE_VWHEEL: {
ReadAxis(out, 0, rec->mouse.but);
ReadAxis(rec, 0, win->mouse.but);
return true;
}
case MOUSE_HWHEEL: {
ReadAxis(out, 1, rec->mouse.but);
ReadAxis(rec, 1, win->mouse.but);
return true;
}
@ -163,21 +158,30 @@ bool dispatch_rec(
return false;
}
bool PlatformReadInput(struct InputRecordBuf *recs, struct InputStringBuf *str)
size_t read_input(struct win_rec *buf, size_t n)
{
DWORD read_max = RingBufferEmpty(&IO_BUF_T, &recs->head);
union record win_buf[read_max];
DWORD filled;
DWORD len;
if (!ReadConsoleInputW(win.input_hand, buf, n, &len))
return 0;
if (!ReadConsoleInputW(win.input_hand, &win_buf->win, read_max, &filled))
return len;
}
bool PlatformReadInput(struct RecordBuffer *recs, struct StringBuffer *str)
{
size_t n = RingBufferEmpty(IO_BUF_T, &recs->head);
struct win_rec buf[n];
size_t len = read_input(buf, n);
if (len == 0)
return false;
Time now = TimeNow();
for (size_t i = 0; i < filled; i++) {
struct InputRecord *rec = RingBufferNext(&IO_BUF_T, &recs->head);
for (size_t i = 0; i < len; i++) {
struct InputRecord *rec = RingBufferNext(IO_BUF_T, &recs->head);
if (dispatch_rec(rec, str, &win_buf->native + i)) {
if (dispatch_rec(rec, str, &buf[i])) {
rec->time = now;
recs->head.len += 1;
}

View file

@ -1,43 +0,0 @@
/*const u8 I[16] = {
0, 0, 0, 0,
0, 0, 0, 0,
1, 1, 1, 1,
0, 0, 0, 0
};
const u8 O[4] = {
1, 1,
1, 1
};
const u8 T[9] = {
0, 1, 0,
1, 1, 1,
0, 0, 0
};
const u8 S[9] = {
0, 1, 1,
1, 1, 0,
0, 0, 0
};
const u8 Z[9] = {
1, 1, 0,
0, 1, 1,
0, 0, 0
};
const u8 J[9] = {
1, 0, 0,
1, 1, 1,
0, 0, 0
};
const u8 L[9] = {
0, 0, 1,
1, 1, 1,
0, 0, 0
};*/

110
source/fumotris/fumotris.c Normal file
View file

@ -0,0 +1,110 @@
#include "fumocommon.h"
#include "fumoengine.h"
enum ControlCode {
LEFT,
RIGHT,
SOFT_DROP,
HARD_DROP,
ROTATE_CCW,
ROTATE_CW,
ROTATE_180,
SWAP,
ESC,
VSCROLL,
HSCROLL,
MOUSE
};
#define CODE_COUNT 12
const struct ControlBind ctrl_binds[12] = {
{ 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 }
};
void Loop(struct FumoGame *game)
{
while (true) {
game->time = TimeNow();
if (!InputAquire(&game->input_hand))
ErrorExit("Aquire failed");
//ControllerPoll(&game->ctrl, &game->input_hand.recs);
if (!InputRelease(&game->input_hand))
ErrorExit("Release failed");
//EventInvokeUpdate(&game->update, 0);
}
}
int main()
{
struct FumoGame game;
FumoInit(&game);
for (size_t i = 0; i < CODE_COUNT; i++) {
const struct ControlBind *bind = &ctrl_binds[i];
ControllerMap(&game.ctrl, bind->code, bind->bind, bind->type);
}
Loop(&game);
return 0;
}
/*const u8 I[16] = {
0, 0, 0, 0,
0, 0, 0, 0,
1, 1, 1, 1,
0, 0, 0, 0
};
const u8 O[4] = {
1, 1,
1, 1
};
const u8 T[9] = {
0, 1, 0,
1, 1, 1,
0, 0, 0
};
const u8 S[9] = {
0, 1, 1,
1, 1, 0,
0, 0, 0
};
const u8 Z[9] = {
1, 1, 0,
0, 1, 1,
0, 0, 0
};
const u8 J[9] = {
1, 0, 0,
1, 1, 1,
0, 0, 0
};
const u8 L[9] = {
0, 0, 1,
1, 1, 1,
0, 0, 0
};*/

BIN
test.exe

Binary file not shown.