2024-05-07 22:10:15 +00:00
|
|
|
#include "fumotris.h"
|
2024-05-15 05:44:13 +00:00
|
|
|
#include <stdlib.h>
|
2024-05-02 22:17:37 +00:00
|
|
|
|
|
|
|
|
2024-05-08 12:47:46 +00:00
|
|
|
struct Fumotris {
|
2024-05-15 22:10:47 +00:00
|
|
|
struct Terminal term;
|
|
|
|
|
|
|
|
struct TetraTemplate *bag[7];
|
|
|
|
usize bag_i;
|
|
|
|
|
2024-05-14 04:20:20 +00:00
|
|
|
struct Tetra board;
|
|
|
|
struct Tetra piece;
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-14 04:20:20 +00:00
|
|
|
bool is_ground;
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
nsec last_moved;
|
|
|
|
nsec last_dropped;
|
|
|
|
};
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void shuffle(struct Fumotris *fumo)
|
2024-05-15 05:44:13 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
for (usize i = 6; i > 0; i--) {
|
2024-05-15 05:44:13 +00:00
|
|
|
usize swap = rand() % i;
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
struct TetraTemplate *tmp = fumo->bag[swap];
|
|
|
|
fumo->bag[swap] = fumo->bag[i];
|
|
|
|
fumo->bag[i] = tmp;
|
2024-05-15 05:44:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void check_clear()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void place(struct Fumotris *fumo)
|
2024-05-15 05:44:13 +00:00
|
|
|
{
|
|
|
|
TetraOverlay(&fumo->piece, &fumo->board);
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
usize lines_cleared = fumo->piece.hgt;
|
|
|
|
|
|
|
|
for (usize y = fumo->piece.y; y < fumo->piece.y + fumo->piece.hgt; y++) {
|
|
|
|
for (usize x = 0; x < fumo->board.wid; x++) {
|
|
|
|
if (fumo->board.blks[fumo->board.wid * y + x] == 0) {
|
|
|
|
lines_cleared -= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-05-15 05:44:13 +00:00
|
|
|
}
|
2024-05-15 22:10:47 +00:00
|
|
|
|
|
|
|
TetraSet(&fumo->piece, fumo->bag[fumo->bag_i++]);
|
|
|
|
|
|
|
|
if (fumo->bag_i == 7) {
|
|
|
|
shuffle(fumo);
|
|
|
|
fumo->bag_i = 0;
|
|
|
|
}
|
|
|
|
|
2024-05-15 05:44:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
i16 get_horizontal(struct Controller *ctrl)
|
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
return (-(i16)ctrl->axes[LEFT].is_held) + ctrl->axes[RIGHT].is_held;
|
2024-05-15 05:44:13 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void FumotrisStart(struct Instance *inst, struct Fumotris *fumo)
|
2024-05-02 22:17:37 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
ControllerBindMulti(&inst->ctrl, BINDS_N, CONTROLS, CODES, TYPES);
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
CreateTerminal(&fumo->term, 20, 20);
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
for (usize i = 0; i < 7; i++)
|
|
|
|
fumo->bag[i] = templates[i];
|
|
|
|
fumo->bag_i = 1;
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
CreateTetra(&fumo->board, 10, 20);
|
|
|
|
TetraSet(&fumo->piece, fumo->bag[0]);
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
fumo->is_ground = false;
|
|
|
|
fumo->last_moved = 0;
|
|
|
|
fumo->last_dropped = 0;
|
2024-05-07 22:10:15 +00:00
|
|
|
}
|
2024-05-07 03:29:10 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void FumotrisUpdate(struct Instance *inst, struct Fumotris *fumo)
|
2024-05-07 22:10:15 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
i16 horizontal = get_horizontal(&inst->ctrl);
|
2024-05-14 04:20:20 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
if (horizontal != 0 and fumo->last_moved < inst->time) {
|
|
|
|
fumo->last_moved = inst->time + 5e7;
|
|
|
|
TetraMove(&fumo->piece, &fumo->board, horizontal, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inst->ctrl.axes[ROTATE_CCW].is_down)
|
|
|
|
TetraRotate(&fumo->piece, &fumo->board, 1);
|
|
|
|
|
|
|
|
if (inst->ctrl.axes[ROTATE_CW].is_down)
|
|
|
|
TetraRotate(&fumo->piece, &fumo->board, -1);
|
|
|
|
|
|
|
|
if (inst->ctrl.axes[SOFT_DROP].is_held and fumo->last_dropped < inst->time) {
|
|
|
|
fumo->last_dropped = inst->time + 5e7;
|
2024-05-14 04:20:20 +00:00
|
|
|
TetraMove(&fumo->piece, &fumo->board, 0, 1);
|
2024-05-15 05:44:13 +00:00
|
|
|
}
|
2024-05-14 04:20:20 +00:00
|
|
|
|
|
|
|
if (inst->ctrl.axes[HARD_DROP].is_down) {
|
|
|
|
while (TetraMove(&fumo->piece, &fumo->board, 0, 1));
|
2024-05-15 22:10:47 +00:00
|
|
|
place(fumo);
|
2024-05-14 04:20:20 +00:00
|
|
|
}
|
2024-05-15 05:44:13 +00:00
|
|
|
}
|
2024-05-14 04:20:20 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
nsec FumotrisFall(struct Instance *inst, struct Fumotris *fumo)
|
2024-05-15 05:44:13 +00:00
|
|
|
{
|
|
|
|
if (!TetraMove(&fumo->piece, &fumo->board, 0, 1)) {
|
|
|
|
if (!fumo->is_ground)
|
|
|
|
fumo->is_ground = true;
|
|
|
|
else
|
2024-05-15 22:10:47 +00:00
|
|
|
place(fumo);
|
2024-05-14 04:20:20 +00:00
|
|
|
}
|
2024-05-15 22:10:47 +00:00
|
|
|
|
|
|
|
return 5e8;
|
2024-05-14 04:20:20 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void FumotrisDraw(struct Instance *inst, struct Fumotris *fumo)
|
2024-05-14 04:20:20 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
TetraTerminalClear(&fumo->board, &fumo->term);
|
|
|
|
TetraTerminalDraw(&fumo->board, &fumo->term);
|
|
|
|
TetraTerminalDraw(&fumo->piece, &fumo->term);
|
|
|
|
|
|
|
|
TerminalPrint(&fumo->term);
|
|
|
|
puts(fumo->term.str);
|
2024-05-02 22:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
struct Instance inst;
|
2024-05-08 12:47:46 +00:00
|
|
|
CreateFumoInstance(&inst);
|
2024-05-02 22:17:37 +00:00
|
|
|
|
2024-05-07 22:10:15 +00:00
|
|
|
struct Fumotris game;
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
EventAdd(&inst.on_start, &game, FumotrisStart);
|
|
|
|
EventAdd(&inst.on_update, &game, FumotrisUpdate);
|
|
|
|
EventAdd(&inst.on_draw, &game, FumotrisDraw);
|
2024-05-15 05:44:13 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
CoroutineAdd(&inst, &game, FumotrisFall);
|
2024-05-02 22:17:37 +00:00
|
|
|
|
2024-05-08 12:47:46 +00:00
|
|
|
FumoInstanceRun(&inst);
|
2024-05-02 22:17:37 +00:00
|
|
|
|
2024-05-07 22:10:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|