summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/draw.c202
-rw-r--r--src/engine.c86
-rw-r--r--src/field.c158
-rw-r--r--src/idlist.c55
-rw-r--r--src/main.c78
5 files changed, 282 insertions, 297 deletions
diff --git a/src/draw.c b/src/draw.c
index a8c776f..dd888d0 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -6,53 +6,30 @@
#include "field.h"
#include "draw.h"
-struct field_drawable {
- sfRectangleShape *p[FLD_BOUND_Y][FLD_SIZE_X];
-};
-
-struct idlist {
- unsigned long id;
- void *obj;
- struct idlist *next;
+#include "idlist.h"
+
+static sfColor shape_color_map[] = {
+ UIBGCOLOR,
+ LCOLOR,
+ RLCOLOR,
+ ZCOLOR,
+ SCOLOR,
+ BCOLOR,
+ ICOLOR,
+ TCOLOR,
};
-static struct idlist *list_new()
-{
- struct idlist *list = calloc(1, sizeof(struct idlist));
- list->id = 1;
- return list;
-}
-
-static struct idlist *list_append(struct idlist *list)
-{
- unsigned long id = list->id + 1;
- struct idlist *last = list;
- while (last->next)
- last = last->next;
- last->next = calloc(1, sizeof(struct idlist));
- last = last->next;
- last->id = id;
- return last;
-}
-
-static struct idlist *list_get(const struct idlist *list, unsigned long id)
-{
- const struct idlist *sought = list;
- if (sought) {
- if (sought->id == id)
- return (struct idlist *)sought;
- while (sought->next) {
- sought = sought->next;
- if (sought->id == id)
- return (struct idlist *)sought;
- }
- }
- return NULL;
-}
-#define BUFSIZE 100
+struct field_drawable {
+ sfRectangleShape ***p;
+ struct vector2ui size;
+ unsigned int attr;
+};
-/* Must be static in future */
+/*
+ * TODO: Must be static in future
+ *
+ * */
struct window w;
static struct idlist *fields_list = NULL;
@@ -64,29 +41,42 @@ void painter_init_window()
sfResize | sfClose, NULL);
if (!w.window)
exit(EXIT_FAILURE);
+ sfRenderWindow_setFramerateLimit(w.window, 60);
+}
+
+void painter_destroy_window()
+{
+ if (w.window) {
+ sfRenderWindow_destroy(w.window);
+ w.window = 0;
+ }
}
-unsigned long painter_register_field()
+unsigned long painter_register_field(struct field *fld)
{
struct idlist *last;
- if (!fields_list) {
+ if (!fields_list)
last = fields_list = list_new();
- } else
+ else
last = list_append(fields_list);
struct field_drawable *f = calloc(1, sizeof(struct field_drawable));
- for (int j = 0; j < FLD_SIZE_Y; j++)
- for (int i = 0; i < FLD_SIZE_X; i++) {
+ f->size = fld->size;
+ f->p = calloc(f->size.y, sizeof(sfRectangleShape **));
+ for (unsigned int j = 0; j < f->size.y; j++) {
+ f->p[j] = calloc(f->size.x, sizeof(sfRectangleShape *));
+ for (unsigned int i = 0; i < f->size.x; i++) {
f->p[j][i] = sfRectangleShape_create();
sfVector2f cell_pos;
- cell_pos.x = FLD_POS.x + (i * (CELL_SIZE.x + 2 * OUT_THICK));
- cell_pos.y = FLD_POS.y - (j * (CELL_SIZE.y + 2 * OUT_THICK));
- sfRectangleShape_setFillColor(f->p[j][i], UIBGCOLOR);
- sfRectangleShape_setSize(f->p[j][i], CELL_SIZE);
+ cell_pos.x = fld->pos.x + (i * (CELL_SIZE.x + 2 * OUT_THICK));
+ cell_pos.y = fld->pos.y - (j * (CELL_SIZE.y + 2 * OUT_THICK));
sfRectangleShape_setPosition(f->p[j][i], cell_pos);
- sfRectangleShape_setOutlineColor(f->p[j][i], UIFGACTIVECOLOR);
+ sfRectangleShape_setFillColor(f->p[j][i], (sfColor)UIBGCOLOR);
+ sfRectangleShape_setSize(f->p[j][i], CELL_SIZE);
+ sfRectangleShape_setOutlineColor(f->p[j][i], (sfColor)UIFGACTIVECOLOR);
sfRectangleShape_setOutlineThickness(f->p[j][i], OUT_THICK);
}
+ }
last->obj = f;
return last->id;
@@ -98,56 +88,74 @@ void painter_update_field(unsigned long id, struct field *fld)
if (!node)
return;
struct field_drawable *f = node->obj;
- for (int j = 0; j < fld->size.y; j++) {
- for (int i = 0; i < fld->size.x; i++) {
- switch (fld->c[j][i].color) {
- case 1 :
- sfRectangleShape_setFillColor(f->p[j][i], LCOLOR);
- break;
- case 2 :
- sfRectangleShape_setFillColor(f->p[j][i], RLCOLOR);
- break;
- case 3 :
- sfRectangleShape_setFillColor(f->p[j][i], ZCOLOR);
- break;
- case 4 :
- sfRectangleShape_setFillColor(f->p[j][i], SCOLOR);
- break;
- case 5 :
- sfRectangleShape_setFillColor(f->p[j][i], BCOLOR);
- break;
- case 6 :
- sfRectangleShape_setFillColor(f->p[j][i], ICOLOR);
- break;
- case 7 :
- sfRectangleShape_setFillColor(f->p[j][i], TCOLOR);
- break;
+ f->attr = fld->attr;
+ for (unsigned int j = 0; j < fld->size.y; j++) {
+ for (unsigned int i = 0; i < fld->size.x; i++) {
+ sfVector2f cell_pos;
+ cell_pos.x = fld->pos.x + (i * (CELL_SIZE.x + 2 * OUT_THICK));
+ cell_pos.y = fld->pos.y - (j * (CELL_SIZE.y + 2 * OUT_THICK));
+ sfRectangleShape_setPosition(f->p[j][i], cell_pos);
+ if (fld->c[j][i].a) {
+ sfRectangleShape_setFillColor(f->p[j][i], shape_color_map[fld->c[j][i].color]);
+ sfRectangleShape_setOutlineColor(f->p[j][i], (sfColor)UIFGACTIVECOLOR);
+ } else if (f->attr & FLD_ATTR_TRANSPARENT) {
+ sfRectangleShape_setFillColor(f->p[j][i], (sfColor)UITRANSPARENT);
+ sfRectangleShape_setOutlineColor(f->p[j][i], (sfColor)UITRANSPARENT);
+ } else {
+ sfRectangleShape_setFillColor(f->p[j][i], (sfColor)UIBGCOLOR);
+ sfRectangleShape_setOutlineColor(f->p[j][i], (sfColor)UIFGINACTIVECOLOR);
}
- sfRectangleShape_setOutlineColor(f->p[j][i], UIFGACTIVECOLOR);
}
}
+ for (unsigned int s = 0; s < fld->shape_cnt; ++s)
+ for (int j = 0; j < 4; j++)
+ for (int i = 0; i < 4; i++)
+ if (fld->shape[s].c[j][i] && j + fld->shape[s].y < (int)fld->size.y) {
+ sfRectangleShape_setFillColor(
+ f->p[j + fld->shape[s].y][i + fld->shape[s].x],
+ shape_color_map[fld->shape[s].color]);
+ sfRectangleShape_setOutlineColor(
+ f->p[j + fld->shape[s].y][i + fld->shape[s].x],
+ (sfColor)UIFGACTIVECOLOR);
+ }
}
-static void draw_field(struct field_drawable *f)
+static void draw_field(void *field)
{
- for (unsigned int j = 0; j < FLD_SIZE_Y; j++)
- for (unsigned int i = 0; i < FLD_SIZE_X; i++)
- sfRenderWindow_drawRectangleShape(w.window, f->p[j][i], NULL);
+ struct field_drawable *f = field;
+ if (!(f->attr & FLD_ATTR_INVISIBLE))
+ for (unsigned int j = 0; j < f->size.y; j++)
+ for (unsigned int i = 0; i < f->size.x; i++)
+ sfRenderWindow_drawRectangleShape(w.window, f->p[j][i], NULL);
}
static void draw_fields()
{
- struct idlist *node = fields_list;
- if (node) {
- if (node->obj)
- draw_field(node->obj);
- while (node->next) {
- node = node->next;
- if (node)
- if (node->obj)
- draw_field(node->obj);
- }
+ list_foreach(fields_list, draw_field);
+}
+
+static void destroy_field(void *field)
+{
+ struct field_drawable *f = field;
+ for (unsigned int j = 0; j < f->size.y; j++) {
+ for (unsigned int i = 0; i < f->size.x; i++)
+ sfRectangleShape_destroy(f->p[j][i]);
+ free(f->p[j]);
}
+ free(f->p);
+ free(f);
+}
+
+void painter_destroy_field(unsigned long id)
+{
+ struct idlist *node = list_get(fields_list, id);
+ destroy_field(node->obj);
+ list_rm_node(node);
+}
+
+void painter_destroy_fields()
+{
+ list_foreach(fields_list, destroy_field);
}
void painter_draw()
@@ -155,7 +163,13 @@ void painter_draw()
draw_fields();
}
-void painter_destroy_window()
+void painter_destroy_drawables()
+{
+ painter_destroy_fields();
+}
+
+void painter_destroy_all()
{
- sfRenderWindow_destroy(w.window);
+ painter_destroy_drawables();
+ painter_destroy_window();
}
diff --git a/src/engine.c b/src/engine.c
index 210257b..9840b34 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2,32 +2,23 @@
#include <stdlib.h>
#include <string.h>
#include <SFML/System/Clock.h>
+#include <SFML/Window/Keyboard.h>
#include <SFML/Graphics/RenderWindow.h>
#include <SFML/Graphics/Text.h>
-#include <SFML/Graphics/RectangleShape.h>
#include "common.h"
#include "tet_conf.h"
#include "text.h"
#include "field.h"
+#include "draw.h"
#include "engine.h"
/* Externs from main.c */
extern struct game game;
-extern struct shape active, next;
-extern struct field fld;
-
-extern sfFont *fontScore;
+extern struct field fld, nxt;
extern char arrKeys; // Arrow keys states byte container
-extern sfClock *gameTick;
-extern sfClock *putTick;
-extern sfClock *mTick;
-extern sfClock *repPushDown; // Clock for repeat latency when Down key held
-extern sfClock *repKeyLeft; // Clock for repeat latency when Left key held
-extern sfClock *repKeyRight; // Clock for repeat latency when Left key held
-
void valueAfterTextDisplay(int value, List *texts, char *type)
{
List *l = texts;
@@ -59,7 +50,7 @@ void checkLevelUp(struct game *game)
}
}
-int getMoveLatencyOfLevel(int level)
+int getMoveLatencyOfLevel(unsigned int level)
{
if (level >= 29)
return L29LATENCY;
@@ -103,18 +94,22 @@ void tTick()
{ // If tick exceeds current level tick latency
if (sfClock_getElapsedTime(game.gameTick).microseconds >= game.moveLatency) {
sfClock_restart(game.gameTick);
- active.y--; // try
- if (collide(&fld, &active))
- active.y++; // fallback
+ fld.shape[0].y--; // try
+ if (field_shape_collision(&fld, &fld.shape[0]))
+ fld.shape[0].y++; // fallback
else
sfClock_restart(game.putTick);
if (sfClock_getElapsedTime(game.putTick).microseconds >= PUT_LATENCY) {
- if (out_of_field(&fld, &active)) {
+ if (field_shape_out_of_bounds(&fld, &fld.shape[0])) {
gameover(&game);
+ fld.shape[0].y = fld.size.y;
+ field_fill_random(&fld);
+ nxt.attr |= FLD_ATTR_INVISIBLE;
+ painter_update_field(nxt.id, &nxt);
return;
} else {
- putShape(&fld, &active);
- int removedLines = rm_lines(&fld);
+ field_put_shape(&fld, &fld.shape[0]);
+ int removedLines = field_rm_lines(&fld);
game.lines += removedLines;
switch (removedLines) {
case 1:
@@ -130,9 +125,13 @@ void tTick()
game.scoreCurrent += RM_4LINES_SCORE * game.level;
break;
}
- active.t = next.t;
- resetActiveShape(&fld, &active);
- gen_shape(&next);
+ fld.shape[0].t = nxt.shape[0].t;
+ field_reset_walking_shape(&fld, 0);
+ for (unsigned int s = 0; s < nxt.shape_cnt - 1; ++s) {
+ nxt.shape[s] = nxt.shape[s + 1];
+ nxt.shape[s].y = 4 - s * 3;
+ }
+ shape_gen_random(&nxt.shape[nxt.shape_cnt - 1]);
checkLevelUp(&game);
}
sfClock_restart(game.putTick);
@@ -150,7 +149,7 @@ void tKeyCtrl()
if (sfKeyboard_isKeyPressed(sfKeyUp)) {
if (!(arrKeys & UP)) {
arrKeys = arrKeys | UP;
- rotate_shape(&fld, &active);
+ field_rotate_shape(&fld, 0);
}
} else {
if ((arrKeys & UP)) {
@@ -162,9 +161,9 @@ void tKeyCtrl()
if (sfKeyboard_isKeyPressed(sfKeyDown)) {
if (!(arrKeys & DOWN)) {
arrKeys = arrKeys | DOWN;
- active.y--;
- if (collide(&fld, &active))
- active.y++;
+ fld.shape[0].y--;
+ if (field_shape_collision(&fld, &fld.shape[0]))
+ fld.shape[0].y++;
else {
// Avoid excess move down by gameTick
sfClock_restart(game.putTick);
@@ -188,9 +187,9 @@ void tKeyCtrl()
&& !sfKeyboard_isKeyPressed(sfKeyRight)) {
if (!(arrKeys & LEFT)) {
arrKeys = arrKeys | LEFT;
- active.x--;
- if (collide(&fld, &active))
- active.x++;
+ fld.shape[0].x--;
+ if (field_shape_collision(&fld, &fld.shape[0]))
+ fld.shape[0].x++;
else
sfClock_restart(game.putTick);
sfClock_restart(game.repKeyLeft);
@@ -219,9 +218,9 @@ void tKeyCtrl()
&& !sfKeyboard_isKeyPressed(sfKeyLeft)) {
if (!(arrKeys & RIGHT)) {
arrKeys = arrKeys | RIGHT;
- active.x++;
- if (collide(&fld, &active))
- active.x--;
+ fld.shape[0].x++;
+ if (field_shape_collision(&fld, &fld.shape[0]))
+ fld.shape[0].x--;
else
sfClock_restart(game.putTick);
sfClock_restart(game.repKeyRight);
@@ -246,17 +245,6 @@ void tKeyCtrl()
}
}
-/*
- * Draw all fld cells
- *
- */
-void drawFld(sfRenderWindow *window, struct field *fld)
-{
- for (int j = 0; j < fld->size.y; j++)
- for (int i = 0; i < fld->size.x; i++)
- sfRenderWindow_drawRectangleShape(window, fld->p[j][i], NULL);
-}
-
void gameover(struct game *game)
{
game->isStarted = 0;
@@ -265,15 +253,3 @@ void gameover(struct game *game)
game->moveLatency = L00LATENCY;
game->lines = 0;
}
-
-void drawNextShape(sfRenderWindow *window)
-{
- for (int j = 0; j < 4; j++)
- for (int i = 0; i < 4; i++)
- if (next.c[j][i]) {
- sfRectangleShape_setFillColor(next.p[j][i], next.fColor);
- sfRectangleShape_setOutlineColor(next.p[j][i], UIFGACTIVECOLOR);
- sfRenderWindow_drawRectangleShape(window, next.p[j][i], NULL);
- }
-}
-
diff --git a/src/field.c b/src/field.c
index c0e3fe5..37680ae 100644
--- a/src/field.c
+++ b/src/field.c
@@ -5,7 +5,6 @@
#include "field.h"
#include "tet_conf.h"
-/* Shapes maps */
extern char arrShapeL[4][4];
extern char arrShapeRL[4][4];
extern char arrShapeZ[4][4];
@@ -18,161 +17,112 @@ static void rotate_shape_left(struct shape *shape);
static void rotate_shape_right(struct shape *shape);
static int out_of_bounds(struct field *fld, struct shape *active);
-void init_field(struct field *fld)
+void field_init(struct field *fld)
{
- sfVector2f fldCPos[22][10];
- for (int j = 0; j < fld->size.y; j++) {
- for (int i = 0; i < fld->size.x; i++) {
- fld->c[j][i].a = 0; // Inactive = empty
- fldCPos[j][i].x
- = fld->pos.x + (i * (fld->cSize.x + 2 * fld->cOutThick));
- fldCPos[j][i].y
- = fld->pos.y - (j * (fld->cSize.y + 2 * fld->cOutThick));
- fld->p[j][i] = sfRectangleShape_create();
- sfRectangleShape_setFillColor(fld->p[j][i], UIBGCOLOR);
- sfRectangleShape_setSize(fld->p[j][i], fld->cSize);
- sfRectangleShape_setPosition(fld->p[j][i], fldCPos[j][i]);
- sfRectangleShape_setOutlineColor(fld->p[j][i], UIFGACTIVECOLOR);
- sfRectangleShape_setOutlineThickness(fld->p[j][i], fld->cOutThick);
- }
+ fld->c = calloc(fld->bound.y, sizeof(struct cell *));
+ for (unsigned int j = 0; j < fld->bound.y; j++) {
+ fld->c[j] = calloc(fld->bound.x, sizeof(struct cell));
+ for (unsigned int i = 0; i < fld->size.x; i++)
+ fld->c[j][i].a = 0;
}
+ fld->shape = calloc(fld->shape_cnt, sizeof(struct shape));
}
-void colorize_field(struct field *fld)
+void field_clear(struct field *fld)
{
- for (int j = 0; j < fld->size.y; j++)
- for (int i = 0; i < fld->size.x; i++)
- if (fld->c[j][i].a) {
- sfRectangleShape_setFillColor(fld->p[j][i], fld->c[j][i].fColor);
- sfRectangleShape_setOutlineColor(fld->p[j][i], UIFGACTIVECOLOR);
- } else {
- sfRectangleShape_setFillColor(fld->p[j][i], UIBGCOLOR);
- sfRectangleShape_setOutlineColor(fld->p[j][i], UIFGINACTIVECOLOR);
- }
+ for (unsigned int j = 0; j < fld->bound.y; j++)
+ for (unsigned int i = 0; i < fld->bound.x; i++) {
+ fld->c[j][i].a = 0;
+ fld->c[j][i].color = 0;
+ }
}
-void colorize_field_random(struct field *fld)
+void field_fill_random(struct field *fld)
{
- for (int j = 0; j < fld->size.y; j++)
- for (int i = 0; i < fld->size.x; i++)
+ for (unsigned int j = 0; j < fld->size.y; j++)
+ for (unsigned int i = 0; i < fld->size.x; i++) {
+ fld->c[j][i].a = 1;
fld->c[j][i].color = rand() % 7 + 1;
-}
-
-void colorize_active_shape(struct field *fld, struct shape *shape)
-{
- for (int j = 0; j < 4; j++)
- for (int i = 0; i < 4; i++)
- if (shape->c[j][i] && j + shape->y < FLD_SIZE_Y) {
- sfRectangleShape_setFillColor(
- fld->p[j + shape->y][i + shape->x], shape->fColor);
- sfRectangleShape_setOutlineColor(
- fld->p[j + shape->y][i + shape->x], UIFGACTIVECOLOR);
- }
-}
-
-void init_next_shape(struct shape *next)
-{
- sfVector2f nsPos;
- for (int j = 0; j < 4; j++) {
- for (int i = 0; i < 4; i++) {
- nsPos.x = next->x + i *(next->cSize.x + 2 * next->cOutThick);
- nsPos.y = next->y - j *(next->cSize.y + 2 * next->cOutThick);
- next->p[j][i] = sfRectangleShape_create();
- sfRectangleShape_setSize(next->p[j][i], next->cSize);
- sfRectangleShape_setPosition(next->p[j][i], nsPos);
- sfRectangleShape_setOutlineThickness(next->p[j][i], next->cOutThick);
}
- }
}
-/*
- * Inserts shape into field, runs filled lines searching, puts new shape
- * into the game at the top.
- *
- */
-void putShape(struct field *fld, struct shape *active)
+void field_put_shape(struct field *fld, struct shape *active)
{
for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++)
if (active->c[j][i]) {
fld->c[j+active->y][i+active->x].a = active->c[j][i];
- fld->c[j+active->y][i+active->x].fColor = active->fColor;
+ fld->c[j+active->y][i+active->x].color = active->color;
}
}
-int out_of_field(struct field *fld, struct shape *active)
+int field_shape_out_of_bounds(struct field *fld, struct shape *active)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
- if (active->c[i][j] && active->y + i >= fld->size.y)
+ if (active->c[i][j] && active->y + i >= (int)fld->size.y)
return 1;
return 0;
}
-void load_shape(struct shape *shape)
+void shape_load(struct shape *shape)
{
+ shape->color = shape->t;
switch (shape->t) { // Copy cell active/inactive state
case 1 :
memcpy(&shape->c[0][0], &arrShapeL[0][0], sizeof(char)*4*4);
- shape->fColor = LCOLOR;
break;
case 2 :
memcpy(&shape->c[0][0], &arrShapeRL[0][0], sizeof(char)*4*4);
- shape->fColor = RLCOLOR;
break;
case 3 :
memcpy(&shape->c[0][0], &arrShapeZ[0][0], sizeof(char)*4*4);
- shape->fColor = ZCOLOR;
break;
case 4 :
memcpy(&shape->c[0][0], &arrShapeS[0][0], sizeof(char)*4*4);
- shape->fColor = SCOLOR;
break;
case 5 :
memcpy(&shape->c[0][0], &arrShapeB[0][0], sizeof(char)*4*4);
- shape->fColor = BCOLOR;
break;
case 6 :
memcpy(&shape->c[0][0], &arrShapeI[0][0], sizeof(char)*4*4);
- shape->fColor = ICOLOR;
break;
case 7 :
memcpy(&shape->c[0][0], &arrShapeT[0][0], sizeof(char)*4*4);
- shape->fColor = TCOLOR;
break;
}
}
-void resetActiveShape(struct field *fld, struct shape *active)
+void field_reset_walking_shape(struct field *fld, unsigned int index)
{
- load_shape(active);
+ struct shape *active = &fld->shape[index];
+ shape_load(active);
active->x = 3;
if (active->t == 6)
active->y = 19;
else
active->y = 18;
- while (collide(fld, active)) {
+ while (field_shape_collision(fld, active))
active->y++;
- }
}
-void gen_shape(struct shape *shape)
+void shape_gen_random(struct shape *shape)
{
shape->t = (rand() % 7) + 1; // Insert new random shape of 7 variants
- load_shape(shape);
+ shape_load(shape);
if (shape->t == 5)
for (int j = 0; j < 3; j++)
for (int i = 0; i < 4; i++)
shape->c[i][j] = shape->c[i][j+1];
}
-int collide(struct field *fld, struct shape *active)
+int field_shape_collision(struct field *fld, struct shape *shape)
{
- if (out_of_bounds(fld, active))
+ if (out_of_bounds(fld, shape))
return 1;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
- if (active->c[i][j] && fld->c[i + active->y][j + active->x].a)
+ if (shape->c[i][j] && fld->c[i + shape->y][j + shape->x].a)
return 1;
return 0;
}
@@ -182,8 +132,8 @@ static int out_of_bounds(struct field *fld, struct shape *active)
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
if (active->c[i][j])
- if (active->x + j >= fld->bound.x || active->x + j < 0
- || active->y + i >= fld->bound.y || active->y + i < 0)
+ if (active->x + j >= (int)fld->bound.x || active->x + j < 0
+ || active->y + i >= (int)fld->bound.y || active->y + i < 0)
return 1;
return 0;
}
@@ -222,27 +172,28 @@ static void rotate_shape_right(struct shape *shape)
shape->c[j][i] = arr[i+1][3-j];
}
-void rotate_shape(struct field *fld, struct shape *shape)
+void field_rotate_shape(struct field *fld, unsigned int index)
{
+ struct shape *shape = &fld->shape[index];
rotate_shape_right(shape);
- if (collide(fld, shape))
+ if (field_shape_collision(fld, shape))
rotate_shape_left(shape);
}
-int rm_lines(struct field *fld)
+int field_rm_lines(struct field *fld)
{
- int lines = 0;
- for (int j = 0; j < FLD_SIZE_Y; j++) {
- int cells = 0;
- for (int i = 0; i < FLD_SIZE_X; i++)
+ unsigned int lines = 0;
+ for (unsigned int j = 0; j < fld->bound.y; j++) {
+ unsigned int cells = 0;
+ for (unsigned int i = 0; i < fld->bound.x; i++)
if (fld->c[j][i].a)
++cells;
- if (cells == FLD_SIZE_X) {
+ if (cells == fld->bound.x) {
++lines;
- for (int n = j; n < FLD_SIZE_Y; n++)
- for (int m = 0; m < 10; m++) {
- fld->c[n][m].a = fld->c[n+1][m].a;
- fld->c[n][m].fColor = fld->c[n+1][m].fColor;
+ for (unsigned int n = j; n < fld->bound.y - 1; n++)
+ for (unsigned int m = 0; m < fld->bound.x; m++) {
+ fld->c[n][m].a = fld->c[n + 1][m].a;
+ fld->c[n][m].color = fld->c[n + 1][m].color;
}
--j;
}
@@ -250,14 +201,9 @@ int rm_lines(struct field *fld)
return lines;
}
-void free_field(struct field *fld) {
- for (int j = 0; j < fld->size.y; j++)
- for (int i = 0; i < fld->size.x; i++)
- sfRectangleShape_destroy(fld->p[j][i]);
-}
-
-void free_shape(struct shape *shape) {
- for (int j = 0; j < 4; j++)
- for (int i = 0; i < 4; i++)
- sfRectangleShape_destroy(shape->p[j][i]);
+void field_deinit(struct field *fld) {
+ for (int j = 0; j < (int)fld->bound.y; j++)
+ free(fld->c[j]);
+ free(fld->c);
+ free(fld->shape);
}
diff --git a/src/idlist.c b/src/idlist.c
new file mode 100644
index 0000000..5b4d99b
--- /dev/null
+++ b/src/idlist.c
@@ -0,0 +1,55 @@
+#include <stdlib.h>
+#include "idlist.h"
+
+struct idlist *list_new()
+{
+ struct idlist *list = calloc(1, sizeof(struct idlist));
+ list->id = 1;
+ return list;
+}
+
+struct idlist *list_append(struct idlist *list)
+{
+ if (!list)
+ return list;
+ struct idlist *last = list;
+ while (last->next)
+ last = last->next;
+ last->next = calloc(1, sizeof(struct idlist));
+ last->next->id = last->id + 1;
+ last->next->prev = last;
+ return last->next;
+}
+
+struct idlist *list_get(const struct idlist *list, unsigned long id)
+{
+ const struct idlist *sought = list;
+ if (sought) {
+ if (sought->id == id)
+ return (struct idlist *)sought;
+ while ((sought = sought->next))
+ if (sought->id == id)
+ return (struct idlist *)sought;
+ }
+ return NULL;
+}
+
+void list_rm_node(struct idlist *node)
+{
+ if (node) {
+ if (node->prev)
+ node->prev->next = node->next;
+ if (node->next)
+ node->next->prev = node->prev;
+ free(node);
+ }
+}
+
+void list_foreach(struct idlist *list, void (*job)(void *))
+{
+ if (list) {
+ job(list->obj);
+ while ((list = list->next))
+ job(list->obj);
+ }
+}
diff --git a/src/main.c b/src/main.c
index 4386205..aa27332 100644
--- a/src/main.c
+++ b/src/main.c
@@ -18,8 +18,7 @@ extern struct window w;
List *texts;
sfFont *fontScore;
-struct shape active, next;
-struct field fld;
+struct field fld, nxt;
struct game game = {
.isStarted = 0,
.scoreCurrent = 0,
@@ -31,31 +30,6 @@ struct game game = {
char arrKeys = 0; // Arrow keys states byte container
void prepare() {
- sfRenderWindow_setFramerateLimit(w.window, 60);
-
- /*
- * Dimensions of every fld's cell
- * 23px - fill color 1px - for outline, 25 - at all
- */
- fld.cSize = CELL_SIZE; //Fld's cell size in pixels
- fld.cOutThick = 1;
- fld.pos = FLD_POS; // Fld bot left corner
- fld.size = (sfVector2i){.x = FLD_SIZE_X, .y = FLD_SIZE_Y}; // Field's size in blocks
- fld.bound = (sfVector2i){.x = FLD_BOUND_X, .y = FLD_BOUND_Y}; // Field's bound in blocks
-
- next = (struct shape){
- .x = 250 + 10 + 20,
- .y = 200,
- .cOutThick = 1,
- .cSize = {.x = 23, .y = 23}
- };
-
- init_field(&fld);
- init_next_shape(&next);
- gen_shape(&next);
- active.t = next.t;
- resetActiveShape(&fld, &active);
- gen_shape(&next);
}
void handleWindowEvents() {
@@ -78,18 +52,17 @@ void gameLoop() {
tKeyCtrl();
valueAfterTextDisplay(game.scoreCurrent, texts, "score");
valueAfterTextDisplay(game.level, texts, "level");
- colorize_field(&fld);
- colorize_active_shape(&fld, &active);
- drawFld(w.window, &fld);
- drawNextShape(w.window);
+ painter_update_field(fld.id, &fld);
+ painter_update_field(nxt.id, &nxt);
drawTextsAtScene(texts, "game", w.window);
+ painter_draw();
}
void menuTick()
{
if (sfClock_getElapsedTime(game.mTick).microseconds >= basicLatency) {
sfClock_restart(game.mTick);
- colorize_field_random(&fld);
+ field_fill_random(&fld);
painter_update_field(fld.id, &fld);
}
}
@@ -99,10 +72,12 @@ void menuLoop() {
drawTextsAtScene(texts, "menu", w.window);
if (sfKeyboard_isKeyPressed(sfKeyS) == 1) {
game.isStarted = 1;
- free_field(&fld);
- free_shape(&next);
- init_field(&fld);
- init_next_shape(&next);
+ field_clear(&fld);
+ shape_gen_random(&fld.shape[0]);
+ field_reset_walking_shape(&fld, 0);
+ for (unsigned int i = 0; i < nxt.shape_cnt; ++i)
+ shape_gen_random(&nxt.shape[i]);
+ nxt.attr &= ~FLD_ATTR_INVISIBLE;
sfClock_restart(game.gameTick);
}
painter_draw();
@@ -111,7 +86,7 @@ void menuLoop() {
void mainLoop() {
while (sfRenderWindow_isOpen(w.window)) {
handleWindowEvents();
- sfRenderWindow_clear(w.window, UIBGCOLOR);
+ sfRenderWindow_clear(w.window, (sfColor)UIBGCOLOR);
if (game.isStarted)
gameLoop();
else
@@ -139,13 +114,32 @@ int main()
texts = ListOfText_getFromListOfKeyMapOfString(tmp);
ListOfKeyMapOfString_free(&tmp);
- prepare();
- colorize_field_random(&fld);
- fld.id = painter_register_field();
+ fld.pos = FLD_POS;
+ fld.size = (struct vector2ui){.x = FLD_SIZE_X, .y = FLD_SIZE_Y};
+ fld.bound = (struct vector2ui){.x = FLD_BOUND_X, .y = FLD_BOUND_Y};
+ fld.shape_cnt = 1;
+ field_init(&fld);
+
+ nxt.pos = NXT_POS;
+ nxt.size = NXT_SIZE;
+ nxt.bound = NXT_SIZE;
+ nxt.shape_cnt = 3;
+ nxt.attr |= FLD_ATTR_TRANSPARENT | FLD_ATTR_INVISIBLE;
+ field_init(&nxt);
+ nxt.shape[0].y = 4;
+ nxt.shape[1].y = 1;
+ nxt.shape[2].y = -2;
+
+ fld.id = painter_register_field(&fld);
+ nxt.id = painter_register_field(&nxt);
+ field_fill_random(&fld);
painter_update_field(fld.id, &fld);
+ painter_update_field(nxt.id, &nxt);
+
mainLoop();
- free_field(&fld);
- free_shape(&next);
+ painter_destroy_drawables();
+ field_deinit(&fld);
+ field_deinit(&nxt);
painter_destroy_window();
sfFont_destroy(fontScore);