dfg
This commit is contained in:
Julia 2024-05-13 23:20:20 -05:00
parent 8b482a0bb6
commit 582b157454
32 changed files with 315 additions and 170 deletions

21
.vscode/c_cpp_properties.json vendored Normal file
View file

@ -0,0 +1,21 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.22000.0",
"compilerPath": "C:/mingw64/bin/gcc.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}

11
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"files.associations": {
"compare": "c",
"concepts": "c",
"cstdlib": "c",
"type_traits": "c",
"cmath": "c",
"limits": "c",
"new": "c"
}
}

View file

@ -11,7 +11,7 @@ ARGS = "-fdiagnostics-color -pthread -Wall -std=c17 -pedantic -g"
SOURCE_DIR = Path("source/") SOURCE_DIR = Path("source/")
OBJECT_DIR = Path("objects/") OBJECT_DIR = Path("objects/")
OUTPUT = Path("build/debug") OUTPUT = Path("debug")
SRC_CHECKSUMS_TXT = Path("build/src_checksums.txt") SRC_CHECKSUMS_TXT = Path("build/src_checksums.txt")

Binary file not shown.

View file

@ -1 +1 @@
{"tetr": "", "ringbuffer": "", "event": "", "ctrl": "", "terminal": "", "fumoengine": "", "parseinput": "", "dictionary": "", "fumocommon": "", "win": "", "input": "", "fumotris": "", "vector": ""} {"ringbuffer": "", "event": "", "ctrl": "", "terminal": "", "fumoengine": "", "parseinput": "", "dictionary": "", "fumocommon": "", "win": "", "input": "", "fumotris": "", "vector": "", "tetra": ""}

View file

@ -1 +1 @@
["0d7597ffd48812c52d3f02731cbf693f", "6669fc7fcffc77563f1315cb7710ec82", "fbccab3d5cd1838cbf8ad1d4e2a7c03b", "1d6bdf7e8de4ac751252b67027e5d57e", "330b6f9493d091e7c340c1434b6f80b4", "a3dca3fbce775b791384bec8abc3f0c3", "f61af2abe56cd6881a830ae6222483e9", "1cdcae043579aa6406b9823b5f52aedd", "088145536b04ef82517eb93630888dff", "1420f33d62a8ed8429c8f1a96f1ab33e", "e38bd5ea2b554a21849158242a2add8e", "9df90eabc8908cac60aa774d335a106c", "333c7211bb2c72ad321495f53d11bff0", "dc6df72158812bc9f6ed484a4cfb046b"] ["1d6bdf7e8de4ac751252b67027e5d57e", "9df90eabc8908cac60aa774d335a106c", "1420f33d62a8ed8429c8f1a96f1ab33e", "dc6df72158812bc9f6ed484a4cfb046b", "6669fc7fcffc77563f1315cb7710ec82", "333c7211bb2c72ad321495f53d11bff0", "088145536b04ef82517eb93630888dff", "f61af2abe56cd6881a830ae6222483e9", "e09059d1f20c982c6c42a61a0754c102", "fbccab3d5cd1838cbf8ad1d4e2a7c03b", "330b6f9493d091e7c340c1434b6f80b4", "e38bd5ea2b554a21849158242a2add8e"]

BIN
debug.exe Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
objects/tetra.o Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -9,7 +9,6 @@
typedef size_t usize; typedef size_t usize;
typedef ptrdiff_t isize;
typedef uint8_t u8; typedef uint8_t u8;

View file

@ -51,9 +51,10 @@ bool FumoInstanceRun(struct FumoInstance *inst)
nsec now = TimeNow(); nsec now = TimeNow();
inst->frametime = now - inst->time; inst->frametime = now - inst->time;
EventInvoke(&inst->on_update, inst);
inst->time = now; inst->time = now;
EventInvoke(&inst->on_update, inst);
TerminalPrint(&inst->term, buf, buf_n); TerminalPrint(&inst->term, buf, buf_n);
puts(buf); puts(buf);

View file

@ -1,4 +1,5 @@
#include "dictionary.h" #include "dictionary.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -74,7 +75,11 @@ void *DictionaryFind(DictT T, struct Dictionary *dict, u32 key)
{ {
usize index = key % dict->capacity; usize index = key % dict->capacity;
return probe_bkt(T, dict, index, key); void *bkt = probe_bkt(T, dict, index, key);
if (bkt == nullptr)
return false;
return get_val(T, bkt);
} }
void *DictionarySet(DictT T, struct Dictionary *dict, u32 key, void *val) void *DictionarySet(DictT T, struct Dictionary *dict, u32 key, void *val)
@ -82,6 +87,7 @@ void *DictionarySet(DictT T, struct Dictionary *dict, u32 key, void *val)
usize index = key % dict->capacity; usize index = key % dict->capacity;
void *bkt = probe_empty_bkt(T, dict, index, key); 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); set_bkt(T, bkt, key, val);

