kj
This commit is contained in:
Julia 2024-05-07 17:10:15 -05:00
parent 2b15552401
commit 62b37ed348
21 changed files with 401 additions and 280 deletions

View file

@ -58,7 +58,9 @@
"typeinfo": "cpp", "typeinfo": "cpp",
"execution": "cpp", "execution": "cpp",
"stdbool.h": "c", "stdbool.h": "c",
"fumoengine.h": "c" "fumoengine.h": "c",
"event.h": "c",
"fumocommon.h": "c"
} }
} }
} }

View file

@ -1,4 +1,6 @@
#pragma once #pragma once
#include <iso646.h>
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#define nullptr ((void *)0) #define nullptr ((void *)0)

View file

@ -2,32 +2,62 @@
#include "platform.h" #include "platform.h"
VectorT FUMOSYS_VEC_T = VECTOR_T(struct FumoHook);
void Panic(char *message) void Panic(char *message)
{ {
printf(message); printf(message);
exit(1); exit(1);
} }
void InvokeUpdate(void_func func, void *arg) bool CreateFumoInstance(struct FumoInstance *instance)
{
struct { nsec frametime; } *args = arg;
((update_func)func)(args->frametime);
}
bool FumoInit(struct FumoGame *game)
{ {
if (!PlatformInit()) if (!PlatformInit())
Panic("Platform failed to initialize"); Panic("Platform failed to initialize");
if (!CreateController(&game->ctrl)) if (!CreateController(&instance->ctrl))
Panic("Out of memory"); Panic("Out of memory");
if (!CreateEvent(&game->update)) if (!CreateInputThread(&instance->input_hand))
Panic("Out of memory");
if (!BeginInputThread(&game->input_hand))
Panic("Input handle failed to initialize"); Panic("Input handle failed to initialize");
return 0; if (!CreateTerminal(&instance->term, 20, 10))
Panic("Out of memory");
if (!CreateEvent(&instance->on_start))
Panic("Out of memory");
if (!CreateEvent(FUMOSYS_VEC_T, &instance->on_update))
Panic("Out of memory");
instance->time = TimeNow();
return true;
}
bool FumoInstanceRun(struct FumoInstance *instance)
{
usize buf_n = TerminalMaxOut(&instance->term);
char *buf = malloc(buf_n);
while (true) {
if (!InputAquire(&instance->input_hand))
Panic("Aquire failed");
ControllerPoll(&instance->ctrl, &instance->input_hand.recs);
if (!InputRelease(&instance->input_hand))
Panic("Release failed");
nsec now = TimeNow();
instance->frametime = now - instance->time;
FumoInvoke(instance, &instance->on_update);
instance->time = now;
TerminalPrint(&instance->term, buf, buf_n);
puts(buf);
_sleep(100);
}
} }

View file

@ -3,21 +3,27 @@
#include "event.h" #include "event.h"
#include "fumocommon.h" #include "fumocommon.h"
#include "input.h" #include "input.h"
#include "terminal.h"
#include "vector.h"
struct FumoGame { struct FumoInstance {
struct Controller ctrl; struct Controller ctrl;
struct InputHandle input_hand; struct InputHandle input_hand;
struct Terminal term;
struct Event start; struct Event on_start;
struct Event draw; struct Event on_update;
struct Event update;
nsec time; nsec time;
nsec frametime;
}; };
void Panic(char *message); void Panic(char *message);
bool FumoInit(struct FumoGame *game); bool CreateFumoInstance(struct FumoInstance *game);
bool FumoInstanceHook(struct Vector *vec, update_func update, void *state);
bool FumoInstanceRun(struct FumoInstance *game);

View file

