diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/draw.c | 202 | ||||
-rw-r--r-- | src/engine.c | 86 | ||||
-rw-r--r-- | src/field.c | 158 | ||||
-rw-r--r-- | src/idlist.c | 55 | ||||
-rw-r--r-- | src/main.c | 78 |
5 files changed, 282 insertions, 297 deletions
@@ -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); + } +} @@ -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); |