From e150d54ca90a8d1cc99ce4d1b8285f5ea971e279 Mon Sep 17 00:00:00 2001 From: Oxore Date: Sat, 2 Dec 2017 09:57:42 +0300 Subject: Yaml loader for text resources added, need to be involved --- Makefile | 1 + dat/ya.yaml | 36 ++++++++ include/common.h | 27 +++++- include/text.h | 20 +++++ src/functions.c | 4 +- src/main.c | 61 +++++++------ src/text.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 371 insertions(+), 37 deletions(-) create mode 100644 dat/ya.yaml create mode 100644 include/text.h create mode 100644 src/text.c diff --git a/Makefile b/Makefile index b8b76ba..7277eee 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ CFLAGS+=-I$(INCLUDE) LIBS+=-lcsfml-graphics LIBS+=-lcsfml-window LIBS+=-lcsfml-system +LIBS+=-lyaml BUILD:=build SRC:=src diff --git a/dat/ya.yaml b/dat/ya.yaml new file mode 100644 index 0000000..b6882ce --- /dev/null +++ b/dat/ya.yaml @@ -0,0 +1,36 @@ +--- +- + type: "score" + scene: "game" + text: "Score: " + font: "Arial" + size: 20 + x: 270 + y: 10 + +- + type: "level" + scene: "game" + text: "Level: " + font: "Arial" + size: 20 + x: 270 + y: 44 + +- + type: + scene: "menu" + text: "TETRIS" + font: "Arial" + size: 36 + x: 290 + y: 100 + +- + type: "" + scene: "menu" + text: "Press \"S\" to start" + font: "Arial" + size: 36 + x: 266 + y: 200 diff --git a/include/common.h b/include/common.h index 5f64a2b..136edaa 100644 --- a/include/common.h +++ b/include/common.h @@ -61,10 +61,31 @@ typedef struct Game { int level; } 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 { - sfFont *font; - sfText *text; - sfVector2f pos; + char *font; + char *type; + char *scene; + char *text; + void *sfText; } Text; #endif diff --git a/include/text.h b/include/text.h new file mode 100644 index 0000000..7948c51 --- /dev/null +++ b/include/text.h @@ -0,0 +1,20 @@ +#include +#include "common.h" + +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); diff --git a/src/functions.c b/src/functions.c index 4fca5c8..ee0566d 100644 --- a/src/functions.c +++ b/src/functions.c @@ -75,7 +75,7 @@ void scoreDisplay(int s, Text *textScore) { char a[64]; sprintf(a, "Score: %d", s); - sfText_setString(textScore->text, (char *)&a); + sfText_setString(textScore->sfText, (char *)&a); } @@ -83,7 +83,7 @@ void levelDisplay(int s, Text *textLevel) { char a[64]; sprintf(a, "Level: %d", s); - sfText_setString(textLevel->text, (char *)&a); + sfText_setString(textLevel->sfText, (char *)&a); } diff --git a/src/main.c b/src/main.c index f719c9e..739c4e7 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,11 @@ #include "common.h" #include "functions.h" +#include "text.h" /* --- Variables --- */ Window w = {.mode = {450, 520, 32}}; Game game = {.isStarted = 0, .scoreCurrent = 0, .level = 1}; +List *texts; Text menu1; Text menu2; Text score; @@ -45,37 +47,32 @@ void prepare() { initFld(); - score.pos = (sfVector2f){.x = 250+10+10, .y = 10}; - score.text = sfText_create(); - sfText_setFont(score.text, fontScore); - sfText_setCharacterSize(score.text, 20); - sfText_setPosition(score.text, score.pos); + texts = ListOfText_getFromListOfKeyMapOfString(ListOfKeyMapOfString_getFromYaml("dat/ya.yaml")); + score.sfText = sfText_create(); + sfText_setFont(score.sfText, fontScore); + sfText_setCharacterSize(score.sfText, 20); + sfText_setPosition(score.sfText, (sfVector2f){.x = 250+10+10, .y = 10}); - level.pos = (sfVector2f){.x = 250+10+10, .y = 44}; - level.text = sfText_create(); - sfText_setFont(level.text, fontScore); - sfText_setCharacterSize(level.text, 20); - sfText_setPosition(level.text, level.pos); + level.sfText = sfText_create(); + sfText_setFont(level.sfText, fontScore); + sfText_setCharacterSize(level.sfText, 20); + sfText_setPosition(level.sfText, (sfVector2f){.x = 250+10+10, .y = 44}); /* * Menu texts * */ - menu1.pos.x = 10+250+30; - menu1.pos.y = 100; - menu1.text = sfText_create(); - sfText_setFont(menu1.text, fontScore); - sfText_setCharacterSize(menu1.text, 36); - sfText_setPosition(menu1.text, menu1.pos); - sfText_setString(menu1.text, "TETRIS"); - - menu2.pos.x = 10+250+16; - menu2.pos.y = 200; - menu2.text = sfText_create(); - sfText_setFont(menu2.text, fontScore); - sfText_setCharacterSize(menu2.text, 20); - sfText_setPosition(menu2.text, menu2.pos); - sfText_setString(menu2.text, "Press \"S\" to start"); + menu1.sfText = sfText_create(); + sfText_setFont(menu1.sfText, fontScore); + sfText_setCharacterSize(menu1.sfText, 36); + sfText_setPosition(menu1.sfText, (sfVector2f){.x = 250+10+30, .y = 100}); + sfText_setString(menu1.sfText, "TETRIS"); + + menu2.sfText = sfText_create(); + sfText_setFont(menu2.sfText, fontScore); + sfText_setCharacterSize(menu2.sfText, 20); + sfText_setPosition(menu2.sfText, (sfVector2f){.x = 250+10+16, .y = 200}); + sfText_setString(menu2.sfText, "Press \"S\" to start"); w.window = sfRenderWindow_create(w.mode, windowName_conf, @@ -100,8 +97,8 @@ void gameLoop() { colorizeActive(); drawFld(w.window); drawNextShape(w.window); - sfRenderWindow_drawText(w.window, score.text, NULL); - sfRenderWindow_drawText(w.window, level.text, NULL); + sfRenderWindow_drawText(w.window, score.sfText, NULL); + sfRenderWindow_drawText(w.window, level.sfText, NULL); } void menuTick() @@ -115,8 +112,8 @@ void menuTick() void menuLoop() { menuTick(); drawFld(w.window); - sfRenderWindow_drawText(w.window, menu1.text, NULL); - sfRenderWindow_drawText(w.window, menu2.text, NULL); + sfRenderWindow_drawText(w.window, menu1.sfText, NULL); + sfRenderWindow_drawText(w.window, menu2.sfText, NULL); if (sfKeyboard_isKeyPressed(sfKeyS) == 1) { game.isStarted = 1; freeFld(); @@ -146,9 +143,9 @@ int main() printf("%d\n", game.scoreCurrent); freeFld(); sfRenderWindow_destroy(w.window); - sfText_destroy(score.text); - sfText_destroy(menu1.text); - sfText_destroy(menu2.text); + sfText_destroy(score.sfText); + sfText_destroy(menu1.sfText); + sfText_destroy(menu2.sfText); return EXIT_SUCCESS; } diff --git a/src/text.c b/src/text.c new file mode 100644 index 0000000..c922f34 --- /dev/null +++ b/src/text.c @@ -0,0 +1,259 @@ +#include +#include +#include +#include +#include + +#include "text.h" + +extern sfFont *fontScore; + +FILE *openFile(char *filename) +{ + FILE *file; + if (!(file = fopen(filename, "rb"))){ + printf("ERROR\n"); + 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) +{ + 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); + } + 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); + do { + if (!yaml_parser_parse(&parser, &event)) { + printf("Parser error %d\n", parser.error); + exit(EXIT_FAILURE); + } + 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); + yaml_event_delete(&ev); + break; + default: break; + } + if(event.type != YAML_STREAM_END_EVENT) + yaml_event_delete(&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; +} + +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; +} + +char *_loadText_getString(void *obj, char *key) +{ + 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; +} + +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); + 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; +} -- cgit v1.2.3