diff options
author | Oxore <oxore@protonmail.com> | 2018-07-09 01:06:04 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2018-07-09 01:06:04 +0300 |
commit | 73ec96ee907f0a8ebdeec20f2058de705b00d65d (patch) | |
tree | 144d4558a6cf91948e2946194406c2268ae6bb7c /src/painter.c | |
parent | 45ebf081cbf623bc258d20f38b68ed6c334316d3 (diff) |
Finish painter, refactor game logic & keys handling
Add dependencies in Makefile: now it tracks headers too!
Introduce texts in painter. Delegate all the window painting to the
painter.
Refactor texts from yaml parsing. Remove overcomplicated keymaps and
lists of keymaps of... Whatever! Just let em go! Simple idlist with
foreach is more than enough.
Make displayable values be separate text objects which consists only of
a number value that rendered every tick and then displayed.
Refactor game logic: make state machine look much obvious with
transition functions.
Refactor long if-else and switch-case statement chains: replace them
with arrays of values (it actually takes more lines of code :P)
Refactor keys handling: shorten and separate shape moving code to
functions.
Diffstat (limited to 'src/painter.c')
-rw-r--r-- | src/painter.c | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/src/painter.c b/src/painter.c new file mode 100644 index 0000000..9f6b911 --- /dev/null +++ b/src/painter.c @@ -0,0 +1,274 @@ +#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 "painter.h" + +#include "idlist.h" + +static sfColor shape_color_map[] = { + UIBGCOLOR, + LCOLOR, + RLCOLOR, + ZCOLOR, + SCOLOR, + BCOLOR, + ICOLOR, + 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 text_drawable { + struct drawable; + + sfText *text; + unsigned long attr; +}; + +static sfRenderWindow *window; +static sfFont *font; + +static struct idlist *drawables = NULL; + +void painter_set_window(sfRenderWindow *w) +{ + window = w; +} + +void painter_load_font(char *filename) +{ + 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 (!drawables) + last = drawables = list_new(); + else + 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++) { + 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_setPosition(f->p[j][i], cell_pos); + 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; +} + +void painter_update_field(unsigned long id, struct field *fld) +{ + struct idlist *node = list_get(drawables, id); + if (!node) + return; + struct field_drawable *f = node->obj; + 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); + } + } + } + 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_drawable(struct drawable *d) +{ + 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(window, f->p[j][i], NULL); +} + +static void destroy_field_drawable(struct drawable *d) +{ + 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]); + free(f->p[j]); + } + free(f->p); + free(f); +} + +unsigned long painter_register_text(struct text *txt) +{ + 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_update_text(unsigned long id, struct text *txt) +{ + 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() +{ + 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() +{ + list_foreach(drawables, destroy_drawable); + list_destroy(drawables); + drawables = 0; +} + +void painter_destroy_all() +{ + painter_destroy_drawables(); + painter_destroy_font(); + window = 0; +} |