@ -1,19 +1,17 @@
#include "event.h" #include "event.h"
#define INIT_CAPACITY 16
bool CreateEvent(struct Event *event) bool CreateEvent(struct Event *event)
{ {
void_func *callbacks = malloc(INIT_CAPACITY * sizeof(void_func)); struct Method *methods = malloc(16 * sizeof(struct Method));
if (callbacks == nullptr) if (methods == nullptr)
return false; return false;
*event = (struct Event) { *event = (struct Event) {
.callbacks = callbacks, .methods = methods,
.len = 0, .len = 0,
.capacity = INIT_CAPACITY .capacity = 16
}; };
return true; return true;
@ -21,30 +19,34 @@ bool CreateEvent(struct Event *event)
void FreeEvent(struct Event *event) void FreeEvent(struct Event *event)
{ {
free(event->callbacks); free(event->methods);
} }
bool EventRegister(struct Event *event, void_func callback) bool EventRegister(struct Event *event, callback func, void *instance)
{ {
if (event->len == event->capacity) { if (event->len == event->capacity) {
usize new_size = event->capacity * 2 * sizeof(void_func); usize new_size = event->capacity * 2 * sizeof(struct Method);
void_func *new_callbacks = realloc(event->callbacks, new_size); struct Method *new_methods = realloc(event->methods, new_size);
if (new_callbacks == nullptr) if (new_methods == nullptr)
return false; return false;
event->callbacks = new_callbacks; event->methods = new_methods;
event->capacity = new_size; event->capacity = new_size;
} }
event->callbacks[event->len++] = callback; event->methods[event->len++] = (struct Method) {
.func = func,
.instance = instance
};
return true; return true;
} }
void EventInvoke(struct Event *event, void *args) void EventInvoke(struct Event *event, void *state)
{ {
for (usize i = 0; i < event->len; i++) { for (usize i = 0; i < event->len; i++) {
event->callbacks[i](args); struct Method *method = event->methods + i;
method->func(state, method->instance);
} }
} }

View file

@ -1,27 +1,26 @@
#pragma once #pragma once
#include <iso646.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "fumocommon.h" #include "fumocommon.h"
typedef void (*void_func)(void *arg); typedef void (*callback)(void *state, void *instance);
typedef void (*invoker_func)(void_func func, void *arg);
struct Method {
callback func;
void *instance;
};
struct Event { struct Event {
void_func *callbacks; struct Method *methods;
usize len; usize len;
usize capacity; usize capacity;
}; };
bool CreateEvent(struct Event *event); bool CreateEvent(struct Event *event, void *state);
bool EventRegister(struct Event *event, void_func callback); bool EventRegister(struct Event *event, callback func, void *instance);
void EventInvoke(struct Event *event, void *args); void EventInvoke(struct Event *event);

View file

@ -3,26 +3,26 @@
#include <string.h> #include <string.h>
void *get_ptr(RingBufferT T, struct RingBufferHead *head, size_t i) void *get_ptr(RingBufferT T, struct RingBufferHead *head, usize i)
{ {
u8 *bytes = (u8 *)head; u8 *bytes = (u8 *)head;
return bytes + T->OFFSET + T->SIZE * i; return bytes + T->OFFSET + T->SIZE * i;
} }
size_t RingBufferEmpty(RingBufferT T, struct RingBufferHead *head) usize RingBufferEmpty(RingBufferT T, struct RingBufferHead *head)
{ {
return T->LEN - head->len; return T->LEN - head->len;
} }
void *RingBufferGet(RingBufferT T, struct RingBufferHead *head, size_t i) void *RingBufferGet(RingBufferT T, struct RingBufferHead *head, usize i)
{ {
size_t wrap_i = (head->start + i) % T->LEN; usize wrap_i = (head->start + i) % T->LEN;
return get_ptr(T, head, wrap_i); return get_ptr(T, head, wrap_i);
} }
void *RingBufferNext(RingBufferT T, struct RingBufferHead *head) void *RingBufferNext(RingBufferT T, struct RingBufferHead *head)
{ {
size_t wrap_i = (head->start + head->len) % T->LEN; usize wrap_i = (head->start + head->len) % T->LEN;
return get_ptr(T, head, wrap_i); return get_ptr(T, head, wrap_i);
} }
@ -37,9 +37,9 @@ void RingBufferTransfer(
struct RingBufferHead *dest, struct RingBufferHead *dest,
struct RingBufferHead *tmp struct RingBufferHead *tmp
) { ) {
size_t copy_max = min_usize(T->LEN - dest->len, tmp->len); usize copy_max = min_usize(T->LEN - dest->len, tmp->len);
for (size_t i = 0; i < copy_max; i++) { for (usize i = 0; i < copy_max; i++) {
void *to = RingBufferGet(T, dest, dest->len + i); void *to = RingBufferGet(T, dest, dest->len + i);
void *from = RingBufferGet(T, tmp, i); void *from = RingBufferGet(T, tmp, i);
memcpy(to, from, T->SIZE); memcpy(to, from, T->SIZE);
@ -49,15 +49,15 @@ void RingBufferTransfer(
tmp->len -= copy_max; tmp->len -= copy_max;
} }
size_t RingBufferOut( usize RingBufferOut(
RingBufferT T, RingBufferT T,
size_t n, usize n,
void *dest, void *dest,
struct RingBufferHead *src struct RingBufferHead *src
) { ) {
size_t copy_max = min_usize(n, src->len); usize copy_max = min_usize(n, src->len);
for (size_t i = 0; i < copy_max; i++) { for (usize i = 0; i < copy_max; i++) {
void *to = (u8 *)dest + i * T->SIZE; void *to = (u8 *)dest + i * T->SIZE;
void *from = RingBufferGet(T, src, i); void *from = RingBufferGet(T, src, i);
memcpy(to, from, T->SIZE); memcpy(to, from, T->SIZE);

View file

@ -1,41 +1,39 @@
#pragma once #pragma once
#include <iso646.h>
#include <stdalign.h> #include <stdalign.h>
#include <stdbool.h>
#include <stdint.h>
#include "fumocommon.h" #include "fumocommon.h"
#define RINGBUF_T(RBUF_ITEM_T, RBUF_LEN) \
typedef const struct RingBufferT {
size_t OFFSET;
size_t SIZE;
size_t LEN;
} *const RingBufferT;
struct RingBufferHead {
size_t len;
size_t start;
};
#define RINGBUF_T_INIT(RBUF_STRUCT, RBUF_ITEM, RBUF_LEN) \
(&(struct RingBufferT) { \ (&(struct RingBufferT) { \
.OFFSET = offsetof(struct { \ .OFFSET = offsetof(struct { \
struct RingBufferHead head; \ struct RingBufferHead head; \
RBUF_ITEM item; \ RBUF_ITEM_T item; \
}, item), \ }, item), \
.SIZE = sizeof(RBUF_ITEM), \ .SIZE = sizeof(RBUF_ITEM_T), \
.LEN = RBUF_LEN \ .LEN = RBUF_LEN \
}) \ }) \
#define RINGBUF_HEAD_INIT ((struct RingBufferHead) { 0, 0 }) #define RINGBUF_HEAD_INIT ((struct RingBufferHead) { 0, 0 })
size_t RingBufferEmpty(RingBufferT T, struct RingBufferHead *head);
typedef const struct RingBufferT {
usize OFFSET;
usize SIZE;
usize LEN;
} *const RingBufferT;
struct RingBufferHead {
usize len;
usize start;
};
usize RingBufferEmpty(RingBufferT T, struct RingBufferHead *head);
void *RingBufferGet( void *RingBufferGet(
RingBufferT T, RingBufferT T,
struct RingBufferHead *head, struct RingBufferHead *head,
size_t i usize i
); );
void *RingBufferNext(RingBufferT T, struct RingBufferHead *head); void *RingBufferNext(RingBufferT T, struct RingBufferHead *head);
@ -48,9 +46,9 @@ void RingBufferTransfer(
struct RingBufferHead *tmp struct RingBufferHead *tmp
); );
size_t RingBufferOut( usize RingBufferOut(
RingBufferT T, RingBufferT T,
size_t n, usize n,
void *dest, void *dest,
struct RingBufferHead *src struct RingBufferHead *src
); );

View file

@ -0,0 +1,47 @@
#include "vector.h"
#include <stdlib.h>
#include <string.h>
bool CreateVector(VectorT T, struct Vector *vec)
{
void *array = malloc(16 * T->SIZE);
if (array == nullptr)
return false;
*vec = (struct Vector) {
.len = 0,
.capacity = 16,
.array = array
};
return true;
}
void FreeVector(struct Vector *vec)
{
free(vec->array);
}
void *VectorGet(VectorT T, struct Vector *vec, usize i)
{
return (u8 *)vec->array + i * T->SIZE;
}
bool VectorAdd(VectorT T, struct Vector *vec, void *item)
{
if (vec->len == vec->capacity) {
usize new_capacity = vec->capacity * 2;
void *new_array = realloc(vec->array, new_capacity * T->SIZE);
if (new_array == nullptr)
return false;
vec->capacity = new_capacity;
}
memcpy(VectorGet(T, vec, vec->len++), item, T->SIZE);
return true;
}

View file

@ -0,0 +1,26 @@
#include "fumocommon.h"
#define VECTOR_T(VEC_ITEM_T) \
(&(struct VectorT) { \
.SIZE = sizeof(VEC_ITEM_T) \
}) \
typedef const struct VectorT {
usize SIZE;
} *const VectorT;
struct Vector {
usize len;
usize capacity;
void *array;
};
bool CreateVector(VectorT T, struct Vector *vec);
void FreeVector(struct Vector *vec);
void *VectorGet(VectorT T, struct Vector *vec, usize i);
bool VectorAdd(VectorT T, struct Vector *vec, void *item);

View file

@ -120,6 +120,20 @@ bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type)
return true; return true;
} }
bool ControllerMapMulti(
struct Controller *ctrl,
usize n_maps,
struct ControlMapping *maps
) {
for (usize i = 0; i < n_maps; i++) {
struct ControlMapping *map = maps + i;
if (!ControllerMap(ctrl, map->code, map->bind, map->type))
return false;
}
return true;
}
struct InputAxis *ControllerGet(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)); struct ctrl_bkt *code_bkt = find(&ctrl->codes, as_id(code, type));

View file

@ -57,8 +57,8 @@ struct Controller {
struct ctrl_dict binds; struct ctrl_dict binds;
}; };
struct ControlBind { struct ControlMapping {
int code; u16 code;
u16 bind; u16 bind;
u16 type; u16 type;
}; };
@ -69,6 +69,12 @@ void FreeController(struct Controller *ctrl);
bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type); bool ControllerMap(struct Controller *ctrl, u16f code, u16f bind, u16f type);
bool ControllerMapMulti(
struct Controller *ctrl,
usize n_maps,
struct ControlMapping *maps
);
struct InputAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type); struct InputAxis *ControllerGet(struct Controller *ctrl, u16f code, u16f type);
void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs); void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs);

