diff options
-rw-r--r-- | .clang | 0 | ||||
-rw-r--r-- | LICENSE.md | 2 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | include/common.h | 77 | ||||
-rw-r--r-- | include/engine.h | 19 | ||||
-rw-r--r-- | include/field.h | 58 | ||||
-rw-r--r-- | include/functions.h | 34 | ||||
-rw-r--r-- | include/text.h | 48 | ||||
-rw-r--r-- | src/engine.c | 367 | ||||
-rw-r--r-- | src/field.c | 235 | ||||
-rw-r--r-- | src/functions.c | 678 | ||||
-rw-r--r-- | src/main.c | 61 | ||||
-rw-r--r-- | src/text.c | 9 |
14 files changed, 771 insertions, 829 deletions
@@ -2,7 +2,7 @@ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 - Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> + Copyright (C) 2018 Vladimir Novikov <oxore@protonmail.com> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long @@ -11,12 +11,20 @@ OBJECTS:=$(patsubst $(SRC)/%.c,$(BUILD)/%.c.o,$(SOURCES)) INCLUDE+=include INCLUDE:=$(patsubst %,-I%,$(INCLUDE)) +#COMMON+=-fsanitize=leak + +CFLAGS+=$(COMMON) CFLAGS+=$(INCLUDE) CFLAGS+=-Wall +CFLAGS+=-Wextra +CFLAGS+=-Wpedantic +CFLAGS+=-Wduplicated-branches +CFLAGS+=-Wduplicated-cond CFLAGS+=-std=c11 CFLAGS+=-g3 CFLAGS+=-O0 +LDFLAGS+=$(COMMON) LDFLAGS+=-lcsfml-graphics LDFLAGS+=-lcsfml-window LDFLAGS+=-lcsfml-system @@ -29,9 +29,9 @@ make clean __Windows__ -Hey look at the [repo releases](https://github.com/Oxore/tetris-csfml/releases)! Now I have some windows binaries there! +Look at the [repo releases](https://github.com/Oxore/tetris-csfml/releases)! Now I have some windows binaries there! -__TODO:__ +### TODO: - Add screenshots and gameplay gif - [x] Levels speed and scores calibration diff --git a/include/common.h b/include/common.h index 773cb3f..275547a 100644 --- a/include/common.h +++ b/include/common.h @@ -1,82 +1,13 @@ -/* - * Types - * - * */ - -typedef struct Cell { - char a; // active/empty state of cell - sfColor fColor; // fill color -} Cell; - - -/* - * shape coords - * y - * ^. . . . - * |. . . . - * |. . . . - * |. . . . - * 0------->x - * - */ - -typedef struct Shape { - int x; // x coord of shape's left side - int y; // y coord of shape's bottom - int t; // shape type - sfColor fColor; // shape color - char c[4][4]; // array of logic shape cells - sfRectangleShape *p[4][4]; // array of physical shape cells - sfVector2f cSize; // shape rectangles size variable x/y -} Shape; - -typedef struct Field { - sfVector2i pos; - sfColor fColor; // shape color - Cell c[25][10]; // array of logic shape cells - sfRectangleShape *p[25][10]; // array of physical shape cells - int cOutThick; // Field rectangles outline thickness - sfVector2f cSize; // shape rectangles size variable x/y - sfVector2i size; -} Field; - -typedef struct Window { +struct window { sfVideoMode mode; sfRenderWindow *window; sfEvent event; -} Window; +}; -typedef struct Game { +struct game { int isStarted; int scoreCurrent; int level; int moveLatency; int lines; -} Game; - -/* ======== text.[c|h] types =========== */ - -typedef struct List { - void *obj; - void *next; - void *prev; -} List; - -typedef struct Pair { - void *k; - void *v; -} Pair; - -typedef struct KeyMap { - Pair *pair; - void *next; - void *prev; -} KeyMap; - -typedef struct Text { - char *font; - char *type; - char *scene; - char *text; - void *sfText; -} Text; +}; diff --git a/include/engine.h b/include/engine.h new file mode 100644 index 0000000..655eb01 --- /dev/null +++ b/include/engine.h @@ -0,0 +1,19 @@ +#define RIGHT 1 +#define DOWN 2 +#define UP 4 +#define LEFT 8 +#define RIGHTHOLD 16 +#define LEFTHOLD 128 + +void tKeyCtrl(); +void tTick(); +void checkLevelUp(struct game *game); +int getMoveLatencyOfLevel(int level); +int rmLines(); +void valueAfterTextDisplay(int value, List *texts, char *type); +void colorizeActive(); +void drawFld(sfRenderWindow *window); +void gameover(struct game *game); +void genNextShape(); +void drawNextShape(); +void freeFld(); diff --git a/include/field.h b/include/field.h new file mode 100644 index 0000000..410e609 --- /dev/null +++ b/include/field.h @@ -0,0 +1,58 @@ +#define FLD_SIZE_Y 22 +#define FLD_SIZE_X 10 +#define FLD_BOUND_Y FLD_SIZE_Y + 3 +#define FLD_BOUND_X FLD_SIZE_X +/* + * Types + * + * */ + +struct cell { + char a; // active/empty state of cell + sfColor fColor; // fill color +}; + + +/* + * shape coords + * y + * ^. . . . + * |. . . . + * |. . . . + * |. . . . + * 0------->x + * + */ + +struct shape { + int x; // x coord of shape's left side + int y; // y coord of shape's bottom + int t; // shape type + sfColor fColor; // shape color + char c[4][4]; // array of logic shape cells + sfRectangleShape *p[4][4]; // array of physical shape cells + int cOutThick; // shape rectangles outline thickness + sfVector2f cSize; // shape rectangles size variable x/y +}; + +struct field { + sfVector2i pos; + sfColor fColor; // shape color + struct cell c[FLD_BOUND_Y][FLD_SIZE_X]; // array of logic shape cells + sfRectangleShape *p[FLD_BOUND_Y][FLD_SIZE_X]; // array of physical shape cells + int cOutThick; // Field rectangles outline thickness + sfVector2f cSize; // shape rectangles size variable x/y + sfVector2i size; + sfVector2i bound; +}; + +void init_field(struct field *fld); +void colorize_field(struct field *fld); +void colorize_field_random(struct field *fld); +void init_next_shape_field(struct shape *next); +void putShape(struct field *fld, struct shape *active); +int out_of_field(struct field *fld, struct shape *active); +void load_shape(struct shape *shape); +void rotate_shape(struct field *fld, struct shape *shape); +int collide(struct field *fld, struct shape *active); +void resetActiveShape(struct field *fld, struct shape *active); diff --git a/include/functions.h b/include/functions.h deleted file mode 100644 index f47f816..0000000 --- a/include/functions.h +++ /dev/null @@ -1,34 +0,0 @@ -#define RIGHT 0b0001 -#define DOWN 0b0010 -#define UP 0b0100 -#define LEFT 0b1000 -#define RIGHTHOLD 0b10000 -#define LEFTHOLD 0b10000000 - -void tKeyCtrl(); -void initFld(); -void tTick(); -void resetActiveShape(Shape *active); -void putShape(); -int outOfFieldCheck(Field *fld, Shape *active); -void checkLevelUp(Game *game); -int getMoveLatencyOfLevel(int level); -int cellCollisionCheckHere(Field *fld, Shape *active); -int cellCollisionCheck(int dir); -int wallCollisionCheck(); -int cellRotCollisionCheck(); -int wallRotCollisionCheck(); -void rotateLeft(); -void rotateRight(); -void rotateShape(); -int rmLines(); -void valueAfterTextDisplay(int value, List *texts, char *type); -void colorizeFld(); -void colorizeActive(); -void drawFld(sfRenderWindow *window); -void colorizeRandom(Field *fld); -void gameover(Game *game); -void genNextShape(); -void copyShape(Shape *localSh); -void drawNextShape(); -void freeFld(); diff --git a/include/text.h b/include/text.h index 1171a51..73285bf 100644 --- a/include/text.h +++ b/include/text.h @@ -1,17 +1,39 @@ -FILE *openFile(char *filename); -void checkArgs(int argc, char **argv); +typedef struct List { + void *obj; + void *next; + void *prev; +} List; + +typedef struct Pair { + void *k; + void *v; +} Pair; + +typedef struct KeyMap { + Pair *pair; + void *next; + void *prev; +} KeyMap; + +typedef struct Text { + char *font; + char *type; + char *scene; + char *text; + void *sfText; +} Text; + +FILE *openFile(char *filename); +void checkArgs(int argc, char **argv); KeyMap *KeyMap_getLast(KeyMap **keyMap); KeyMap *KeyMap_new(KeyMap **keyMap); KeyMap *KeyMap_get(KeyMap **keyMap, const void *key); KeyMap *KeyMap_put(KeyMap **keyMap, const void *key, const void *value); -List *List_getLast(List **list); -List *List_new(List **list); -List *ListOfKeyMapOfString_getFromYaml(char *filename); -void KeyMapOfString_free(KeyMap *keyMap); -void ListOfKeyMapOfString_free(List **list); -int _loadText_getInt(void *obj, char *key); -char *_loadText_getString(void *obj, char *key); -void _loadText_initSfText(Text *objo, void *obji); -List *ListOfText_getFromListOfKeyMapOfString(List *list); -void Text_free(Text *obj); -void ListOfText_free(List **list); +List *List_getLast(List **list); +List *List_new(List **list); +List *ListOfKeyMapOfString_getFromYaml(char *filename); +void KeyMapOfString_free(KeyMap *keyMap); +void ListOfKeyMapOfString_free(List **list); +List *ListOfText_getFromListOfKeyMapOfString(List *list); +void Text_free(Text *obj); +void ListOfText_free(List **list); diff --git a/src/engine.c b/src/engine.c new file mode 100644 index 0000000..6df3c79 --- /dev/null +++ b/src/engine.c @@ -0,0 +1,367 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <SFML/System/Clock.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 "engine.h" + +/* Externs from main.c */ +extern struct game game; +extern struct shape active, next; +extern struct field fld; + +extern sfFont *fontScore; + +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; + while (l) { + Text *text = (Text *)l->obj; + if (text->type) + if (!strcmp(text->type, type)) { + char a[64]; + if (text->text) { + if (strlen(text->text) > 52) { + memset(text->text+52, '\0', 1); + strcpy(a, text->text); + } + sprintf(a, "%s%d", text->text, value); + sfText_setString(text->sfText, (char *)&a); + break; + } + } + l = l->next; + } +} + +/* + * Removes line when cells all are in row in it + * + */ +int rmLines() +{ + int k = 0; // "Filled line" indicator + int s = 0; + for (int j = 0; j < 22; j++) { + for (int i = 0; i < 10; i++) + if (fld.c[j][i].a != 0) + k++; + if (k >= 10) { // If line is full + s++; // Give scores for line + for (int n = j; n < 22; n++) { // Drop all lines down + if (n == 21) { + for (int m = 0; m < 10; m++) { + fld.c[n][m].a = 0; + fld.c[n][m].fColor = UIBGCOLOR; + } + break; + } + 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; + } + } + j--; // Do not let loop to go to next line because + // next line go down by itself =) + } + k = 0; // Clear line fill indicator + } + return s; // Return number of deleted lines +} + +void checkLevelUp(struct game *game) +{ + while (game->lines >= LEVELUP_LINES) { + game->level++; + game->lines -= LEVELUP_LINES; + game->moveLatency = getMoveLatencyOfLevel(game->level); + } +} + +int getMoveLatencyOfLevel(int level) +{ + if (level >= 29) + return L29LATENCY; + else if (level >= 19) + return L19LATENCY; + else if (level >= 16) + return L16LATENCY; + else if (level >= 13) + return L13LATENCY; + else if (level >= 10) + return L10LATENCY; + else if (level == 9) + return L09LATENCY; + else if (level == 8) + return L08LATENCY; + else if (level == 7) + return L07LATENCY; + else if (level == 6) + return L06LATENCY; + else if (level == 5) + return L05LATENCY; + else if (level == 4) + return L04LATENCY; + else if (level == 3) + return L03LATENCY; + else if (level == 2) + return L02LATENCY; + else if (level == 1) + return L01LATENCY; + else if (level == 0) + return L00LATENCY; + return L00LATENCY; +} + + +/* + * Game tick + * + */ +void tTick() +{ // If tick exceeds current level tick latency + if (sfClock_getElapsedTime(gameTick).microseconds >= game.moveLatency) { + sfClock_restart(gameTick); + active.y--; // try + if (collide(&fld, &active)) + active.y++; // fallback + else + sfClock_restart(putTick); + if (sfClock_getElapsedTime(putTick).microseconds >= PUT_LATENCY) { + if (out_of_field(&fld, &active)) { + gameover(&game); + return; + } else { + putShape(&fld, &active); + int removedLines = rmLines(); + game.lines += removedLines; + switch (removedLines) { + case 1: + game.scoreCurrent += RM_1LINES_SCORE * game.level; + break; + case 2: + game.scoreCurrent += RM_2LINES_SCORE * game.level; + break; + case 3: + game.scoreCurrent += RM_3LINES_SCORE * game.level; + break; + case 4: + game.scoreCurrent += RM_4LINES_SCORE * game.level; + break; + } + active.t = next.t; + resetActiveShape(&fld, &active); + genNextShape(); + checkLevelUp(&game); + } + sfClock_restart(putTick); + } + } +} + + + + + + +/* + * Keys hold handler + * + */ +void tKeyCtrl() +{ + /* Up arrow key 'hold' handler */ + if (sfKeyboard_isKeyPressed(sfKeyUp)) { + if (!(arrKeys & UP)) { + arrKeys = arrKeys | UP; + rotate_shape(&fld, &active); + } + } else { + if ((arrKeys & UP)) { + arrKeys = arrKeys & ~UP; + } + } + + /* Down Arrow Key 'hold' handler */ + if (sfKeyboard_isKeyPressed(sfKeyDown)) { + if (!(arrKeys & DOWN)) { + arrKeys = arrKeys | DOWN; + active.y--; + if (collide(&fld, &active)) + active.y++; + else { + // Avoid excess move down by gameTick + sfClock_restart(putTick); + sfClock_restart(gameTick); + game.scoreCurrent++; + } + sfClock_restart(repPushDown); + } else { + if (sfClock_getElapsedTime(repPushDown).microseconds + >= moveRepeatLatency2) + arrKeys = arrKeys & ~DOWN; + } + } else { + if ((arrKeys & DOWN)) { + arrKeys = arrKeys & ~DOWN; + } + } + + /* Left Arrow Key 'hold' handler */ + if (sfKeyboard_isKeyPressed(sfKeyLeft) + && !sfKeyboard_isKeyPressed(sfKeyRight)) { + if (!(arrKeys & LEFT)) { + arrKeys = arrKeys | LEFT; + active.x--; + if (collide(&fld, &active)) + active.x++; + else + sfClock_restart(putTick); + sfClock_restart(repKeyLeft); + } else { + if (!(arrKeys & LEFTHOLD)) { + if (sfClock_getElapsedTime(repKeyLeft).microseconds + >= moveRepeatLatency1) { + arrKeys = arrKeys | LEFTHOLD; + arrKeys = arrKeys & ~LEFT; + } + } else { + if (sfClock_getElapsedTime(repKeyLeft).microseconds + >= moveRepeatLatency2) + arrKeys = arrKeys & ~LEFT; + } + } + } else if (!sfKeyboard_isKeyPressed(sfKeyLeft)) { + if ((arrKeys & LEFT)) { + arrKeys = arrKeys & ~LEFT; + arrKeys = arrKeys & ~LEFTHOLD; + } + } + + /* Right Arrow Key 'hold' handler */ + if (sfKeyboard_isKeyPressed(sfKeyRight) + && !sfKeyboard_isKeyPressed(sfKeyLeft)) { + if (!(arrKeys & RIGHT)) { + arrKeys = arrKeys | RIGHT; + active.x++; + if (collide(&fld, &active)) + active.x--; + else + sfClock_restart(putTick); + sfClock_restart(repKeyRight); + } else { + if (!(arrKeys & RIGHTHOLD)) { + if (sfClock_getElapsedTime(repKeyRight).microseconds + >= moveRepeatLatency1) { + arrKeys = arrKeys | RIGHTHOLD; + arrKeys = arrKeys & ~RIGHT; + } + } else if (!sfKeyboard_isKeyPressed(sfKeyLeft)) { + if (sfClock_getElapsedTime(repKeyRight).microseconds + >= moveRepeatLatency2) // Wait short time + arrKeys = arrKeys & ~RIGHT; + } + } + } else { + if ((arrKeys & RIGHT)) { + arrKeys = arrKeys & ~RIGHT; + arrKeys = arrKeys & ~RIGHTHOLD; + } + } +} + + +/* + * Colorize active cells of active shape (overlay only + * active cells above background of fld) + * + */ +void colorizeActive() +{ + for (int j = 0; j < 4; j++) + for (int i = 0; i < 4; i++) + if (active.c[j][i] && j+active.y < 22) { + sfRectangleShape_setFillColor(fld.p[j + active.y][i + active.x], + active.fColor); + sfRectangleShape_setOutlineColor( + fld.p[j + active.y][i + active.x], UIFGACTIVECOLOR); + } +} + + +/* + * Draw all fld cells + * + */ +void drawFld(sfRenderWindow *window) +{ + 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; + game->scoreCurrent = 0; + game->level = 0; + game->moveLatency = L00LATENCY; + game->lines = 0; +} + + +void genNextShape() +{ + next.t = (rand() % 7) + 1; // Insert new random shape of 7 variants + load_shape(&next); + if (next.t == 5) + for (int j = 0; j < 3; j++) + for (int i = 0; i < 4; i++) + next.c[i][j] = next.c[i][j+1]; +} + + + + +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); + } +} + +void freeFld() { + for (int j = 0; j < fld.size.y; j++) + for (int i = 0; i < fld.size.x; i++) + sfRectangleShape_destroy(fld.p[j][i]); + for (int j = 0; j < 4; j++) + for (int i = 0; i < 4; i++) + sfRectangleShape_destroy(next.p[j][i]); +} diff --git a/src/field.c b/src/field.c new file mode 100644 index 0000000..dcb332d --- /dev/null +++ b/src/field.c @@ -0,0 +1,235 @@ +#include <stdlib.h> +#include <string.h> +#include <SFML/Graphics/RectangleShape.h> + +#include "field.h" +#include "tet_conf.h" + +/* Shapes maps */ +extern char arrShapeL[4][4]; +extern char arrShapeRL[4][4]; +extern char arrShapeZ[4][4]; +extern char arrShapeS[4][4]; +extern char arrShapeB[4][4]; +extern char arrShapeI[4][4]; +extern char arrShapeT[4][4]; + +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) +{ + 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); + } + } +} + +void colorize_field(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); + } +} + +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); + } + } +} + +void init_next_shape_field(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) +{ + 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; + } +} + +int out_of_field(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) + return 1; + return 0; +} + +void load_shape(struct shape *shape) +{ + 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) +{ + load_shape(active); + active->x = 3; + if (active->t == 6) + active->y = 19; + else + active->y = 18; + while (collide(fld, active)) { + active->y++; + } +} + +int collide(struct field *fld, struct shape *active) +{ + if (out_of_bounds(fld, active)) + 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) + return 1; + return 0; +} + +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) + return 1; + return 0; +} + +static void rotate_shape_left(struct shape *shape) +{ + char arr[4][4]; + memcpy(&arr[0][0], &shape->c[0][0], sizeof(char)*4*4); + if (shape->t == 5) + return; + if (shape->t == 6) { + for (int j = 3; j >= 0; j--) + for (int i = 0; i < 4; i++) + shape->c[j][i] = arr[3-i][3-j]; + return; + } + for (int j = 3; j > 0; j--) + for (int i = 0; i < 3; i++) + shape->c[j][i] = arr[3-i][j-1]; +} + +static void rotate_shape_right(struct shape *shape) +{ + char arr[4][4]; + memcpy(&arr[0][0], &shape->c[0][0], sizeof(char)*4*4); + if (shape->t == 5) + return; + if (shape->t == 6) { + for (int j = 3; j >= 0; j--) + for (int i = 0; i < 4; i++) + shape->c[j][i] = arr[3-i][3-j]; + return; + } + for (int j = 3; j > 0; j--) + for (int i = 0; i < 3; i++) + shape->c[j][i] = arr[i+1][3-j]; +} + +void rotate_shape(struct field *fld, struct shape *shape) +{ + rotate_shape_right(shape); + if (collide(fld, shape)) + rotate_shape_left(shape); +} diff --git a/src/functions.c b/src/functions.c deleted file mode 100644 index eebbf67..0000000 --- a/src/functions.c +++ /dev/null @@ -1,678 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <SFML/System/Clock.h> -#include <SFML/Graphics/RenderWindow.h> -#include <SFML/Graphics/Text.h> -#include <SFML/Graphics/RectangleShape.h> - -#include "common.h" -#include "tet_conf.h" -#include "functions.h" - -/* Externs from main.c */ -extern Game game; -extern Shape active, next; -extern Field fld; - -extern sfFont *fontScore; - -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 - -/* Shapes maps */ -extern char arrShapeL[4][4]; -extern char arrShapeRL[4][4]; -extern char arrShapeZ[4][4]; -extern char arrShapeS[4][4]; -extern char arrShapeB[4][4]; -extern char arrShapeI[4][4]; -extern char arrShapeT[4][4]; - - -/* Field init routine */ -void initFld() -{ - sfVector2f fldCPos[22][10]; - /* Create field */ - 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); - } - } - /* Create next shape field */ - 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*fld.cOutThick); - nsPos.y = next.y-j*(next.cSize.y+2*fld.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], fld.cOutThick); - } - } - genNextShape(); - resetActiveShape(&active); -} - - -void valueAfterTextDisplay(int value, List *texts, char *type) -{ - List *l = texts; - while (l) { - Text *text = (Text *)l->obj; - if (text->type) - if (!strcmp(text->type, type)) { - char a[64]; - if (text->text) { - if (strlen(text->text) > 52) { - memset(text->text+52, '\0', 1); - strcpy(a, text->text); - } - sprintf(a, "%s%d", text->text, value); - sfText_setString(text->sfText, (char *)&a); - break; - } - } - l = l->next; - } -} - -/* - * Removes line when cells all are in row in it - * - */ -int rmLines() -{ - int k = 0; // "Filled line" indicator - int s = 0; - for (int j = 0; j < 22; j++) { - for (int i = 0; i < 10; i++) - if (fld.c[j][i].a != 0) - k++; - if (k >= 10) { // If line is full - s++; // Give scores for line - for (int n = j; n < 22; n++) { // Drop all lines down - if (n == 21) { - for (int m = 0; m < 10; m++) { - fld.c[n][m].a = 0; - fld.c[n][m].fColor = UIBGCOLOR; - } - break; - } - 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; - } - } - j--; // Do not let loop to go to next line because - // next line go down by itself =) - } - k = 0; // Clear line fill indicator - } - return s; // Return number of deleted lines -} - -/* - * Inserts shape into field, runs filled lines searching, puts new shape - * into the game at the top. - * - */ -void putShape() -{ - if (outOfFieldCheck(&fld, &active)) { - gameover(&game); - return; - } - 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]; - if ((j+active.y >= 0) && (i+active.x >= 0)) - fld.c[j+active.y][i+active.x].fColor = active.fColor; - } - int removedLines = rmLines(); - game.lines += removedLines; - switch (removedLines) { - case 1: - game.scoreCurrent += RM_1LINES_SCORE * game.level; - break; - case 2: - game.scoreCurrent += RM_2LINES_SCORE * game.level; - break; - case 3: - game.scoreCurrent += RM_3LINES_SCORE * game.level; - break; - case 4: - game.scoreCurrent += RM_4LINES_SCORE * game.level; - break; - } - resetActiveShape(&active); - checkLevelUp(&game); -} - -int outOfFieldCheck(Field *fld, 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) { - gameover(&game); - return 1; - } - } - } - return 0; -} - -void checkLevelUp(Game *game) -{ - while (game->lines >= LEVELUP_LINES) { - game->level++; - game->lines -= LEVELUP_LINES; - game->moveLatency = getMoveLatencyOfLevel(game->level); - } -} - -int getMoveLatencyOfLevel(int level) -{ - if (level >= 29) - return L29LATENCY; - else if (level >= 19) - return L19LATENCY; - else if (level >= 16) - return L16LATENCY; - else if (level >= 13) - return L13LATENCY; - else if (level >= 10) - return L10LATENCY; - else if (level == 9) - return L09LATENCY; - else if (level == 8) - return L08LATENCY; - else if (level == 7) - return L07LATENCY; - else if (level == 6) - return L06LATENCY; - else if (level == 5) - return L05LATENCY; - else if (level == 4) - return L04LATENCY; - else if (level == 3) - return L03LATENCY; - else if (level == 2) - return L02LATENCY; - else if (level == 1) - return L01LATENCY; - else if (level == 0) - return L00LATENCY; - return L00LATENCY; -} - -void resetActiveShape(Shape *active) -{ - genNextShape(); - copyShape(active); - active->x = 3; - if (active->t == 6) - active->y = 19; - else - active->y = 18; - for (;;) { - if (cellCollisionCheckHere(&fld, active)) - active->y++; - else - break; - } -} - -/* - * Game tick - * - */ -void tTick() -{ // If tick exceeds current level tick latency - if (sfClock_getElapsedTime(gameTick).microseconds - >= game.moveLatency) { - sfClock_restart(gameTick); - /* if bottom not reached */ - if ((wallCollisionCheck(DOWN) == 0) - && (cellCollisionCheck(DOWN) == 0)) { - active.y--; // Move - sfClock_restart(putTick); - } else { - if (sfClock_getElapsedTime(putTick).microseconds >= PUT_LATENCY) { - putShape(); // Just put the shape - sfClock_restart(putTick); - } - } - } -} - - -/* - * Rotate matrix left routine - * - */ -void rotateLeft() -{ - char arr[4][4]; - memcpy(&arr[0][0], &active.c[0][0], sizeof(char)*4*4); - if (active.t == 5) - return; - if (active.t == 6) { - for (int j = 3; j >= 0; j--) - for (int i = 0; i < 4; i++) - active.c[j][i] = arr[3-i][3-j]; - return; - } - for (int j = 3; j > 0; j--) - for (int i = 0; i < 3; i++) - active.c[j][i] = arr[3-i][j-1]; -} - - -/* - * Rotate matrix right routine - * - */ -void rotateRight() -{ - char arr[4][4]; - memcpy(&arr[0][0], &active.c[0][0], sizeof(char)*4*4); - if (active.t == 5) - return; - if (active.t == 6) { - for (int j = 3; j >= 0; j--) - for (int i = 0; i < 4; i++) - active.c[j][i] = arr[3-i][3-j]; - return; - } - for (int j = 3; j > 0; j--) - for (int i = 0; i < 3; i++) - active.c[j][i] = arr[i+1][3-j]; -} - - -/* - * Rotates active shape with callling collision checkers - * - */ -void rotateShape() -{ - rotateRight(); // Try rotate - if ((wallRotCollisionCheck()) - || (cellRotCollisionCheck())) - rotateLeft(); -} - -int cellRotCollisionCheck() -{ - 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) - return 1; // Collision happens - return 0; // Else it do not -} - - -int wallRotCollisionCheck() -{ - if (active.y < 0) //If shape has crossed Bottom border - for (int i = 0; i < 4; i++) - if (active.c[-1-active.y][i]) - return 1; // Collision happens - if (active.x < 0) //If shape has crossed Left border - for (int i = 0; i < 4; i++) - if (active.c[i][-1-active.x]) - return 1; // Collision happens - if (active.x > 6) //If shape has crossed Right border - for (int i = 0; i < 4; i++) - if (active.c[i][3-(active.x-7)]) - return 1; // Collision happens - return 0; // If no conditions are met collision is absent -} - -int cellCollisionCheckHere(Field *fld, Shape *active) -{ - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - if (active->y + i < fld->size.y) - if (active->c[i][j] && fld->c[i+active->y][j+active->x].a) - return 1; - return 0; -} - -int cellCollisionCheck(int dir) -{ - for (int j = 0; j < 4; j++) { - for (int i = 0; i < 4; i++) { - if ((dir & RIGHT) // Check Right - && (j+active.y >= 0) // Avoiding nonexisting fld cells - && (i+active.x+1 >= 0) // --- - && active.c[j][i] // Check activity - && fld.c[j+active.y][i+active.x+1].a) - return 1; // Collision happens - if ((dir & LEFT) // Check Left - && (j+active.y >= 0) // Avoiding nonexisting fld cells - && (i+active.x-1 >= 0) // --- - && active.c[j][i] // Check activity - && fld.c[j+active.y][i+active.x-1].a) - return 1; // Collision happens - if ((dir & DOWN) // Check Bottom - && (j+active.y-1 >= 0) // Avoiding nonexisting fld cells - && (i+active.x >= 0) // --- - && active.c[j][i] // Check activity - && fld.c[j+active.y-1][i+active.x].a) - return 1; // Collision happens - } - } - return 0; // Else it do not -} - -int wallCollisionCheck(int dir) -{ - if (dir & RIGHT) { // Right collision request - if (active.x >= 6) // If shape has reached Right boreder - for (int i = 0 ; i < 4; i++) - if (active.c[i][3-(active.x-6)]) - return 1; // Collision happens - } else if (dir & DOWN) { // Bottom collision request - if (active.y <= 0) //If shape has reached Bottom border - for (int i = 0; i < 4; i++) - if (active.c[-active.y][i]) - return 1; // Collision happens - } else if (dir & LEFT) // Left collision request - if (active.x <= 0) // If shape has reached Left border - for (int i = 0; i < 4; i++) - if (active.c[i][-active.x]) - return 1; // Collision happens - return 0; -} - - -/* - * Keys hold handler - * - */ -void tKeyCtrl() -{ - /* Up arrow key 'hold' handler */ - if (sfKeyboard_isKeyPressed(sfKeyUp)) { - if (!(arrKeys & UP)) { - arrKeys = arrKeys | UP; - rotateShape(); - } - } else { - if ((arrKeys & UP)) { - arrKeys = arrKeys & ~UP; - } - } - - /* Down Arrow Key 'hold' handler */ - if (sfKeyboard_isKeyPressed(sfKeyDown)) { - if (!(arrKeys & DOWN)) { - arrKeys = arrKeys | DOWN; - if (!wallCollisionCheck(DOWN) - && !cellCollisionCheck(DOWN)) { - active.y--; - // Avoid excess move down by gameTick - sfClock_restart(putTick); - sfClock_restart(gameTick); - game.scoreCurrent++; - } - repPushDown = sfClock_create(); - } else { - if (sfClock_getElapsedTime(repPushDown).microseconds - >= moveRepeatLatency2) - arrKeys = arrKeys & ~DOWN; - } - } else { - if ((arrKeys & DOWN)) { - arrKeys = arrKeys & ~DOWN; - } - } - - /* Left Arrow Key 'hold' handler */ - if (sfKeyboard_isKeyPressed(sfKeyLeft) - && !sfKeyboard_isKeyPressed(sfKeyRight)) { - if (!(arrKeys & LEFT)) { - arrKeys = arrKeys | LEFT; - if (!wallCollisionCheck(LEFT) - && !cellCollisionCheck(LEFT)) { - active.x--; - sfClock_restart(putTick); - } - repKeyLeft = sfClock_create(); - } else { - if (!(arrKeys & LEFTHOLD)) { - if (sfClock_getElapsedTime(repKeyLeft) - .microseconds - >= moveRepeatLatency1) { - arrKeys = arrKeys | LEFTHOLD; - arrKeys = arrKeys & ~LEFT; - } - } else { - if (sfClock_getElapsedTime(repKeyLeft) - .microseconds - >= moveRepeatLatency2) - arrKeys = arrKeys & ~LEFT; - } - } - } else if (!sfKeyboard_isKeyPressed(sfKeyLeft)) { - if ((arrKeys & LEFT)) { - arrKeys = arrKeys & ~LEFT; - arrKeys = arrKeys & ~LEFTHOLD; - } - } - - /* Right Arrow Key 'hold' handler */ - if (sfKeyboard_isKeyPressed(sfKeyRight) - && !sfKeyboard_isKeyPressed(sfKeyLeft)) { - if (!(arrKeys & RIGHT)) { - arrKeys = arrKeys | RIGHT; - if (!wallCollisionCheck(RIGHT) - && !cellCollisionCheck(RIGHT)) { - active.x++; - sfClock_restart(putTick); - } - repKeyRight = sfClock_create(); - } else { - if (!(arrKeys & RIGHTHOLD)) { - if (sfClock_getElapsedTime(repKeyRight).microseconds - >= moveRepeatLatency1) { - arrKeys = arrKeys | RIGHTHOLD; - arrKeys = arrKeys & ~RIGHT; - } - } else if (!sfKeyboard_isKeyPressed(sfKeyLeft)) { - if (sfClock_getElapsedTime(repKeyRight).microseconds - >= moveRepeatLatency2) // Wait short time - arrKeys = arrKeys & ~RIGHT; - } - } - } else { - if ((arrKeys & RIGHT)) { - arrKeys = arrKeys & ~RIGHT; - arrKeys = arrKeys & ~RIGHTHOLD; - } - } -} - - -/* - * Colorize active cells of field - * - */ -void colorizeFld() -{ - 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); - } -} - -/* - * Colorize active cells of active shape (overlay only - * active cells above background of fld) - * - */ -void colorizeActive() -{ - for (int j = 0; j < 4; j++) - for (int i = 0; i < 4; i++) - if (active.c[j][i] && j+active.y < 22) { - sfRectangleShape_setFillColor( - fld.p[j+active.y][i+active.x], - active.fColor); - sfRectangleShape_setOutlineColor( - fld.p[j+active.y][i+active.x], - UIFGACTIVECOLOR); - } -} - - -/* - * Draw all fld cells - * - */ -void drawFld(sfRenderWindow *window) -{ - 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 colorizeRandom(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); - } - } -} - - -void gameover(Game *game) -{ - game->isStarted = 0; - game->scoreCurrent = 0; - game->level = 0; - game->moveLatency = L00LATENCY; - game->lines = 0; -} - - -void genNextShape() -{ - active.t = next.t; - next.t = (rand()%7)+1; // Insert new random shape of 7 variants - copyShape(&next); - if (next.t == 5) - for (int j = 0; j < 3; j++) - for (int i = 0; i < 4; i++) - next.c[i][j] = next.c[i][j+1]; -} - - -void copyShape(Shape *localSh) -{ - switch (localSh->t) { // Copy cell active/inactive state - case 1 : - memcpy(&localSh->c[0][0], &arrShapeL[0][0], sizeof(char)*4*4); - localSh->fColor = LCOLOR; - break; - case 2 : - memcpy(&localSh->c[0][0], &arrShapeRL[0][0], sizeof(char)*4*4); - localSh->fColor = RLCOLOR; - break; - case 3 : - memcpy(&localSh->c[0][0], &arrShapeZ[0][0], sizeof(char)*4*4); - localSh->fColor = ZCOLOR; - break; - case 4 : - memcpy(&localSh->c[0][0], &arrShapeS[0][0], sizeof(char)*4*4); - localSh->fColor = SCOLOR; - break; - case 5 : - memcpy(&localSh->c[0][0], &arrShapeB[0][0], sizeof(char)*4*4); - localSh->fColor = BCOLOR; - break; - case 6 : - memcpy(&localSh->c[0][0], &arrShapeI[0][0], sizeof(char)*4*4); - localSh->fColor = ICOLOR; - break; - case 7 : - memcpy(&localSh->c[0][0], &arrShapeT[0][0], sizeof(char)*4*4); - localSh->fColor = TCOLOR; - break; - } -} - - -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); - } -} - -void freeFld() { - for (int j = 0; j < fld.size.y; j++) - for (int i = 0; i < fld.size.x; i++) - sfRectangleShape_destroy(fld.p[j][i]); - for (int j = 0; j < 4; j++) - for (int i = 0; i < 4; i++) - sfRectangleShape_destroy(next.p[j][i]); -} @@ -8,24 +8,25 @@ #include <SFML/Graphics/Font.h> #include "common.h" -#include "functions.h" #include "text.h" +#include "field.h" +#include "engine.h" #include "tet_conf.h" -Window w = {.mode = {450, 570, 32}}; -Game game = { +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, .level = 0, .moveLatency = L00LATENCY, .lines = 0 }; -List *texts; -sfFont *fontScore; -Shape active, next; -Field fld; -char arrKeys = 0b00000000; // Arrow keys states byte container +char arrKeys = 0; // Arrow keys states byte container sfClock *gameTick; sfClock *putTick; @@ -35,10 +36,13 @@ 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) ); + 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"); @@ -52,17 +56,27 @@ void prepare() { fld.cSize = (sfVector2f){.x = 23, .y = 23}; //Fld's cell size in pixels fld.cOutThick = 1; fld.pos = (sfVector2i){.x = 10, .y = 10+550-24}; // Fld bot left corner - fld.size = (sfVector2i){.x = 10, .y = 22}; // Field's size in blocks + 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 = (Shape){.x = 250+10+20, .y = 200, - .cSize = {.x = 23, .y = 23}}; + next = (struct shape){ + .x = 250 + 10 + 20, + .y = 200, + .cOutThick = 1, + .cSize = {.x = 23, .y = 23} + }; - initFld(); - texts = ListOfText_getFromListOfKeyMapOfString(ListOfKeyMapOfString_getFromYaml("dat/texts.yaml")); - w.window = sfRenderWindow_create(w.mode, - windowName_conf, - sfResize | sfClose, - NULL); + init_field(&fld); + init_next_shape_field(&next); + genNextShape(); + active.t = next.t; + resetActiveShape(&fld, &active); + genNextShape(); + 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); @@ -88,7 +102,7 @@ void gameLoop() { tKeyCtrl(); valueAfterTextDisplay(game.scoreCurrent, texts, "score"); valueAfterTextDisplay(game.level, texts, "level"); - colorizeFld(); + colorize_field(&fld); colorizeActive(); drawFld(w.window); drawNextShape(w.window); @@ -97,9 +111,9 @@ void gameLoop() { void menuTick() { - if(sfClock_getElapsedTime(mTick).microseconds >= basicLatency) { + if (sfClock_getElapsedTime(mTick).microseconds >= basicLatency) { sfClock_restart(mTick); - colorizeRandom(&fld); + colorize_field_random(&fld); } } @@ -110,7 +124,8 @@ void menuLoop() { if (sfKeyboard_isKeyPressed(sfKeyS) == 1) { game.isStarted = 1; freeFld(); - initFld(); + init_field(&fld); + init_next_shape_field(&next); sfClock_restart(gameTick); } } @@ -130,7 +145,7 @@ void mainLoop() { int main() { prepare(); - colorizeRandom(&fld); + colorize_field_random(&fld); mainLoop(); freeFld(); sfRenderWindow_destroy(w.window); @@ -77,7 +77,6 @@ KeyMap *KeyMap_put(KeyMap **keyMap, const void *key, const void *value) KeyMap *keyMapLocal = KeyMap_get(keyMap, key); if (!keyMapLocal) { keyMapLocal = KeyMap_new(keyMap); - keyMapLocal->pair = malloc(sizeof(Pair)); keyMapLocal->pair->k = malloc(strlen(key)+1); strcpy(keyMapLocal->pair->k, key); } @@ -180,7 +179,7 @@ void ListOfKeyMapOfString_free(List **list) *list = 0; } -int _loadText_getInt(void *obj, char *key) +static int _loadText_getInt(void *obj, char *key) { int v = 0; KeyMap *keyMap = KeyMap_get((KeyMap **)&obj, key); @@ -191,7 +190,7 @@ int _loadText_getInt(void *obj, char *key) return v; } -char *_loadText_getString(void *obj, char *key) +static char *_loadText_getString(void *obj, char *key) { char *v = 0; KeyMap *keyMap = KeyMap_get((KeyMap **)&obj, key); @@ -204,10 +203,10 @@ char *_loadText_getString(void *obj, char *key) return v; } -void _loadText_initSfText(Text *objo, void *obji) +static void _loadText_initSfText(Text *objo, void *obji) { sfVector2f pos = { - .x = _loadText_getInt(obji, "x"), + .x = _loadText_getInt(obji, "x"), .y = _loadText_getInt(obji, "y") }; int size = _loadText_getInt(obji, "size"); |