a
a
This commit is contained in:
parent
24599197c0
commit
2b15552401
|
@ -2,12 +2,12 @@
|
|||
#include <time.h>
|
||||
|
||||
|
||||
size_t MinSize(size_t a, size_t b)
|
||||
usize min_usize(usize a, usize b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
Time TimeNow()
|
||||
nsec TimeNow()
|
||||
{
|
||||
struct timespec ts;
|
||||
timespec_get(&ts, TIME_UTC);
|
||||
|
@ -21,4 +21,18 @@ double TimeNowD()
|
|||
timespec_get(&ts, TIME_UTC);
|
||||
|
||||
return ts.tv_sec + (double)ts.tv_nsec / 1000000000.0;
|
||||
}
|
||||
|
||||
u32 Hash(void *item, usize size)
|
||||
{
|
||||
u8 *data = (u8 *)item;
|
||||
|
||||
u32 h = 98317;
|
||||
for (usize i = 0; i < size; i++) {
|
||||
h ^= data[i];
|
||||
h *= 0x5bd1e995;
|
||||
h ^= h >> 15;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
|
@ -36,11 +36,12 @@ typedef int64_t i64;
|
|||
typedef int_fast64_t i64f;
|
||||
|
||||
|
||||
typedef u64 Time;
|
||||
typedef u64 nsec;
|
||||
|
||||
|
||||
size_t MinSize(size_t a, size_t b);
|
||||
size_t min_usize(usize a, usize b);
|
||||
|
||||
Time TimeNow();
|
||||
nsec TimeNow();
|
||||
double TimeNowD();
|
||||
|
||||
double TimeNowD();
|
||||
u32 Hash(void *item, usize size);
|
|
@ -8,6 +8,13 @@ void Panic(char *message)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void InvokeUpdate(void_func func, void *arg)
|
||||
{
|
||||
struct { nsec frametime; } *args = arg;
|
||||
|
||||
((update_func)func)(args->frametime);
|
||||
}
|
||||
|
||||
bool FumoInit(struct FumoGame *game)
|
||||
{
|
||||
if (!PlatformInit())
|
||||
|
|
|
@ -13,7 +13,7 @@ struct FumoGame {
|
|||
struct Event draw;
|
||||
struct Event update;
|
||||
|
||||
Time time;
|
||||
nsec time;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2,57 +2,49 @@
|
|||
|
||||
#define INIT_CAPACITY 16
|
||||
|
||||
size_t clbks_size(size_t capacity) {
|
||||
return sizeof(union func) * capacity;
|
||||
}
|
||||
|
||||
bool CreateEvent(struct Event *event)
|
||||
{
|
||||
union func *callbacks = malloc(clbks_size(INIT_CAPACITY));
|
||||
void_func *callbacks = malloc(INIT_CAPACITY * sizeof(void_func));
|
||||
|
||||
if (callbacks == nullptr)
|
||||
return false;
|
||||
|
||||
*event = (struct Event) {
|
||||
.clbks = callbacks,
|
||||
.callbacks = callbacks,
|
||||
.len = 0,
|
||||
.capacity = INIT_CAPACITY,
|
||||
.capacity = INIT_CAPACITY
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeEvent(struct Event *event)
|
||||
{
|
||||
free(event->clbks);
|
||||
free(event->callbacks);
|
||||
}
|
||||
|
||||
bool EventSubscribe(struct Event *event, union func callback)
|
||||
bool EventRegister(struct Event *event, void_func callback)
|
||||
{
|
||||
if (event->len == event->capacity) {
|
||||
size_t new_cap = event->capacity * 2;
|
||||
union func *new_clbks = realloc(event->clbks, clbks_size(new_cap));
|
||||
usize new_size = event->capacity * 2 * sizeof(void_func);
|
||||
void_func *new_callbacks = realloc(event->callbacks, new_size);
|
||||
|
||||
if (new_clbks == nullptr)
|
||||
if (new_callbacks == nullptr)
|
||||
return false;
|
||||
|
||||
event->clbks = new_clbks;
|
||||
event->capacity = new_cap;
|
||||
event->callbacks = new_callbacks;
|
||||
event->capacity = new_size;
|
||||
}
|
||||
|
||||
event->clbks[event->len++] = callback;
|
||||
event->callbacks[event->len++] = callback;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EventInvoke(struct Event *event, void *arg)
|
||||
void EventInvoke(struct Event *event, void *args)
|
||||
{
|
||||
for (size_t i = 0; i < event->len; i++) {
|
||||
event->clbks[i].generic(arg);
|
||||
}
|
||||
}
|
||||
|
||||
void EventInvokeUpdate(struct Event *event, Time dt)
|
||||
{
|
||||
for (size_t i = 0; i < event->len; i++) {
|
||||
event->clbks[i].update(dt);
|
||||
for (usize i = 0; i < event->len; i++) {
|
||||
event->callbacks[i](args);
|
||||
}
|
||||
}
|
|
@ -8,21 +8,20 @@
|
|||
#include "fumocommon.h"
|
||||
|
||||
|
||||
union func {
|
||||
void (*generic)(void *arg);
|
||||
void (*update)(Time dt);
|
||||
};
|
||||
typedef void (*void_func)(void *arg);
|
||||
|
||||
typedef void (*invoker_func)(void_func func, void *arg);
|
||||
|
||||
|
||||
struct Event {
|
||||
union func *clbks;
|
||||
size_t len;
|
||||
size_t capacity;
|
||||
void_func *callbacks;
|
||||
usize len;
|
||||
usize capacity;
|
||||
};
|
||||
|
||||
|
||||
bool CreateEvent(struct Event *event);
|
||||
|
||||
bool EventSubscribe(struct Event *event, union func callback);
|
||||
bool EventRegister(struct Event *event, void_func callback);
|
||||
|
||||
void EventInvoke(struct Event *event, void *arg);
|
||||
|
||||
void EventInvokeUpdate(struct Event *event, Time dt);
|
||||
void EventInvoke(struct Event *event, void *args);
|
|
@ -1,24 +0,0 @@
|
|||
#include <iso646.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fumocommon.h"
|
||||
|
||||
|
||||
typedef u32 hashtype;
|
||||
|
||||
hashtype Hash(void *item, size_t size)
|
||||
{
|
||||
u8 *data = (u8 *)item;
|
||||
|
||||
u32 h = 98317;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
h ^= data[i];
|
||||
h *= 0x5bd1e995;
|
||||
h ^= h >> 15;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#pragma once
|
||||
#include <iso646.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fumocommon.h"
|
||||
|
||||
|
||||
typedef u32 hashtype;
|
||||
|
||||
hashtype Hash(void *item, size_t size);
|
|
@ -37,7 +37,7 @@ void RingBufferTransfer(
|
|||
struct RingBufferHead *dest,
|
||||
struct RingBufferHead *tmp
|
||||
) {
|
||||
size_t copy_max = MinSize(T->LEN - dest->len, tmp->len);
|
||||
size_t copy_max = min_usize(T->LEN - dest->len, tmp->len);
|
||||
|
||||
for (size_t i = 0; i < copy_max; i++) {
|
||||
void *to = RingBufferGet(T, dest, dest->len + i);
|
||||
|
@ -55,7 +55,7 @@ size_t RingBufferOut(
|
|||
void *dest,
|
||||
struct RingBufferHead *src
|
||||
) {
|
||||
size_t copy_max = MinSize(n, src->len);
|
||||
size_t copy_max = min_usize(n, src->len);
|
||||
|
||||
for (size_t i = 0; i < copy_max; i++) {
|
||||
void *to = (u8 *)dest + i * T->SIZE;
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
|
||||
struct InputAxis {
|
||||
Time last_pressed;
|
||||
Time last_released;
|
||||
nsec last_pressed;
|
||||
nsec last_released;
|
||||
|
||||
union {
|
||||
struct Button but;
|
||||
|
|
|
@ -60,7 +60,7 @@ union InputData {
|
|||
|
||||
|
||||
struct InputRecord {
|
||||
Time time;
|
||||
nsec time;
|
||||
|
||||
union {
|
||||
struct Button but;
|
||||
|
|
|
@ -20,4 +20,4 @@ bool PlatformReadInput(struct RecordBuffer *recs, struct StringBuffer *str);
|
|||
|
||||
bool PlatformStopInput();
|
||||
|
||||
bool PlatformWait(Time duration);
|
||||
bool PlatformWait(nsec duration);
|
|
@ -176,7 +176,7 @@ bool PlatformReadInput(struct RecordBuffer *recs, struct StringBuffer *str)
|
|||
if (len == 0)
|
||||
return false;
|
||||
|
||||
Time now = TimeNow();
|
||||
nsec now = TimeNow();
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
struct InputRecord *rec = RingBufferNext(IO_BUF_T, &recs->head);
|
||||
|
@ -195,7 +195,7 @@ bool PlatformStopInput()
|
|||
return CancelSynchronousIo(win.input_hand);
|
||||
}
|
||||
|
||||
bool PlatformWait(Time duration)
|
||||
bool PlatformWait(nsec duration)
|
||||
{
|
||||
LARGE_INTEGER nsec_div_100;
|
||||
nsec_div_100.QuadPart = -duration / 100;
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
#include "term.h"
|
||||
|
||||
|
||||
size_t term_buf_size(size_t area, size_t hgt)
|
||||
{
|
||||
static const size_t reset_str_len = 7;
|
||||
static const size_t max_color_str_len = 10;
|
||||
|
||||
return reset_str_len + (max_color_str_len + 1) * area + hgt + 1;
|
||||
}
|
||||
|
||||
bool CreateTerminal(struct Terminal *term, size_t wid, size_t hgt)
|
||||
{
|
||||
size_t area = wid * hgt;
|
||||
size_t buf_size = term_buf_size(area, hgt);
|
||||
|
||||
struct Char4 *chs = calloc(area, sizeof(struct Char4));
|
||||
|
||||
if (chs == nullptr)
|
||||
return false;
|
||||
|
||||
*term = (struct Terminal) {
|
||||
.wid = wid,
|
||||
.hgt = hgt,
|
||||
.area = area,
|
||||
|
||||
.chs = chs,
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeTerminal(struct Terminal *term)
|
||||
{
|
||||
free(term->chs);
|
||||
}
|
||||
|
||||
size_t u8_to_buf(char *buf, u8f x)
|
||||
{
|
||||
size_t len = 1;
|
||||
|
||||
if (x > 9) {
|
||||
u8f o, t;
|
||||
|
||||
o = x % 10;
|
||||
t = x / 10;
|
||||
|
||||
if (x > 99) {
|
||||
u8f h;
|
||||
|
||||
t %= 10;
|
||||
h = t / 10;
|
||||
len = 3;
|
||||
|
||||
buf[0] = h + 48;
|
||||
buf[1] = t + 48;
|
||||
buf[2] = o + 48;
|
||||
} else {
|
||||
len = 2;
|
||||
|
||||
buf[0] = t + 48;
|
||||
buf[1] = o + 48;
|
||||
}
|
||||
} else {
|
||||
buf[0] = x + 48;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t ch4_dif_to_buf(char *buf, struct Char4 *dif, struct Char4 *blk)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
if (dif->bg != blk->bg) {
|
||||
dif->bg = blk->bg;
|
||||
u8f bg = blk->bg + (blk->bg < 8 ? 40 : 92);
|
||||
|
||||
buf[len++] = '\x1b';
|
||||
buf[len++] = '[';
|
||||
len += u8_to_buf(buf + len, bg);
|
||||
|
||||
if (dif->fg != blk->fg) {
|
||||
dif->fg = blk->fg;
|
||||
u8f fg = blk->fg + (blk->fg < 8 ? 30 : 82);
|
||||
|
||||
buf[len++] = ';';
|
||||
len += u8_to_buf(buf + len, fg);
|
||||
}
|
||||
|
||||
buf[len++] = 'm';
|
||||
} else if (dif->fg != blk->fg) {
|
||||
dif->fg = blk->fg;
|
||||
u8f fg = blk->fg + (blk->fg < 8 ? 30 : 82);
|
||||
|
||||
buf[len++] = '\x1b';
|
||||
buf[len++] = '[';
|
||||
len += u8_to_buf(buf + len, fg);
|
||||
buf[len++] = 'm';
|
||||
}
|
||||
buf[len++] = blk->ch;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t TerminalPrint(char *dest, size_t n, struct Terminal *term)
|
||||
{
|
||||
struct Char4 dif;
|
||||
|
||||
size_t len = 7;
|
||||
memcpy(term->buf, "\x1b[H\x1b[0m", 7);
|
||||
|
||||
for (size_t y = 0; y < term->hgt; y++) {
|
||||
for (size_t x = 0; x < term->wid; x++) {
|
||||
size_t i = y * term->wid + x;
|
||||
struct Char4 *blk = &term->chs[i];
|
||||
|
||||
// DEBUG
|
||||
if (blk->ch == 0)
|
||||
blk->ch = '#';
|
||||
// DEBUG
|
||||
|
||||
len += ch4_dif_to_buf(term->buf + len, &dif, blk);
|
||||
}
|
||||
term->buf[len++] = '\n';
|
||||
}
|
||||
|
||||
term->buf[len] = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
/*int main()
|
||||
{
|
||||
struct Terminal term;
|
||||
NewTerm(&term, 20, 20);
|
||||
|
||||
for (int i = 0; i < 20 * 20; i++) {
|
||||
term.blks[i].ch = 'l';
|
||||
term.blks[i].bg = 0;
|
||||
term.blks[i].fg = 8;
|
||||
}
|
||||
|
||||
size_t len = TermOut(&term);
|
||||
puts(term.buf);
|
||||
|
||||
printf("hi");
|
||||
return 0;
|
||||
}*/
|
133
source/fumoengine/terminal/terminal.c
Normal file
133
source/fumoengine/terminal/terminal.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
#include "terminal.h"
|
||||
|
||||
#define RESET_STR_LEN 7
|
||||
#define MAX_CH4_LEN 11
|
||||
|
||||
|
||||
usize TerminalStringSize(usize wid, usize hgt)
|
||||
{
|
||||
return RESET_STR_LEN
|
||||
+ MAX_CH4_LEN * wid * hgt
|
||||
+ hgt
|
||||
+ 1;
|
||||
}
|
||||
|
||||
bool CreateTerminal(struct Terminal *term, usize wid, usize hgt)
|
||||
{
|
||||
struct Char4 *ch4s = calloc(wid * hgt, sizeof(struct Char4));
|
||||
|
||||
if (ch4s == nullptr)
|
||||
return false;
|
||||
|
||||
*term = (struct Terminal) {
|
||||
.wid = wid,
|
||||
.hgt = hgt,
|
||||
|
||||
.ch4s = ch4s
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeTerminal(struct Terminal *term)
|
||||
{
|
||||
free(term->ch4s);
|
||||
}
|
||||
|
||||
usize u8_to_buf(char *buf, u8f x)
|
||||
{
|
||||
usize len = 1;
|
||||
|
||||
if (x > 9) {
|
||||
u8f ones, tens;
|
||||
|
||||
ones = x % 10;
|
||||
tens = x / 10;
|
||||
|
||||
if (x > 99) {
|
||||
u8f hnds;
|
||||
|
||||
tens %= 10;
|
||||
hnds = tens / 10;
|
||||
len = 3;
|
||||
|
||||
buf[0] = hnds + 48;
|
||||
buf[1] = tens + 48;
|
||||
buf[2] = ones + 48;
|
||||
} else {
|
||||
len = 2;
|
||||
|
||||
buf[0] = tens + 48;
|
||||
buf[1] = ones + 48;
|
||||
}
|
||||
} else {
|
||||
buf[0] = x + 48;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
u8f ansi_bg(u8f bg)
|
||||
{
|
||||
return bg + (bg < 8 ? 40 : 92);
|
||||
}
|
||||
|
||||
u8f ansi_fg(u8f fg)
|
||||
{
|
||||
return fg + (fg < 8 ? 30 : 82);
|
||||
}
|
||||
|
||||
usize ch4_dif_to_buf(char *buf, struct Color4 *dif, struct Char4 *ch4)
|
||||
{
|
||||
usize len = 0;
|
||||
|
||||
if (dif->bg != ch4->color.bg) {
|
||||
buf[len++] = '\x1b';
|
||||
buf[len++] = '[';
|
||||
len += u8_to_buf(buf + len, ansi_bg(ch4->color.bg));
|
||||
|
||||
if (dif->fg != ch4->color.fg) {
|
||||
buf[len++] = ';';
|
||||
len += u8_to_buf(buf + len, ansi_fg(ch4->color.fg));
|
||||
}
|
||||
|
||||
buf[len++] = 'm';
|
||||
|
||||
} else if (dif->fg != ch4->color.fg) {
|
||||
buf[len++] = '\x1b';
|
||||
buf[len++] = '[';
|
||||
len += u8_to_buf(buf + len, ansi_fg(ch4->color.fg));
|
||||
buf[len++] = 'm';
|
||||
}
|
||||
|
||||
buf[len++] = ch4->ch;
|
||||
*dif = ch4->color;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
usize TerminalPrint(char *buf, usize n, struct Terminal *term)
|
||||
{
|
||||
struct Char4 dif;
|
||||
|
||||
usize len = 7;
|
||||
memcpy(buf, "\x1b[H\x1b[0m", 7);
|
||||
|
||||
for (usize y = 0; y < term->hgt; y++) {
|
||||
for (usize x = 0; x < term->wid; x++) {
|
||||
usize i = y * term->wid + x;
|
||||
struct Char4 *ch4 = &term->ch4s[i];
|
||||
|
||||
// DEBUG
|
||||
if (ch4->ch == 0)
|
||||
ch4->ch = '#';
|
||||
// DEBUG
|
||||
|
||||
len += ch4_dif_to_buf(buf + len, &dif, ch4);
|
||||
}
|
||||
buf[len++] = '\n';
|
||||
}
|
||||
|
||||
buf[len] = 0;
|
||||
return len;
|
||||
}
|
|
@ -8,22 +8,25 @@
|
|||
#include "fumocommon.h"
|
||||
|
||||
|
||||
struct Char4 {
|
||||
char ch;
|
||||
struct Color4 {
|
||||
u8 bg : 4;
|
||||
u8 fg : 4;
|
||||
};
|
||||
|
||||
struct Terminal {
|
||||
size_t wid;
|
||||
size_t hgt;
|
||||
size_t area;
|
||||
|
||||
struct Char4 *chs;
|
||||
struct Char4 {
|
||||
struct Color4 color;
|
||||
char ch;
|
||||
};
|
||||
|
||||
bool CreateTerminal(struct Terminal *term, size_t wid, size_t hgt);
|
||||
struct Terminal {
|
||||
usize wid;
|
||||
usize hgt;
|
||||
|
||||
struct Char4 *ch4s;
|
||||
};
|
||||
|
||||
bool CreateTerminal(struct Terminal *term, usize wid, usize hgt);
|
||||
|
||||
void FreeTerminal(struct Terminal *term);
|
||||
|
||||
size_t TerminalPrint(char *dest, size_t n, struct Terminal *term);
|
||||
usize TerminalPrint(char *buf, usize n, struct Terminal *term);
|
|
@ -43,13 +43,13 @@ void Loop(struct FumoGame *game)
|
|||
Panic("Aquire failed");
|
||||
|
||||
ControllerPoll(&game->ctrl, &game->input_hand.recs);
|
||||
u64 val = ControllerGet(&game->ctrl, LEFT, BUTTON)->is_down;
|
||||
printf("%u\n", val);
|
||||
|
||||
if (!InputRelease(&game->input_hand))
|
||||
Panic("Release failed");
|
||||
|
||||
EventInvokeUpdate(&game->update, 0);
|
||||
|
||||
|
||||
EventInvoke(&game->update, 0);
|
||||
|
||||
_sleep(100);
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ void TetrMapToTermBuf(struct TetrMap *map, struct Terminal *term)
|
|||
size_t map_i = y * map->wid + x;
|
||||
size_t buf_i = (y + map->y) * term->wid + (x + map->x) * 2;
|
||||
|
||||
struct Char4 *a = &term->chs[buf_i];
|
||||
struct Char4 *b = &term->chs[buf_i + 1];
|
||||
struct Char4 *a = &term->ch4s[buf_i];
|
||||
struct Char4 *b = &term->ch4s[buf_i + 1];
|
||||
|
||||
if (map->blks[map_i] == 0) {
|
||||
a->ch = '(';
|
||||
|
|
Loading…
Reference in a new issue