View file

@ -4,17 +4,8 @@
#include "platform.h" #include "platform.h"
RingBufferT IO_BUF_T = RINGBUF_T_INIT( RingBufferT IO_BUF_T = RINGBUF_T(struct InputRecord, IO_BUF_SIZE);
struct RecordBuffer, RingBufferT STR_BUF_T = RINGBUF_T(char, STR_BUF_SIZE);
struct InputRecord,
IO_BUF_SIZE
);
RingBufferT STR_BUF_T = RINGBUF_T_INIT(
struct StringBuffer,
char,
STR_BUF_SIZE
);
void *input_worker(void *arg) void *input_worker(void *arg)
@ -54,7 +45,7 @@ void *input_worker(void *arg)
return nullptr; return nullptr;
} }
bool BeginInputThread(struct InputHandle *hand) bool CreateInputThread(struct InputHandle *hand)
{ {
*hand = (struct InputHandle) { *hand = (struct InputHandle) {
.recs.head = RINGBUF_HEAD_INIT, .recs.head = RINGBUF_HEAD_INIT,

View file

@ -100,7 +100,7 @@ struct InputHandle {
bool is_terminating; bool is_terminating;
}; };
bool BeginInputThread(struct InputHandle *hand); bool CreateInputThread(struct InputHandle *hand);
bool EndInputThread(struct InputHandle *hand); bool EndInputThread(struct InputHandle *hand);

View file

@ -1,14 +1,15 @@
#include "terminal.h" #include "terminal.h"
#include <string.h>
#define RESET_STR_LEN 7 #define RESET_STR_LEN 7
#define MAX_CH4_LEN 11 #define MAX_CH4_LEN 11
usize TerminalStringSize(usize wid, usize hgt) usize TerminalMaxOut(struct Terminal *term)
{ {
return RESET_STR_LEN return RESET_STR_LEN
+ MAX_CH4_LEN * wid * hgt + MAX_CH4_LEN * term->wid * term->hgt
+ hgt + term->hgt
+ 1; + 1;
} }
@ -23,7 +24,7 @@ bool CreateTerminal(struct Terminal *term, usize wid, usize hgt)
.wid = wid, .wid = wid,
.hgt = hgt, .hgt = hgt,
.ch4s = ch4s .buf = ch4s
}; };
return true; return true;
@ -31,10 +32,10 @@ bool CreateTerminal(struct Terminal *term, usize wid, usize hgt)
void FreeTerminal(struct Terminal *term) void FreeTerminal(struct Terminal *term)
{ {
free(term->ch4s); free(term->buf);
} }
usize u8_to_buf(char *buf, u8f x) usize u8_to_str(char *out, u8f x)
{ {
usize len = 1; usize len = 1;
@ -51,17 +52,17 @@ usize u8_to_buf(char *buf, u8f x)
hnds = tens / 10; hnds = tens / 10;
len = 3; len = 3;
buf[0] = hnds + 48; out[0] = hnds + 48;
buf[1] = tens + 48; out[1] = tens + 48;
buf[2] = ones + 48; out[2] = ones + 48;
} else { } else {
len = 2; len = 2;
buf[0] = tens + 48; out[0] = tens + 48;
buf[1] = ones + 48; out[1] = ones + 48;
} }
} else { } else {
buf[0] = x + 48; out[0] = x + 48;
} }
return len; return len;
@ -77,57 +78,57 @@ u8f ansi_fg(u8f fg)
return fg + (fg < 8 ? 30 : 82); return fg + (fg < 8 ? 30 : 82);
} }
usize ch4_dif_to_buf(char *buf, struct Color4 *dif, struct Char4 *ch4) usize ch4_dif_to_str(char *out, struct Color4 *dif, struct Char4 *ch4)
{ {
usize len = 0; usize len = 0;
if (dif->bg != ch4->color.bg) { if (dif->bg != ch4->color.bg) {
buf[len++] = '\x1b'; out[len++] = '\x1b';
buf[len++] = '['; out[len++] = '[';
len += u8_to_buf(buf + len, ansi_bg(ch4->color.bg)); len += u8_to_str(out + len, ansi_bg(ch4->color.bg));
if (dif->fg != ch4->color.fg) { if (dif->fg != ch4->color.fg) {
buf[len++] = ';'; out[len++] = ';';
len += u8_to_buf(buf + len, ansi_fg(ch4->color.fg)); len += u8_to_str(out + len, ansi_fg(ch4->color.fg));
} }
buf[len++] = 'm'; out[len++] = 'm';
} else if (dif->fg != ch4->color.fg) { } else if (dif->fg != ch4->color.fg) {
buf[len++] = '\x1b'; out[len++] = '\x1b';
buf[len++] = '['; out[len++] = '[';
len += u8_to_buf(buf + len, ansi_fg(ch4->color.fg)); len += u8_to_str(out + len, ansi_fg(ch4->color.fg));
buf[len++] = 'm'; out[len++] = 'm';
} }
buf[len++] = ch4->ch; out[len++] = ch4->ch;
*dif = ch4->color; *dif = ch4->color;
return len; return len;
} }
usize TerminalPrint(char *buf, usize n, struct Terminal *term) usize TerminalPrint(struct Terminal *term, char *out, usize n)
{ {
struct Char4 dif; struct Color4 dif = { 0, 0 };
usize len = 7; usize len = 7;
memcpy(buf, "\x1b[H\x1b[0m", 7); memcpy(out, "\x1b[H\x1b[0m", 7);
for (usize y = 0; y < term->hgt; y++) { for (usize y = 0; y < term->hgt; y++) {
for (usize x = 0; x < term->wid; x++) { for (usize x = 0; x < term->wid; x++) {
usize i = y * term->wid + x; usize i = y * term->wid + x;
struct Char4 *ch4 = &term->ch4s[i]; struct Char4 *ch4 = &term->buf[i];
// DEBUG // DEBUG
if (ch4->ch == 0) if (ch4->ch == 0)
ch4->ch = '#'; ch4->ch = '#';
// DEBUG // DEBUG
len += ch4_dif_to_buf(buf + len, &dif, ch4); len += ch4_dif_to_str(out + len, &dif, ch4);
} }
buf[len++] = '\n'; out[len++] = '\n';
} }
buf[len] = 0; out[len] = 0;
return len; return len;
} }