View file

@ -10,18 +10,15 @@ DictT BIND_T = DICT_T(struct InputAxis *);
bool CreateController(struct Controller *ctrl) bool CreateController(struct Controller *ctrl)
{ {
struct InputAxis *axes = calloc(16, sizeof(struct InputAxis)); struct InputAxis *axes = calloc(16, sizeof(struct InputAxis));
if (axes == nullptr) if (axes == nullptr)
return false; return false;
if (!CreateDictionary(BIND_T, &ctrl->binds)) if (!CreateDictionary(BIND_T, &ctrl->binds))
return false; return false;
*ctrl = (struct Controller) { ctrl->pending_len = 0;
.pending_len = 0, ctrl->axes = axes;
.axes = axes, ctrl->axes_len = 0;
.axes_len = 0
};
return true; return true;
} }
@ -42,13 +39,11 @@ bool ControllerBind(struct Controller *ctrl, u16 control, u16 code, u16 type)
u32 hash = hash_bind(code, type); u32 hash = hash_bind(code, type);
struct InputAxis *axis = &ctrl->axes[control]; struct InputAxis *axis = &ctrl->axes[control];
struct InputAxis **bind = DictionarySet(BIND_T, &ctrl->binds, hash, axis); struct InputAxis **bind = DictionarySet(BIND_T, &ctrl->binds, hash, &axis);
if (bind == nullptr) if (bind == nullptr)
return false; return false;
*bind = axis;
return true; return true;
} }
@ -97,13 +92,13 @@ void ControllerPoll(struct Controller *ctrl, struct RecordBuffer *recs)
struct InputRecord *rec = recs->buf + i; struct InputRecord *rec = recs->buf + i;
u32 hash = hash_bind(rec->code, rec->type); u32 hash = hash_bind(rec->code, rec->type);
struct InputAxis *axis = DictionaryFind(BIND_T, &ctrl->binds, hash); struct InputAxis **axis = DictionaryFind(BIND_T, &ctrl->binds, hash);
if (axis == nullptr) if (axis == nullptr)
continue; continue;
dispatch_update(axis, rec); dispatch_update(*axis, rec);
ctrl->pending[ctrl->pending_len++] = axis; ctrl->pending[ctrl->pending_len++] = *axis;
} }
recs->head.len = 0; recs->head.len = 0;

View file

