diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/draw.c | 161 | ||||
-rw-r--r-- | src/engine.c | 42 | ||||
-rw-r--r-- | src/field.c | 33 | ||||
-rw-r--r-- | src/main.c | 76 |
4 files changed, 225 insertions, 87 deletions
diff --git a/src/draw.c b/src/draw.c new file mode 100644 index 0000000..a8c776f --- /dev/null +++ b/src/draw.c @@ -0,0 +1,161 @@ +#include <SFML/Graphics/RenderWindow.h> +#include <SFML/Graphics/RectangleShape.h> +#include <stdlib.h> + +#include "tet_conf.h" +#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; +}; + +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 + +/* Must be static in future */ +struct window w; + +static struct idlist *fields_list = NULL; + +void painter_init_window() +{ + w = (struct window){.mode = {450, 570, 32}}; + w.window = sfRenderWindow_create(w.mode, windowName_conf, + sfResize | sfClose, NULL); + if (!w.window) + exit(EXIT_FAILURE); +} + +unsigned long painter_register_field() +{ + struct idlist *last; + if (!fields_list) { + last = fields_list = list_new(); + } 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->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); + sfRectangleShape_setPosition(f->p[j][i], cell_pos); + sfRectangleShape_setOutlineColor(f->p[j][i], UIFGACTIVECOLOR); + sfRectangleShape_setOutlineThickness(f->p[j][i], OUT_THICK); + } + + last->obj = f; + return last->id; +} + +void painter_update_field(unsigned long id, struct field *fld) +{ + struct idlist *node = list_get(fields_list, id); + 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; + } + sfRectangleShape_setOutlineColor(f->p[j][i], UIFGACTIVECOLOR); + } + } +} + +static void draw_field(struct field_drawable *f) +{ + 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); +} + +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); + } + } +} + +void painter_draw() +{ + draw_fields(); +} + +void painter_destroy_window() +{ + sfRenderWindow_destroy(w.window); +} diff --git a/src/engine.c b/src/engine.c index b5e1bac..210257b 100644 --- a/src/engine.c +++ b/src/engine.c @@ -101,14 +101,14 @@ int getMoveLatencyOfLevel(int level) */ void tTick() { // If tick exceeds current level tick latency - if (sfClock_getElapsedTime(gameTick).microseconds >= game.moveLatency) { - sfClock_restart(gameTick); + if (sfClock_getElapsedTime(game.gameTick).microseconds >= game.moveLatency) { + sfClock_restart(game.gameTick); active.y--; // try if (collide(&fld, &active)) active.y++; // fallback else - sfClock_restart(putTick); - if (sfClock_getElapsedTime(putTick).microseconds >= PUT_LATENCY) { + sfClock_restart(game.putTick); + if (sfClock_getElapsedTime(game.putTick).microseconds >= PUT_LATENCY) { if (out_of_field(&fld, &active)) { gameover(&game); return; @@ -135,7 +135,7 @@ void tTick() gen_shape(&next); checkLevelUp(&game); } - sfClock_restart(putTick); + sfClock_restart(game.putTick); } } } @@ -167,13 +167,13 @@ void tKeyCtrl() active.y++; else { // Avoid excess move down by gameTick - sfClock_restart(putTick); - sfClock_restart(gameTick); + sfClock_restart(game.putTick); + sfClock_restart(game.gameTick); game.scoreCurrent++; } - sfClock_restart(repPushDown); + sfClock_restart(game.repPushDown); } else { - if (sfClock_getElapsedTime(repPushDown).microseconds + if (sfClock_getElapsedTime(game.repPushDown).microseconds >= moveRepeatLatency2) arrKeys = arrKeys & ~DOWN; } @@ -192,17 +192,17 @@ void tKeyCtrl() if (collide(&fld, &active)) active.x++; else - sfClock_restart(putTick); - sfClock_restart(repKeyLeft); + sfClock_restart(game.putTick); + sfClock_restart(game.repKeyLeft); } else { if (!(arrKeys & LEFTHOLD)) { - if (sfClock_getElapsedTime(repKeyLeft).microseconds + if (sfClock_getElapsedTime(game.repKeyLeft).microseconds >= moveRepeatLatency1) { arrKeys = arrKeys | LEFTHOLD; arrKeys = arrKeys & ~LEFT; } } else { - if (sfClock_getElapsedTime(repKeyLeft).microseconds + if (sfClock_getElapsedTime(game.repKeyLeft).microseconds >= moveRepeatLatency2) arrKeys = arrKeys & ~LEFT; } @@ -223,17 +223,17 @@ void tKeyCtrl() if (collide(&fld, &active)) active.x--; else - sfClock_restart(putTick); - sfClock_restart(repKeyRight); + sfClock_restart(game.putTick); + sfClock_restart(game.repKeyRight); } else { if (!(arrKeys & RIGHTHOLD)) { - if (sfClock_getElapsedTime(repKeyRight).microseconds + if (sfClock_getElapsedTime(game.repKeyRight).microseconds >= moveRepeatLatency1) { arrKeys = arrKeys | RIGHTHOLD; arrKeys = arrKeys & ~RIGHT; } } else if (!sfKeyboard_isKeyPressed(sfKeyLeft)) { - if (sfClock_getElapsedTime(repKeyRight).microseconds + if (sfClock_getElapsedTime(game.repKeyRight).microseconds >= moveRepeatLatency2) // Wait short time arrKeys = arrKeys & ~RIGHT; } @@ -250,11 +250,11 @@ void tKeyCtrl() * Draw all fld cells * */ -void drawFld(sfRenderWindow *window) +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); + 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) diff --git a/src/field.c b/src/field.c index 89abd02..c0e3fe5 100644 --- a/src/field.c +++ b/src/field.c @@ -53,36 +53,9 @@ void colorize_field(struct field *fld) void colorize_field_random(struct field *fld) { - int a; - for (int j = 0; j < fld->size.y; j++) { - for (int i = 0; i < fld->size.x; i++) { - a = rand() % 7 + 1; - switch (a) { - case 1 : - sfRectangleShape_setFillColor(fld->p[j][i], LCOLOR); - break; - case 2 : - sfRectangleShape_setFillColor(fld->p[j][i], RLCOLOR); - break; - case 3 : - sfRectangleShape_setFillColor(fld->p[j][i], ZCOLOR); - break; - case 4 : - sfRectangleShape_setFillColor(fld->p[j][i], SCOLOR); - break; - case 5 : - sfRectangleShape_setFillColor(fld->p[j][i], BCOLOR); - break; - case 6 : - sfRectangleShape_setFillColor(fld->p[j][i], ICOLOR); - break; - case 7 : - sfRectangleShape_setFillColor(fld->p[j][i], TCOLOR); - break; - } - sfRectangleShape_setOutlineColor(fld->p[j][i], UIFGACTIVECOLOR); - } - } + for (int j = 0; j < fld->size.y; j++) + for (int i = 0; i < fld->size.x; i++) + fld->c[j][i].color = rand() % 7 + 1; } void colorize_active_shape(struct field *fld, struct shape *shape) @@ -10,14 +10,16 @@ #include "common.h" #include "text.h" #include "field.h" +#include "draw.h" #include "engine.h" #include "tet_conf.h" +extern struct window w; + List *texts; sfFont *fontScore; struct shape active, next; struct field fld; -struct window w = {.mode = {450, 570, 32}}; struct game game = { .isStarted = 0, .scoreCurrent = 0, @@ -28,34 +30,16 @@ struct game game = { char arrKeys = 0; // Arrow keys states byte container -sfClock *gameTick; -sfClock *putTick; -sfClock *mTick; -sfClock *repPushDown; // Clock for repeat latency when Down arrow long push -sfClock *repKeyLeft; // Clock for repeat latency when Left arrow long push -sfClock *repKeyRight; // Clock for repeat latency when Left arrow long push - void prepare() { - srand(time(NULL)); - gameTick = sfClock_create(); - putTick = sfClock_create(); - mTick = sfClock_create(); - repPushDown = sfClock_create(); - repKeyLeft = sfClock_create(); - repKeyRight = sfClock_create(); - fontScore = sfFont_createFromFile("dat/arial.ttf"); - if (!fontScore) { - printf("dat/arial.ttf font load failed"); - exit(-1); - } + sfRenderWindow_setFramerateLimit(w.window, 60); /* * Dimensions of every fld's cell * 23px - fill color 1px - for outline, 25 - at all */ - fld.cSize = (sfVector2f){.x = 23, .y = 23}; //Fld's cell size in pixels + fld.cSize = CELL_SIZE; //Fld's cell size in pixels fld.cOutThick = 1; - fld.pos = (sfVector2i){.x = 10, .y = 10+550-24}; // Fld bot left corner + 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 @@ -72,14 +56,6 @@ void prepare() { active.t = next.t; resetActiveShape(&fld, &active); gen_shape(&next); - List *tmp = ListOfKeyMapOfString_getFromYaml("dat/texts.yaml"); - texts = ListOfText_getFromListOfKeyMapOfString(tmp); - ListOfKeyMapOfString_free(&tmp); - w.window = sfRenderWindow_create(w.mode, windowName_conf, - sfResize | sfClose, NULL); - if (!w.window) - exit(EXIT_FAILURE); - sfRenderWindow_setFramerateLimit(w.window, 60); } void handleWindowEvents() { @@ -104,22 +80,22 @@ void gameLoop() { valueAfterTextDisplay(game.level, texts, "level"); colorize_field(&fld); colorize_active_shape(&fld, &active); - drawFld(w.window); + drawFld(w.window, &fld); drawNextShape(w.window); drawTextsAtScene(texts, "game", w.window); } void menuTick() { - if (sfClock_getElapsedTime(mTick).microseconds >= basicLatency) { - sfClock_restart(mTick); + if (sfClock_getElapsedTime(game.mTick).microseconds >= basicLatency) { + sfClock_restart(game.mTick); colorize_field_random(&fld); + painter_update_field(fld.id, &fld); } } void menuLoop() { menuTick(); - drawFld(w.window); drawTextsAtScene(texts, "menu", w.window); if (sfKeyboard_isKeyPressed(sfKeyS) == 1) { game.isStarted = 1; @@ -127,8 +103,9 @@ void menuLoop() { free_shape(&next); init_field(&fld); init_next_shape(&next); - sfClock_restart(gameTick); + sfClock_restart(game.gameTick); } + painter_draw(); } void mainLoop() { @@ -145,12 +122,39 @@ void mainLoop() { int main() { + srand(time(NULL)); + game.gameTick = sfClock_create(); + game.putTick = sfClock_create(); + game.mTick = sfClock_create(); + game.repPushDown = sfClock_create(); + game.repKeyLeft = sfClock_create(); + game.repKeyRight = sfClock_create(); + fontScore = sfFont_createFromFile("dat/arial.ttf"); + if (!fontScore) { + printf("dat/arial.ttf font load failed"); + exit(-1); + } + painter_init_window(); + List *tmp = ListOfKeyMapOfString_getFromYaml("dat/texts.yaml"); + texts = ListOfText_getFromListOfKeyMapOfString(tmp); + ListOfKeyMapOfString_free(&tmp); + prepare(); colorize_field_random(&fld); + fld.id = painter_register_field(); + painter_update_field(fld.id, &fld); mainLoop(); free_field(&fld); free_shape(&next); - sfRenderWindow_destroy(w.window); + + painter_destroy_window(); + sfFont_destroy(fontScore); + sfClock_destroy(game.gameTick); + sfClock_destroy(game.putTick); + sfClock_destroy(game.mTick); + sfClock_destroy(game.repPushDown); + sfClock_destroy(game.repKeyLeft); + sfClock_destroy(game.repKeyRight); ListOfText_free(&texts); return EXIT_SUCCESS; } |