View file

@ -22,11 +22,13 @@ struct Terminal {
usize wid; usize wid;
usize hgt; usize hgt;
struct Char4 *ch4s; struct Char4 *buf;
}; };
usize TerminalMaxOut(struct Terminal *term);
bool CreateTerminal(struct Terminal *term, usize wid, usize hgt); bool CreateTerminal(struct Terminal *term, usize wid, usize hgt);
void FreeTerminal(struct Terminal *term); void FreeTerminal(struct Terminal *term);
usize TerminalPrint(char *buf, usize n, struct Terminal *term); usize TerminalPrint(struct Terminal *term, char *out, usize n);

View file

@ -1,114 +1,35 @@
#include "fumocommon.h" #include "fumotris.h"
#include "fumoengine.h"
enum ControlCode { void Update(struct FumoInstance *instance, void *args)
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) { struct Fumotris *game = args;
game->time = TimeNow();
if (!InputAquire(&game->input_hand)) TetrMapDraw(&game->board, &instance->term);
Panic("Aquire failed"); }
ControllerPoll(&game->ctrl, &game->input_hand.recs);
if (!InputRelease(&game->input_hand)) bool CreateFumotris(struct Fumotris *game)
Panic("Release failed"); {
if (!CreateTetrMap(&game->board, 10, 10))
return false;
return true;
EventInvoke(&game->update, 0);
_sleep(100);
}
} }
int main() int main()
{ {
struct FumoGame game; struct FumoInstance instance;
FumoInit(&game); CreateFumoInstance(&instance);
for (size_t i = 0; i < CODE_COUNT; i++) { struct Fumotris game;
const struct ControlBind *bind = &ctrl_binds[i]; CreateFumotris(&game);
ControllerMap(&game.ctrl, bind->code, bind->bind, bind->type);
}
Loop(&game); ControllerMapMulti(&instance.ctrl, CODE_COUNT, MAPPINGS);
FumoInstanceHook(&instance.on_update, Update, &game);
FumoInstanceRun(&instance);
return 0; 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
};*/

View file

@ -0,0 +1,84 @@
#include "fumocommon.h"
#include "fumoengine.h"
#include "tetr.h"
#define CODE_COUNT 12
enum ControlCode {
LEFT,
RIGHT,
SOFT_DROP,
HARD_DROP,
ROTATE_CCW,
ROTATE_CW,
ROTATE_180,
SWAP,
ESC,
VSCROLL,
HSCROLL,
MOUSE
};
struct ControlMapping MAPPINGS[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 }
};
struct Fumotris {
struct TetrMap board;
struct TetrMap piece;
};
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
};