@ -114,9 +114,9 @@ usize TerminalPrint(struct Terminal *term, char *out, usize n)
usize len = 7; usize len = 7;
memcpy(out, "\x1b[H\x1b[0m", 7); memcpy(out, "\x1b[H\x1b[0m", 7);
usize i = 0;
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++, i++) {
usize i = y * term->wid + x;
struct Char4 *ch4 = &term->buf[i]; struct Char4 *ch4 = &term->buf[i];
// DEBUG // DEBUG

View file

@ -2,36 +2,69 @@
struct Fumotris { struct Fumotris {
struct TetrMap board; struct Tetra board;
struct TetrMap piece; struct Tetra piece;
nsec timer;
bool is_ground;
}; };
void FumotrisStart(void *inst_arg, void *game_arg) void FumotrisStart(struct FumoInstance *inst, struct Fumotris *fumo)
{ {
struct FumoInstance *inst = inst_arg;
struct Fumotris *game = game_arg;
ControllerBindMulti(&inst->ctrl, BINDS_N, controls_g, codes_g, types_g); ControllerBindMulti(&inst->ctrl, BINDS_N, controls_g, codes_g, types_g);
CreateTetrMap(&game->board, 10, 10); CreateTetra(&fumo->board, 10, 10);
CreateTetrMap(&game->piece, 3, 3); SetTetra(&fumo->piece, T, 3, 3, 0, 0);
game->piece.blks = T; fumo->timer = 0;
fumo->is_ground = false;
} }
void FumotrisUpdate(void *inst_arg, void *game_arg) void FumotrisUpdate(struct FumoInstance *inst, struct Fumotris *fumo)
{ {
struct FumoInstance *inst = inst_arg; i16 horizontal = 0;
struct Fumotris *game = game_arg;
if (inst->ctrl.axes[LEFT].is_down) if (inst->ctrl.axes[LEFT].is_down)
game->piece.x -= 1; horizontal -= 1;
if (inst->ctrl.axes[RIGHT].is_down) if (inst->ctrl.axes[RIGHT].is_down)
game->piece.x += 1; horizontal += 1;
TetraMove(&fumo->piece, &fumo->board, horizontal, 0);
TetrMapDraw(&game->board, &inst->term);
TetrMapDraw(&game->piece, &inst->term); if (inst->ctrl.axes[SOFT_DROP].is_down)
TetraMove(&fumo->piece, &fumo->board, 0, 1);
if (inst->ctrl.axes[HARD_DROP].is_down) {
while (TetraMove(&fumo->piece, &fumo->board, 0, 1));
fumo->timer = 0;
TetraOverlay(&fumo->piece, &fumo->board);
SetTetra(&fumo->piece, I, 4, 4, 0, 0);
return;
}
fumo->timer += inst->frametime;
while (fumo->timer > 5e8) {
fumo->timer -= 5e8;
if (!TetraMove(&fumo->piece, &fumo->board, 0, 1)) {
if (!fumo->is_ground) {
fumo->is_ground = true;
} else {
TetraOverlay(&fumo->piece, &fumo->board);
SetTetra(&fumo->piece, I, 4, 4, 0, 0);
fumo->is_ground = false;
}
}
}
}
void FumotrisDraw(struct FumoInstance *inst, struct Fumotris *fumo)
{
TetraTerminalClear(&fumo->board, &inst->term);
TetraTerminalDraw(&fumo->board, &inst->term);
TetraTerminalDraw(&fumo->piece, &inst->term);
} }
int main() int main()

View file

@ -1,6 +1,6 @@
#include "fumocommon.h" #include "fumocommon.h"
#include "fumoengine.h" #include "fumoengine.h"
#include "tetr.h" #include "tetra.h"
#define BINDS_N 12 #define BINDS_N 12
@ -22,6 +22,12 @@ enum FumotrisControls {
MOUSE MOUSE
}; };
struct TetraTemplate {
u8 *blks;
u16 wid;
u16 hgt;
};
u16 controls_g[BINDS_N] = { u16 controls_g[BINDS_N] = {
LEFT, LEFT,
@ -74,44 +80,72 @@ u16 types_g[BINDS_N] = {
JOYSTICK JOYSTICK
}; };
u8 I[16] = { struct TetraTemplate I = {
.blks = &(u8) {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0 0, 0, 0, 0
},
.wid = 4,
.hgt = 4
}; };
u8 O[4] = { struct TetraTemplate O = {
.blks = &(u8) {
1, 1, 1, 1,
1, 1 1, 1
},
.wid = 2,
.hgt = 2
}; };
u8 T[9] = { struct TetraTemplate T = {
.blks = &(u8) {
0, 1, 0, 0, 1, 0,
1, 1, 1, 1, 1, 1,
0, 0, 0 0, 0, 0
},
.wid = 3,
.hgt = 3
}; };
u8 S[9] = { struct TetraTemplate S = {
.blks = &(u8) {
0, 1, 1, 0, 1, 1,
1, 1, 0, 1, 1, 0,
0, 0, 0 0, 0, 0
},
.wid = 3,
.hgt = 3
}; };
u8 Z[9] = { struct TetraTemplate Z = {
.blks = &(u8) {
1, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 1,
0, 0, 0 0, 0, 0
},
.wid = 3,
.hgt = 3
}; };
u8 J[9] = { struct TetraTemplate J = {
.blks = &(u8) {
1, 0, 0, 1, 0, 0,
1, 1, 1, 1, 1, 1,
0, 0, 0 0, 0, 0
},
.wid = 3,
.hgt = 3
}; };
u8 L[9] = { struct TetraTemplate L = {
.blks = &(u8) {
0, 0, 1, 0, 0, 1,
1, 1, 1, 1, 1, 1,
0, 0, 0 0, 0, 0
},
.wid = 3,
.hgt = 3
}; };

View file

@ -1,77 +0,0 @@
#include "tetr.h"
bool CreateTetrMap(struct TetrMap *map, usize wid, usize hgt)
{
u8 *blks = calloc(wid * hgt, sizeof(u8));
if (blks == nullptr)
return false;
*map = (struct TetrMap) {
.wid = wid,
.hgt = hgt,
.x = 0,
.y = 0,
.rot = 0,
.blks = blks
};
return true;
}
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 };
for (usize y = 0; y < map->hgt; y++) {
for (usize x = 0; x < map->wid; x++) {
usize map_i = y * map->wid + x;
usize term_i = (y + map->y) * term->wid + (x + map->x) * 2;
struct Char4 *block = term->buf + term_i;
if (map->blks[map_i] == 0) {
block[0].ch = '(';
block[1].ch = ')';
} else {
block[0].ch = '[';
block[1].ch = ']';
}
u8 fg = blk_colors[map->blks[map_i]];
block[0].color.fg = fg;
block[1].color.fg = fg;
}
}
}
bool TetrCollisionCheck(struct TetrMap *board, struct TetrMap *piece, int dx, int dy)
{
size_t i = 0;
for (size_t y = piece->y + dy; y < piece->y + piece->hgt + dy; y++) {
for (size_t x = piece->x + dx; x < piece->x + piece->wid + dx; x++) {
if(piece->blks[i] == 0)
goto next;
if(y >= board->hgt or x >= board->wid)
return false;
size_t board_i = y * board->wid + x;
if(board->blks[board_i] != 0)
return false;
next:
i++;
}
}
return true;
}

