summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine.c493
-rw-r--r--src/field.c1
-rw-r--r--src/idlist.c11
-rw-r--r--src/main.c116
-rw-r--r--src/painter.c (renamed from src/draw.c)185
-rw-r--r--src/text.c287
6 files changed, 564 insertions, 529 deletions
diff --git a/src/engine.c b/src/engine.c
index 9840b34..c218105 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -7,41 +7,97 @@
#include <SFML/Graphics/Text.h>
#include "common.h"
+#include "idlist.h"
#include "tet_conf.h"
+#include "vector.h"
#include "text.h"
#include "field.h"
-#include "draw.h"
+#include "painter.h"
#include "engine.h"
+#define RIGHT (1 << 0)
+#define UP (1 << 1)
+#define DOWN (1 << 2)
+#define LEFT (1 << 3)
+#define RIGHTHOLD (1 << 4)
+#define LEFTHOLD (1 << 7)
+
+int level_move_latency[] = {
+ L00LATENCY,
+ L01LATENCY,
+ L02LATENCY,
+ L03LATENCY,
+ L04LATENCY,
+ L05LATENCY,
+ L06LATENCY,
+ L07LATENCY,
+ L08LATENCY,
+ L09LATENCY,
+ L10LATENCY,
+ L11LATENCY,
+ L12LATENCY,
+ L13LATENCY,
+ L14LATENCY,
+ L15LATENCY,
+ L16LATENCY,
+ L17LATENCY,
+ L18LATENCY,
+ L19LATENCY,
+ L20LATENCY,
+ L21LATENCY,
+ L22LATENCY,
+ L23LATENCY,
+ L24LATENCY,
+ L25LATENCY,
+ L26LATENCY,
+ L27LATENCY,
+ L28LATENCY,
+ L29LATENCY
+};
+
+int rmlines_score[] = {
+ 0,
+ RM_1LINES_SCORE,
+ RM_2LINES_SCORE,
+ RM_3LINES_SCORE,
+ RM_4LINES_SCORE
+};
+
/* Externs from main.c */
-extern struct game game;
-extern struct field fld, nxt;
-
-extern char arrKeys; // Arrow keys states byte container
-
-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;
+extern struct game game;
+extern struct field fld, nxt;
+extern struct idlist *texts;
+extern char arrKeys;
+
+static void render_score_value(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->type, "score.value")) {
+ if (!text->text)
+ text->text = malloc(sizeof(char) * BUFSIZ);
+ sprintf(text->text, "%d", game.scoreCurrent);
}
}
-void checkLevelUp(struct game *game)
+static void render_level_value(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->type, "level.value")) {
+ if (!text->text)
+ text->text = malloc(sizeof(char) * BUFSIZ);
+ sprintf(text->text, "%d", game.level);
+ }
+}
+
+static int getMoveLatencyOfLevel(unsigned int level)
+{
+ if (level > 29)
+ return level_move_latency[29];
+ else
+ return level_move_latency[level];
+}
+
+static void level_up(struct game *game)
{
while (game->lines >= LEVELUP_LINES) {
game->level++;
@@ -50,206 +106,259 @@ void checkLevelUp(struct game *game)
}
}
-int getMoveLatencyOfLevel(unsigned 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(game.gameTick).microseconds >= game.moveLatency) {
- sfClock_restart(game.gameTick);
- fld.shape[0].y--; // try
- if (field_shape_collision(&fld, &fld.shape[0]))
- fld.shape[0].y++; // fallback
+static void hide_menu_text(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->scene, "menu"))
+ text->attr |= TXT_ATTR_INVISIBLE;
+}
+
+static void show_menu_text(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->scene, "menu"))
+ text->attr &= ~TXT_ATTR_INVISIBLE;
+}
+
+static void hide_game_text(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->scene, "game"))
+ text->attr |= TXT_ATTR_INVISIBLE;
+}
+
+static void show_game_text(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->scene, "game"))
+ text->attr &= ~TXT_ATTR_INVISIBLE;
+}
+
+static void update_menu_text(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->scene, "menu"))
+ painter_update_text(text->id, text);
+}
+
+static void update_game_text(void *obj)
+{
+ struct text *text = obj;
+ if (!strcmp(text->scene, "game"))
+ painter_update_text(text->id, text);
+}
+
+static void transition_game_over()
+{
+ game.isStarted = 0;
+ game.scoreCurrent = 0;
+ game.level = 0;
+ game.moveLatency = L00LATENCY;
+ game.lines = 0;
+
+ nxt.attr |= FLD_ATTR_INVISIBLE;
+ painter_update_field(nxt.id, &nxt);
+
+ fld.shape[0].y = fld.size.y;
+ field_fill_random(&fld);
+ painter_update_field(fld.id, &fld);
+
+ list_foreach(texts, show_menu_text);
+ list_foreach(texts, hide_game_text);
+ list_foreach(texts, update_menu_text);
+ list_foreach(texts, update_game_text);
+}
+
+static void transition_put_shape()
+{
+ field_put_shape(&fld, &fld.shape[0]);
+ int removedLines = field_rm_lines(&fld);
+ game.lines += removedLines;
+ game.scoreCurrent += rmlines_score[removedLines] * game.level;
+ 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]);
+ level_up(&game);
+}
+
+static void game_tick()
+{
+ sfClock_restart(game.gameTick);
+ 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 (field_shape_out_of_bounds(&fld, &fld.shape[0]))
+ transition_game_over();
else
- sfClock_restart(game.putTick);
- if (sfClock_getElapsedTime(game.putTick).microseconds >= PUT_LATENCY) {
- 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 {
- field_put_shape(&fld, &fld.shape[0]);
- int removedLines = field_rm_lines(&fld);
- 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;
- }
- 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);
- }
+ transition_put_shape();
+ sfClock_restart(game.putTick);
}
}
-/*
- * Keys hold handler
- *
- */
-void tKeyCtrl()
+static void signal_up()
+{
+ field_rotate_shape(&fld, 0);
+}
+
+static void signal_down()
{
- /* Up arrow key 'hold' handler */
+ fld.shape[0].y--;
+ if (field_shape_collision(&fld, &fld.shape[0])) {
+ fld.shape[0].y++;
+ } else {
+ sfClock_restart(game.gameTick);
+ game.scoreCurrent++;
+ }
+ sfClock_restart(game.repPushDown);
+}
+
+static void signal_left()
+{
+ 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);
+}
+
+static void signal_right()
+{
+ 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);
+}
+
+static void game_keys()
+{
+ /* UP */
if (sfKeyboard_isKeyPressed(sfKeyUp)) {
if (!(arrKeys & UP)) {
arrKeys = arrKeys | UP;
- field_rotate_shape(&fld, 0);
+ signal_up();
}
} else {
- if ((arrKeys & UP)) {
- arrKeys = arrKeys & ~UP;
- }
+ arrKeys = arrKeys & ~UP;
}
- /* Down Arrow Key 'hold' handler */
+ /* DOWN */
if (sfKeyboard_isKeyPressed(sfKeyDown)) {
if (!(arrKeys & DOWN)) {
arrKeys = arrKeys | DOWN;
- 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);
- sfClock_restart(game.gameTick);
- game.scoreCurrent++;
- }
- sfClock_restart(game.repPushDown);
+ signal_down();
} else {
- if (sfClock_getElapsedTime(game.repPushDown).microseconds
- >= moveRepeatLatency2)
+ if (sfClock_getElapsedTime(game.repPushDown).microseconds >= moveRepeatLatency2)
arrKeys = arrKeys & ~DOWN;
}
} else {
- if ((arrKeys & DOWN)) {
- arrKeys = arrKeys & ~DOWN;
- }
+ arrKeys = arrKeys & ~DOWN;
}
- /* Left Arrow Key 'hold' handler */
- if (sfKeyboard_isKeyPressed(sfKeyLeft)
- && !sfKeyboard_isKeyPressed(sfKeyRight)) {
+ /* LEFT */
+ if (sfKeyboard_isKeyPressed(sfKeyLeft) && !sfKeyboard_isKeyPressed(sfKeyRight)) {
if (!(arrKeys & LEFT)) {
arrKeys = arrKeys | LEFT;
- 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);
- } else {
- if (!(arrKeys & LEFTHOLD)) {
- if (sfClock_getElapsedTime(game.repKeyLeft).microseconds
- >= moveRepeatLatency1) {
- arrKeys = arrKeys | LEFTHOLD;
- arrKeys = arrKeys & ~LEFT;
- }
- } else {
- if (sfClock_getElapsedTime(game.repKeyLeft).microseconds
- >= moveRepeatLatency2)
- arrKeys = arrKeys & ~LEFT;
+ signal_left();
+ } else if (!(arrKeys & LEFTHOLD)) {
+ if (sfClock_getElapsedTime(game.repKeyLeft).microseconds >= moveRepeatLatency1) {
+ arrKeys = arrKeys | LEFTHOLD;
+ arrKeys = arrKeys & ~LEFT;
}
+ } else {
+ if (sfClock_getElapsedTime(game.repKeyLeft).microseconds >= moveRepeatLatency2)
+ arrKeys = arrKeys & ~LEFT;
}
- } else if (!sfKeyboard_isKeyPressed(sfKeyLeft)) {
- if ((arrKeys & LEFT)) {
- arrKeys = arrKeys & ~LEFT;
- arrKeys = arrKeys & ~LEFTHOLD;
- }
+ } else {
+ arrKeys = arrKeys & ~LEFT;
+ arrKeys = arrKeys & ~LEFTHOLD;
}
- /* Right Arrow Key 'hold' handler */
- if (sfKeyboard_isKeyPressed(sfKeyRight)
- && !sfKeyboard_isKeyPressed(sfKeyLeft)) {
+ /* RIGHT */
+ if (sfKeyboard_isKeyPressed(sfKeyRight) && !sfKeyboard_isKeyPressed(sfKeyLeft)) {
if (!(arrKeys & RIGHT)) {
arrKeys = arrKeys | RIGHT;
- 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);
- } else {
- if (!(arrKeys & RIGHTHOLD)) {
- if (sfClock_getElapsedTime(game.repKeyRight).microseconds
- >= moveRepeatLatency1) {
- arrKeys = arrKeys | RIGHTHOLD;
- arrKeys = arrKeys & ~RIGHT;
- }
- } else if (!sfKeyboard_isKeyPressed(sfKeyLeft)) {
- if (sfClock_getElapsedTime(game.repKeyRight).microseconds
- >= moveRepeatLatency2) // Wait short time
- arrKeys = arrKeys & ~RIGHT;
+ signal_right();
+ } else if (!(arrKeys & RIGHTHOLD)) {
+ if (sfClock_getElapsedTime(game.repKeyRight).microseconds >= moveRepeatLatency1) {
+ arrKeys = arrKeys | RIGHTHOLD;
+ arrKeys = arrKeys & ~RIGHT;
}
+ } else {
+ if (sfClock_getElapsedTime(game.repKeyRight).microseconds >= moveRepeatLatency2)
+ arrKeys = arrKeys & ~RIGHT;
}
} else {
- if ((arrKeys & RIGHT)) {
- arrKeys = arrKeys & ~RIGHT;
- arrKeys = arrKeys & ~RIGHTHOLD;
- }
+ arrKeys = arrKeys & ~RIGHT;
+ arrKeys = arrKeys & ~RIGHTHOLD;
}
}
-void gameover(struct game *game)
+static void menuTick()
{
- game->isStarted = 0;
- game->scoreCurrent = 0;
- game->level = 0;
- game->moveLatency = L00LATENCY;
- game->lines = 0;
+ sfClock_restart(game.mTick);
+ field_fill_random(&fld);
+ painter_update_field(fld.id, &fld);
}
+
+void transition_init(void)
+{
+ list_foreach(texts, show_menu_text);
+ list_foreach(texts, hide_game_text);
+ list_foreach(texts, update_menu_text);
+ list_foreach(texts, update_game_text);
+}
+
+static void transition_game_start()
+{
+ game.isStarted = 1;
+ 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;
+ list_foreach(texts, hide_menu_text);
+ list_foreach(texts, show_game_text);
+ list_foreach(texts, update_menu_text);
+ list_foreach(texts, update_game_text);
+ sfClock_restart(game.gameTick);
+}
+
+static void menu_loop() {
+ if (sfClock_getElapsedTime(game.mTick).microseconds >= basicLatency)
+ menuTick();
+ if (sfKeyboard_isKeyPressed(sfKeyS) == 1)
+ transition_game_start();
+ painter_draw();
+}
+
+static void game_loop() {
+ game_keys();
+ if (sfClock_getElapsedTime(game.gameTick).microseconds >= game.moveLatency)
+ game_tick();
+ list_foreach(texts, render_score_value);
+ list_foreach(texts, render_level_value);
+ painter_update_field(fld.id, &fld);
+ painter_update_field(nxt.id, &nxt);
+ list_foreach(texts, update_game_text);
+ painter_draw();
+}
+
+void main_loop()
+{
+ if (game.isStarted)
+ game_loop();
+ else
+ menu_loop();
+}
+
diff --git a/src/field.c b/src/field.c
index 37680ae..18b4fed 100644
--- a/src/field.c
+++ b/src/field.c
@@ -2,6 +2,7 @@
#include <string.h>
#include <SFML/Graphics/RectangleShape.h>
+#include "vector.h"
#include "field.h"
#include "tet_conf.h"
diff --git a/src/idlist.c b/src/idlist.c
index 5b4d99b..b9d551a 100644
--- a/src/idlist.c
+++ b/src/idlist.c
@@ -53,3 +53,14 @@ void list_foreach(struct idlist *list, void (*job)(void *))
job(list->obj);
}
}
+
+void list_destroy(struct idlist *list)
+{
+ if (list) {
+ while (list->next) {
+ list = list->next;
+ free(list->prev);
+ }
+ free(list);
+ }
+}
diff --git a/src/main.c b/src/main.c
index aa27332..6eafc6e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,15 +8,17 @@
#include <SFML/Graphics/Font.h>
#include "common.h"
+#include "idlist.h"
+#include "vector.h"
#include "text.h"
#include "field.h"
-#include "draw.h"
+#include "painter.h"
#include "engine.h"
#include "tet_conf.h"
-extern struct window w;
+sfRenderWindow *window;
+struct idlist *texts;
-List *texts;
sfFont *fontScore;
struct field fld, nxt;
struct game game = {
@@ -27,72 +29,19 @@ struct game game = {
.lines = 0
};
-char arrKeys = 0; // Arrow keys states byte container
+char arrKeys = 0;
-void prepare() {
+static void handleWindowEvents() {
+ sfEvent event;
+ while (sfRenderWindow_pollEvent(window, &event))
+ if (event.type == sfEvtClosed)
+ sfRenderWindow_close(window);
}
-void handleWindowEvents() {
- while (sfRenderWindow_pollEvent(w.window, &w.event))
- if (w.event.type == sfEvtClosed)
- sfRenderWindow_close(w.window);
-}
-
-void drawTextsAtScene(List *texts, char *scene, sfRenderWindow *window) {
- List *t = texts;
- while (t) {
- if (!strcmp(((Text *)t->obj)->scene, scene))
- sfRenderWindow_drawText(window, ((Text *)t->obj)->sfText, NULL);
- t = t->next;
- }
-}
-
-void gameLoop() {
- tTick();
- tKeyCtrl();
- valueAfterTextDisplay(game.scoreCurrent, texts, "score");
- valueAfterTextDisplay(game.level, texts, "level");
- painter_update_field(fld.id, &fld);
- painter_update_field(nxt.id, &nxt);
- drawTextsAtScene(texts, "game", w.window);
- painter_draw();
-}
-
-void menuTick()
+static void register_text(void *obj)
{
- if (sfClock_getElapsedTime(game.mTick).microseconds >= basicLatency) {
- sfClock_restart(game.mTick);
- field_fill_random(&fld);
- painter_update_field(fld.id, &fld);
- }
-}
-
-void menuLoop() {
- menuTick();
- drawTextsAtScene(texts, "menu", w.window);
- if (sfKeyboard_isKeyPressed(sfKeyS) == 1) {
- game.isStarted = 1;
- 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();
-}
-
-void mainLoop() {
- while (sfRenderWindow_isOpen(w.window)) {
- handleWindowEvents();
- sfRenderWindow_clear(w.window, (sfColor)UIBGCOLOR);
- if (game.isStarted)
- gameLoop();
- else
- menuLoop();
- sfRenderWindow_display(w.window);
- }
+ struct text *text = obj;
+ text->id = painter_register_text(text);
}
int main()
@@ -104,15 +53,19 @@ int main()
game.repPushDown = sfClock_create();
game.repKeyLeft = sfClock_create();
game.repKeyRight = sfClock_create();
+ painter_load_font("dat/arial.ttf");
fontScore = sfFont_createFromFile("dat/arial.ttf");
if (!fontScore) {
- printf("dat/arial.ttf font load failed");
- exit(-1);
+ printf("%s font load failed", "dat/arial.ttf");
+ exit(EXIT_FAILURE);
}
- painter_init_window();
- List *tmp = ListOfKeyMapOfString_getFromYaml("dat/texts.yaml");
- texts = ListOfText_getFromListOfKeyMapOfString(tmp);
- ListOfKeyMapOfString_free(&tmp);
+
+ sfVideoMode mode = (sfVideoMode){450, 570, 32};
+ window = sfRenderWindow_create(mode, windowName_conf, sfResize | sfClose, NULL);
+ if (!window)
+ exit(EXIT_FAILURE);
+ sfRenderWindow_setFramerateLimit(window, 60);
+ painter_set_window(window);
fld.pos = FLD_POS;
fld.size = (struct vector2ui){.x = FLD_SIZE_X, .y = FLD_SIZE_Y};
@@ -136,19 +89,34 @@ int main()
painter_update_field(fld.id, &fld);
painter_update_field(nxt.id, &nxt);
- mainLoop();
+ texts = load_texts("dat/texts.yaml");
+
+ list_foreach(texts, register_text);
+
+ transition_init();
+ while (sfRenderWindow_isOpen(window)) {
+ handleWindowEvents();
+ main_loop();
+ }
+
+ list_foreach(texts, text_destroy);
+ list_destroy(texts);
+
painter_destroy_drawables();
field_deinit(&fld);
field_deinit(&nxt);
- painter_destroy_window();
+ if (window) {
+ sfRenderWindow_destroy(window);
+ window = 0;
+ }
sfFont_destroy(fontScore);
+ painter_destroy_font();
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;
}
diff --git a/src/draw.c b/src/painter.c
index dd888d0..9f6b911 100644
--- a/src/draw.c
+++ b/src/painter.c
@@ -1,10 +1,15 @@
#include <SFML/Graphics/RenderWindow.h>
#include <SFML/Graphics/RectangleShape.h>
+#include <SFML/Graphics/Font.h>
+#include <SFML/Graphics/Text.h>
#include <stdlib.h>
+#include <stdio.h>
#include "tet_conf.h"
+#include "vector.h"
+#include "text.h"
#include "field.h"
-#include "draw.h"
+#include "painter.h"
#include "idlist.h"
@@ -19,48 +24,65 @@ static sfColor shape_color_map[] = {
TCOLOR,
};
+enum t {
+ TYPE_U,
+ TYPE_FIELD,
+ TYPE_TEXT
+};
+
+struct drawable {
+ enum t t;
+};
struct field_drawable {
+ struct drawable;
+
sfRectangleShape ***p;
- struct vector2ui size;
- unsigned int attr;
+ struct vector2ui size;
+ unsigned int attr;
};
-/*
- * TODO: Must be static in future
- *
- * */
-struct window w;
+struct text_drawable {
+ struct drawable;
+
+ sfText *text;
+ unsigned long attr;
+};
-static struct idlist *fields_list = NULL;
+static sfRenderWindow *window;
+static sfFont *font;
-void painter_init_window()
+static struct idlist *drawables = NULL;
+
+void painter_set_window(sfRenderWindow *w)
{
- w = (struct window){.mode = {450, 570, 32}};
- w.window = sfRenderWindow_create(w.mode, windowName_conf,
- sfResize | sfClose, NULL);
- if (!w.window)
- exit(EXIT_FAILURE);
- sfRenderWindow_setFramerateLimit(w.window, 60);
+ window = w;
}
-void painter_destroy_window()
+void painter_load_font(char *filename)
{
- if (w.window) {
- sfRenderWindow_destroy(w.window);
- w.window = 0;
+ font = sfFont_createFromFile(filename);
+ if (!font) {
+ printf("%s font load failed", filename);
+ exit(EXIT_FAILURE);
}
}
+void painter_destroy_font()
+{
+ sfFont_destroy(font);
+}
+
unsigned long painter_register_field(struct field *fld)
{
struct idlist *last;
- if (!fields_list)
- last = fields_list = list_new();
+ if (!drawables)
+ last = drawables = list_new();
else
- last = list_append(fields_list);
+ last = list_append(drawables);
struct field_drawable *f = calloc(1, sizeof(struct field_drawable));
+ f->t = TYPE_FIELD;
f->size = fld->size;
f->p = calloc(f->size.y, sizeof(sfRectangleShape **));
for (unsigned int j = 0; j < f->size.y; j++) {
@@ -84,7 +106,7 @@ unsigned long painter_register_field(struct field *fld)
void painter_update_field(unsigned long id, struct field *fld)
{
- struct idlist *node = list_get(fields_list, id);
+ struct idlist *node = list_get(drawables, id);
if (!node)
return;
struct field_drawable *f = node->obj;
@@ -120,23 +142,18 @@ void painter_update_field(unsigned long id, struct field *fld)
}
}
-static void draw_field(void *field)
+static void draw_field_drawable(struct drawable *d)
{
- struct field_drawable *f = field;
+ struct field_drawable *f = (void *)d;
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()
-{
- list_foreach(fields_list, draw_field);
+ sfRenderWindow_drawRectangleShape(window, f->p[j][i], NULL);
}
-static void destroy_field(void *field)
+static void destroy_field_drawable(struct drawable *d)
{
- struct field_drawable *f = field;
+ struct field_drawable *f = (void *)d;
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]);
@@ -146,30 +163,112 @@ static void destroy_field(void *field)
free(f);
}
-void painter_destroy_field(unsigned long id)
+unsigned long painter_register_text(struct text *txt)
{
- struct idlist *node = list_get(fields_list, id);
- destroy_field(node->obj);
- list_rm_node(node);
+ struct idlist *last;
+ if (!drawables)
+ last = drawables = list_new();
+ else
+ last = list_append(drawables);
+
+ struct text_drawable *t = calloc(1, sizeof(struct text_drawable));
+ t->t = TYPE_TEXT;
+ t->text = sfText_create();
+ sfText_setFont(t->text, font);
+ sfText_setCharacterSize(t->text, txt->size);
+ sfVector2f pos = (sfVector2f){.x = txt->pos.x, .y = txt->pos.y};
+ sfText_setPosition(t->text, pos);
+ sfText_setString(t->text, txt->text);
+
+ last->obj = t;
+ return last->id;
}
-void painter_destroy_fields()
+void painter_update_text(unsigned long id, struct text *txt)
{
- list_foreach(fields_list, destroy_field);
+ struct idlist *node = list_get(drawables, id);
+ if (!node)
+ return;
+ struct text_drawable *t = node->obj;
+ t->attr = txt->attr;
+ sfText_setCharacterSize(t->text, txt->size);
+ sfVector2f pos = (sfVector2f){.x = txt->pos.x, .y = txt->pos.y};
+ sfText_setPosition(t->text, pos);
+ sfText_setString(t->text, txt->text);
+}
+
+static void draw_text_drawable(struct drawable *d)
+{
+ struct text_drawable *t = (struct text_drawable *)d;
+ if (!(t->attr & TXT_ATTR_INVISIBLE))
+ sfRenderWindow_drawText(window, t->text, NULL);
+}
+
+static void destroy_text_drawable(struct drawable *d)
+{
+ struct text_drawable *t = (struct text_drawable *)d;
+ sfText_destroy(t->text);
+ free(t);
+}
+
+static void draw_drawable(void *obj)
+{
+ struct drawable *d = obj;
+ switch (d->t) {
+ case TYPE_FIELD:
+ draw_field_drawable(d);
+ break;
+ case TYPE_TEXT:
+ draw_text_drawable(d);
+ break;
+ case TYPE_U:
+ fprintf(stderr, "ERROR: Unknown type of drawable\n");
+ exit(EXIT_FAILURE);
+ break;
+ }
}
void painter_draw()
{
- draw_fields();
+ sfRenderWindow_clear(window, (sfColor)UIBGCOLOR);
+ list_foreach(drawables, draw_drawable);
+ sfRenderWindow_display(window);
+}
+
+static void destroy_drawable(void *obj)
+{
+ struct drawable *d = obj;
+ switch (d->t) {
+ case TYPE_FIELD:
+ destroy_field_drawable(d);
+ break;
+ case TYPE_TEXT:
+ destroy_text_drawable(d);
+ break;
+ case TYPE_U:
+ fprintf(stderr, "ERROR: Unknown type of drawable\n");
+ exit(EXIT_FAILURE);
+ break;
+ }
+}
+
+void painter_destroy_drawable(unsigned long id)
+{
+ struct idlist *node = list_get(drawables, id);
+ destroy_drawable(node->obj);
+ list_rm_node(node);
}
void painter_destroy_drawables()
{
- painter_destroy_fields();
+ list_foreach(drawables, destroy_drawable);
+ list_destroy(drawables);
+ drawables = 0;
}
void painter_destroy_all()
{
painter_destroy_drawables();
- painter_destroy_window();
+ painter_destroy_font();
+ window = 0;
}
diff --git a/src/text.c b/src/text.c
index e1e1e6e..a61d28a 100644
--- a/src/text.c
+++ b/src/text.c
@@ -7,255 +7,102 @@
#include <yaml.h>
#include "common.h"
+#include "idlist.h"
+#include "vector.h"
#include "text.h"
-extern sfFont *fontScore;
-
-FILE *openFile(char *filename)
+static FILE *openFile(char *filename)
{
FILE *file;
if (!(file = fopen(filename, "rb"))){
- printf("ERROR\n");
+ printf("ERROR: fild \"%s\"cannot be opened\n", filename);
exit(EXIT_FAILURE);
}
return file;
}
-void checkArgs(int argc, char **argv)
-{
- if (argc < 2) {
- printf("Usage: %s file1.yaml ...\n", argv[0]);
- exit(EXIT_FAILURE);
- }
-}
-
-KeyMap *KeyMap_getLast(KeyMap **keyMap)
-{
- KeyMap *keyMapLocal = *keyMap;
- if (keyMapLocal)
- while (keyMapLocal->next)
- keyMapLocal = keyMapLocal->next;
- return keyMapLocal;
-}
-
-KeyMap *KeyMap_new(KeyMap **keyMap)
-{
- KeyMap *keyMapLocal = KeyMap_getLast(keyMap);
- if (keyMapLocal) {
- keyMapLocal->next = malloc(sizeof(KeyMap));
- ((KeyMap *)keyMapLocal->next)->prev = keyMapLocal;
- keyMapLocal = keyMapLocal->next;
- } else {
- *keyMap = malloc(sizeof(KeyMap));
- keyMapLocal = *keyMap;
- keyMapLocal->prev = 0;
- }
- keyMapLocal->pair = malloc(sizeof(Pair));
- keyMapLocal->next = 0;
- return keyMapLocal;
-}
-
-KeyMap *KeyMap_get(KeyMap **keyMap, const void *key)
-{
- KeyMap *keyMapLocal = *keyMap;
- while (keyMapLocal)
- if (keyMapLocal->pair)
- if (keyMapLocal->pair->k)
- if (!strcmp(keyMapLocal->pair->k, key))
- return keyMapLocal;
- else
- keyMapLocal = keyMapLocal->next;
- else
- keyMapLocal = keyMapLocal->next;
- else
- keyMapLocal = keyMapLocal->next;
- return 0;
-}
-
-KeyMap *KeyMap_put(KeyMap **keyMap, const void *key, const void *value)
+struct idlist *load_texts(char *filename)
{
- KeyMap *keyMapLocal = KeyMap_get(keyMap, key);
- if (!keyMapLocal) {
- keyMapLocal = KeyMap_new(keyMap);
- keyMapLocal->pair->k = malloc(strlen(key)+1);
- strcpy(keyMapLocal->pair->k, key);
- }
- keyMapLocal->pair->v = malloc(strlen(value)+1);
- strcpy(keyMapLocal->pair->v, value);
- return keyMapLocal;
-}
-
-List *List_getLast(List **list)
-{
- List *listLocal = *list;
- if (listLocal)
- while (listLocal->next)
- listLocal = listLocal->next;
- return listLocal;
-}
-
-List *List_new(List **list)
-{
- List *listLocal = List_getLast(list);
- if (listLocal) {
- (listLocal)->next = malloc(sizeof(List));
- ((List *)listLocal->next)->prev = listLocal;
- listLocal = listLocal->next;
- } else {
- *list = malloc(sizeof(List));
- (*list)->prev = 0;
- listLocal = *list;
- }
- listLocal->obj = 0;
- listLocal->next = 0;
- return listLocal;
-}
-
-List *ListOfKeyMapOfString_getFromYaml(char *filename)
-{
- List *list = 0;
FILE *file = openFile(filename);
yaml_parser_t parser;
yaml_event_t event;
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, file);
+
+ struct idlist *texts = NULL;
+ struct idlist *texts_node = texts;
do {
if (!yaml_parser_parse(&parser, &event)) {
- printf("Parser error %d\n", parser.error);
+ fprintf(stderr, "Parser error %d\n", parser.error);
exit(EXIT_FAILURE);
}
- switch(event.type)
+
+ switch (event.type)
{
- case YAML_MAPPING_START_EVENT:
- List_new(&list);
- break;
- case YAML_SCALAR_EVENT:
- ;yaml_event_t ev;
- yaml_parser_parse(&parser, &ev);
- while (ev.type != YAML_SCALAR_EVENT) {
- yaml_event_delete(&ev);
- if (!yaml_parser_parse(&parser, &ev)) {
- printf("Parser error %d\n", parser.error);
- exit(EXIT_FAILURE);
- }
- }
- KeyMap **keyMap = (KeyMap **)&((List *)List_getLast(&list))->obj;
- KeyMap_put(keyMap, event.data.scalar.value, ev.data.scalar.value);
+ case YAML_MAPPING_START_EVENT:
+ if (!texts) {
+ texts = list_new();
+ texts_node = texts;
+ } else
+ texts_node = list_append(texts);
+ texts_node->obj = calloc(1, sizeof(struct text));
+ break;
+ case YAML_SCALAR_EVENT:
+ ;yaml_event_t ev;
+ yaml_parser_parse(&parser, &ev);
+ while (ev.type != YAML_SCALAR_EVENT) {
yaml_event_delete(&ev);
- break;
- default: break;
+ if (!yaml_parser_parse(&parser, &ev)) {
+ fprintf(stderr, "Parser error %d\n", parser.error);
+ exit(EXIT_FAILURE);
+ }
+ }
+ struct text *text = texts_node->obj;
+ if (!strcmp((char *)event.data.scalar.value, "type")) {
+ text->type = malloc(sizeof(char) * (strlen((char *)ev.data.scalar.value) + 1));
+ strcpy(text->type, (char *)ev.data.scalar.value);
+ } else if (!strcmp((char *)event.data.scalar.value, "scene")) {
+ text->scene = malloc(sizeof(char) * (strlen((char *)ev.data.scalar.value) + 1));
+ strcpy(text->scene, (char *)ev.data.scalar.value);
+ } else if (!strcmp((char *)event.data.scalar.value, "text")) {
+ text->text = malloc(sizeof(char) * (strlen((char *)ev.data.scalar.value) + 1));
+ strcpy(text->text, (char *)ev.data.scalar.value);
+ } else if (!strcmp((char *)event.data.scalar.value, "font")) {
+ text->font = malloc(sizeof(char) * (strlen((char *)ev.data.scalar.value) + 1));
+ strcpy(text->font, (char *)ev.data.scalar.value);
+ } else if (!strcmp((char *)event.data.scalar.value, "size")) {
+ text->size = atoi((char *)ev.data.scalar.value);
+ } else if (!strcmp((char *)event.data.scalar.value, "x")) {
+ text->pos.x = atoi((char *)ev.data.scalar.value);
+ } else if (!strcmp((char *)event.data.scalar.value, "y")) {
+ text->pos.y = atoi((char *)ev.data.scalar.value);
+ }
+ yaml_event_delete(&ev);
+ break;
+ default:
+ break;
}
- if(event.type != YAML_STREAM_END_EVENT)
+
+ if (event.type != YAML_STREAM_END_EVENT)
yaml_event_delete(&event);
- } while(event.type != YAML_STREAM_END_EVENT);
+ } while (event.type != YAML_STREAM_END_EVENT);
+
yaml_event_delete(&event);
yaml_parser_delete(&parser);
fclose(file);
- return list;
-}
-
-void KeyMapOfString_free(KeyMap *keyMap)
-{
- KeyMap *keyMapLocal = KeyMap_getLast(&keyMap);
- while (keyMapLocal) {
- free(keyMapLocal->pair->k);
- free(keyMapLocal->pair->v);
- free(keyMapLocal->pair);
- KeyMap *prev = keyMapLocal->prev;
- free(keyMapLocal);
- keyMapLocal = prev;
- }
-}
-
-void ListOfKeyMapOfString_free(List **list)
-{
- List *listLocal = List_getLast(list);
- while (listLocal) {
- KeyMapOfString_free(listLocal->obj);
- List *prev = listLocal->prev;
- free(listLocal);
- listLocal = prev;
- }
- *list = 0;
-}
-
-static int _loadText_getInt(void *obj, char *key)
-{
- int v = 0;
- KeyMap *keyMap = KeyMap_get((KeyMap **)&obj, key);
- if (keyMap)
- if (keyMap->pair)
- if (keyMap->pair->v)
- v = atoi(keyMap->pair->v);
- return v;
+ return texts;
}
-static char *_loadText_getString(void *obj, char *key)
+void text_destroy(void *obj)
{
- char *v = 0;
- KeyMap *keyMap = KeyMap_get((KeyMap **)&obj, key);
- if (keyMap)
- if (keyMap->pair)
- if (keyMap->pair->v) {
- v = malloc(strlen(keyMap->pair->v)+1);
- strcpy(v, keyMap->pair->v);
- }
- return v;
-}
-
-static void _loadText_initSfText(Text *objo, void *obji)
-{
- sfVector2f pos = {
- .x = _loadText_getInt(obji, "x"),
- .y = _loadText_getInt(obji, "y")
- };
- int size = _loadText_getInt(obji, "size");
- char *text = _loadText_getString(obji, "text");
- objo->sfText = sfText_create();
- sfText_setFont(objo->sfText, fontScore);
- sfText_setCharacterSize(objo->sfText, size);
- sfText_setPosition(objo->sfText, pos);
- sfText_setString(objo->sfText, text);
+ struct text *text = obj;
+ if (text->type)
+ free(text->type);
+ if (text->scene)
+ free(text->scene);
+ if (text->text)
+ free(text->text);
+ if (text->font)
+ free(text->font);
free(text);
}
-
-List *ListOfText_getFromListOfKeyMapOfString(List *list)
-{
- List *li = list;
- List *lo = 0;
- List *l = 0;
- while (li) {
- List_new(&lo);
- l = List_getLast(&lo);
- l->obj = malloc(sizeof(Text));
- ((Text *)l->obj)->type = _loadText_getString(li->obj, "type");
- ((Text *)l->obj)->font = _loadText_getString(li->obj, "font");
- ((Text *)l->obj)->scene = _loadText_getString(li->obj, "scene");
- ((Text *)l->obj)->text = _loadText_getString(li->obj, "text");
- _loadText_initSfText(l->obj, li->obj);
- li = li->next;
- }
- return lo;
-}
-
-void Text_free(Text *obj)
-{
- free(obj->type);
- free(obj->scene);
- free(obj->text);
- free(obj->font);
- sfText_destroy(obj->sfText);
- free(obj);
-}
-
-void ListOfText_free(List **list)
-{
- List *listLocal = List_getLast(list);
- while (listLocal) {
- Text_free(listLocal->obj);
- List *prev = listLocal->prev;
- free(listLocal);
- listLocal = prev;
- }
- *list = 0;
-}