View file

@ -1,62 +1,55 @@
#include <iso646.h> #include "tetr.h"
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fumocommon.h"
#include "term.h"
struct TetrMap { bool CreateTetrMap(struct TetrMap *map, usize wid, usize hgt)
size_t wid;
size_t hgt;
size_t area;
int x;
int y;
u8 rot;
u8 *blks;
};
struct TetrMap NewTetrMap(u8 *blks, size_t wid, size_t hgt)
{ {
size_t area = wid * hgt; u8 *blks = calloc(wid * hgt, sizeof(u8));
memset(blks, 0, area);
if (blks == nullptr)
return false;
return (struct TetrMap) { *map = (struct TetrMap) {
wid, hgt, area, .wid = wid,
0, 0, 0, .hgt = hgt,
blks
.x = 0,
.y = 0,
.rot = 0,
.blks = blks
}; };
return true;
} }
void TetrMapToTermBuf(struct TetrMap *map, struct Terminal *term) void FreeTetrMap(struct TetrMap *map)
{
free(map->blks);
}
void TetrMapDraw(struct TetrMap *map, struct Terminal *term)
{ {
static const u8f blk_colors[8] = { 8, 14, 11, 13, 10, 9, 12, 3 }; static const u8f blk_colors[8] = { 8, 14, 11, 13, 10, 9, 12, 3 };
for (size_t y = 0; y < map->hgt; y++) { for (usize y = 0; y < map->hgt; y++) {
for (size_t x = 0; x < map->wid; x++) { for (usize x = 0; x < map->wid; x++) {
size_t map_i = y * map->wid + x; usize map_i = y * map->wid + x;
size_t buf_i = (y + map->y) * term->wid + (x + map->x) * 2; usize term_i = (y + map->y) * term->wid + (x + map->x) * 2;
struct Char4 *a = &term->ch4s[buf_i]; struct Char4 *block = term->buf + term_i;
struct Char4 *b = &term->ch4s[buf_i + 1];
if (map->blks[map_i] == 0) { if (map->blks[map_i] == 0) {
a->ch = '('; block[0].ch = '(';
b->ch = ')'; block[1].ch = ')';
} else { } else {
a->ch = '['; block[0].ch = '[';
b->ch = ']'; block[1].ch = ']';
} }
u8 fg = blk_colors[map->blks[map_i]]; u8 fg = blk_colors[map->blks[map_i]];
a->fg = fg; block[0].color.fg = fg;
b->fg = fg; block[1].color.fg = fg;
} }
} }
} }

View file

@ -1,29 +1,26 @@
#include <iso646.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "fumocommon.h" #include "fumocommon.h"
#include "term.h" #include "terminal.h"
struct TetrMap { struct TetrMap {
size_t wid; usize wid;
size_t hgt; usize hgt;
size_t area;
int x; int x;
int y; int y;
u8 rot;
u8f rot;
u8 *blks; u8 *blks;
}; };
struct TetrMap NewTetrMap(u8 *blks, size_t wid, size_t hgt); bool CreateTetrMap(struct TetrMap *map, usize wid, usize hgt);
void TetrMapToTermBuf(struct TetrMap *map, struct Terminal *term); void FreeTetrMap(struct TetrMap *map);
void TetrMapDraw(struct TetrMap *map, struct Terminal *term);
bool TetrCollisionCheck(struct TetrMap *board, struct TetrMap *piece, int dx, int dy); bool TetrCollisionCheck(struct TetrMap *board, struct TetrMap *piece, int dx, int dy);

BIN
test.exe

Binary file not shown.