View file

@ -1,26 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "fumocommon.h"
#include "terminal.h"
struct TetrMap {
usize wid;
usize hgt;
int x;
int y;
u8f rot;
u8 *blks;
};
bool CreateTetrMap(struct TetrMap *map, usize wid, usize hgt);
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);

115
source/fumotris/tetra.c Normal file
View file

@ -0,0 +1,115 @@
#include "tetra.h"
bool CreateTetra(struct Tetra *map, u16 wid, u16 hgt)
{
u8 *blks = calloc(wid * hgt, sizeof(u8));
if (blks == nullptr)
return false;
map->blks = blks;
map->wid = wid;
map->hgt = hgt;
map->x = 0;
map->y = 0;
map->rot = 0;
return true;
}
void FreeTetra(struct Tetra *tetra)
{
free(tetra->blks);
}
void SetTetra(struct Tetra *map, u8 *blks, u16 wid, u16 hgt, i16 x, i16 y)
{
map->blks = blks;
map->wid = wid;
map->hgt = hgt;
map->x = x;
map->y = y;
map->rot = 0;
}
bool TetraMove(struct Tetra *piece, struct Tetra *board, i16 dx, i16 dy)
{
if (TetraIsCollision(piece, board, dx, dy))
return false;
piece->x += dx;
piece->y += dy;
return true;
}
bool TetraIsCollision(struct Tetra *piece, struct Tetra *board, i16 dx, i16 dy)
{
i16 x_start = piece->x + dx;
i16 y_start = piece->y + dy;
usize i = 0;
for (i16 y = y_start; y < y_start + piece->hgt; y++) {
for (i16 x = x_start; x < x_start + piece->wid; x++, i++) {
if(piece->blks[i] == 0)
continue;
if(x < 0 or x >= board->wid or y < 0 or y >= board->hgt)
return true;
if(board->blks[board->wid * y + x] != 0)
return true;
}
}
return false;
}
void TetraTerminalClear(struct Tetra *board, struct Terminal *term)
{
for (usize i = 0; i < board->wid * board->hgt; i++) {
struct Char4 *block = term->buf + i * 2;
block[0] = (struct Char4) { .ch = '(', .color.fg = 8 };
block[1] = (struct Char4) { .ch = ')', .color.fg = 8 };
}
}
void TetraTerminalDraw(struct Tetra *tetra, struct Terminal *term)
{
static const u8f blk_colors[8] = { 8, 14, 11, 13, 10, 9, 12, 3 };
usize i = 0;
for (usize y = 0; y < tetra->hgt; y++) {
for (usize x = 0; x < tetra->wid; x++, i++) {
if (tetra->blks[i] == 0)
continue;
usize term_i = (y + tetra->y) * term->wid + (x + tetra->x) * 2;
struct Char4 *block = term->buf + term_i;
u8 fg = blk_colors[tetra->blks[i]];
block[0] = (struct Char4) { .ch = '[', .color.fg = fg };
block[1] = (struct Char4) { .ch = ']', .color.fg = fg };
}
}
}
void TetraOverlay(struct Tetra *piece, struct Tetra *board)
{
usize i = 0;
for (usize y = piece->y; y < piece->y + piece->hgt; y++) {
for (usize x = piece->x; x < piece->x + piece->wid; x++, i++) {
if(piece->blks[i] == 0)
continue;
if(x < 0 or x >= board->wid or y < 0 or y >= board->hgt)
continue;
board->blks[board->wid * y + x] = piece->blks[i];
}
}
}

33
source/fumotris/tetra.h Normal file
View file

@ -0,0 +1,33 @@
#include <stdio.h>
#include <stdlib.h>
#include "fumocommon.h"
#include "terminal.h"
struct Tetra {
u8 *blks;
u16 wid;
u16 hgt;
i16 x;
i16 y;
u8f rot;
};
bool CreateTetra(struct Tetra *map, u16 wid, u16 hgt);
void FreeTetra(struct Tetra *map);
void SetTetra(struct Tetra *map, u8 *blks, u16 wid, u16 hgt, i16 x, i16 y);
void TetraTerminalClear(struct Tetra *board, struct Terminal *term);
void TetraTerminalDraw(struct Tetra *map, struct Terminal *term);
bool TetraMove(struct Tetra *piece, struct Tetra *board, i16 dx, i16 dy);
bool TetraIsCollision(struct Tetra *piece, struct Tetra *board, i16 dx, i16 dy);
void TetraOverlay(struct Tetra *piece, struct Tetra *board);