From ed8127a72e1a2d2703372d5b5dfa8d96703ec3bb Mon Sep 17 00:00:00 2001 From: Oxore Date: Tue, 3 Jul 2018 15:11:54 +0300 Subject: Refactor field, refactor next shape drawing Refactor field functions names. Transfer next shape drawing to painter. Introduce idlist struct with foreach function. Refactor config. Introduce color map array instead of "switch case" statement bloating while coloring rectangles. Decouple field and shape structs from SFML sfVector2 structs by introducing own vector2i and vector2ui structs. Also remove sfRectangleShape members form field an shape structs. --- src/draw.c | 202 ++++++++++++++++++++++++++++++++--------------------------- src/engine.c | 86 +++++++++---------------- src/field.c | 158 +++++++++++++++------------------------------- src/idlist.c | 55 ++++++++++++++++ src/main.c | 78 +++++++++++------------ 5 files changed, 282 insertions(+), 297 deletions(-) create mode 100644 src/idlist.c (limited to 'src') 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 #include #include +#include #include #include -#include #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 +#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); -- cgit v1.2.3