diff --git a/CMakeLists.txt b/CMakeLists.txt index 65291bf..adfe756 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ set(SOURCES src/game.c src/dialogs.c src/npc.c + src/events.c # ... ) # Shared assets, fx-9860G-only assets and fx-CG-50-only assets diff --git a/src/dialogs.c b/src/dialogs.c index 4757303..cdb5ce5 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -8,6 +8,7 @@ #include "config.h" #include "game.h" #include "npc.h" +#include "events.h" #define BOX_HEIGHT (F_HEIGHT/PXSIZE+8) @@ -55,6 +56,7 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text, void for_each_screen(Game *game, unsigned int i), int line_duration, bool update_screen, unsigned int start_i, bool wait_continue) { + text = events_parse_string(&game->handler, text); dfont(&FONT_USED); unsigned int i, n, y = PXSIZE, l = 0; int line_max_chars, return_int = 0; diff --git a/src/events.c b/src/events.c new file mode 100644 index 0000000..aee4472 --- /dev/null +++ b/src/events.c @@ -0,0 +1,123 @@ +#include +#include +#include "events.h" + +void events_init_handler(EventHandler *handler) { + handler->vars = 0; +} + +int events_bind_variable(EventHandler *handler, int *var, char *name) { + if(handler->vars < MAX_VARIABLES){ + handler->variables[handler->vars] = var; + handler->var_names[handler->vars++] = name; + }else{ + return 1; + } + return 0; +} + +char op_chars[OP_AMOUNT+1] = " =+-/*%"; + +int _op_null(int a, int b) { + return 0; +} + +int _op_set(int a, int b) { + return b; +} + +int _op_add(int a, int b) { + return a+b; +} + +int _op_sub(int a, int b) { + return a-b; +} + +int _op_div(int a, int b) { + if(b == 0) return 0; + return a/b; +} + +int _op_mul(int a, int b) { + return a*b; +} + +int _op_mod(int a, int b) { + if(b == 0) return 0; + return a%b; +} + +int (*_operations[OP_AMOUNT])(int, int) = { + _op_null, + _op_set, + _op_add, + _op_sub, + _op_div, + _op_mul, + _op_mod +}; + +#define MIN(a, b) a < b ? a : b + +char _message_buffer[MESSAGE_BUFFER_SZ]; +char *events_parse_string(EventHandler *handler, char *message) { + size_t message_pos = 0; + char in_token = 0; + char var_name[TOKEN_MAX_SZ]; + size_t name_pos = 0; + Operation var_op = OP_NULL; + char num[TOKEN_MAX_SZ]; + size_t num_pos = 0; + Token tok_type = T_NULL; + char c; + size_t i, n; + int *var; + for(i=0;ivars;n++){ + if(!strcmp(var_name, handler->var_names[n])){ + var = handler->variables[n]; + if(var_op){ + *var = _operations[var_op](*var, atoi(num)); + } + break; + } + } + } + /* Reset everything */ + tok_type = T_NULL; + name_pos = 0; + var_op = OP_NULL; + num_pos = 0; + } + }else if(!in_token){ + if(message_pos < TOKEN_MAX_SZ) _message_buffer[message_pos++] = c; + } + if(in_token && c != ' '){ + if(tok_type == T_VAR_EDIT){ + if(var_op != OP_NULL){ + if(num_pos < TOKEN_MAX_SZ) num[num_pos++] = c; + } + if(strchr(op_chars, c)){ + var_op = (Operation)(strchr(op_chars, c)-op_chars); + } + if(var_op == OP_NULL){ + if(name_pos < TOKEN_MAX_SZ) var_name[name_pos++] = c; + } + } + if(c == '$'){ + tok_type = T_VAR_EDIT; + } + } + } + _message_buffer[MIN(message_pos, MESSAGE_BUFFER_SZ)] = '\0'; + return _message_buffer; +} diff --git a/src/events.h b/src/events.h new file mode 100644 index 0000000..f43fecf --- /dev/null +++ b/src/events.h @@ -0,0 +1,35 @@ +#ifndef EVENTS_H +#define EVENTS_H + +#define MAX_VARIABLES 32 +#define MESSAGE_BUFFER_SZ 1024 +#define TOKEN_MAX_SZ 1024 + +typedef struct { + int *variables[MAX_VARIABLES]; + char *var_names[MAX_VARIABLES]; + unsigned int vars; +} EventHandler; + +typedef enum { + T_NULL, + T_VAR_EDIT, + T_AMOUNT +} Token; + +typedef enum { + OP_NULL, + OP_SET, + OP_ADD, + OP_SUB, + OP_DIV, + OP_MUL, + OP_MOD, + OP_AMOUNT +} Operation; + +void events_init_handler(EventHandler *handler); +int events_bind_variable(EventHandler *handler, int *var, char *name); +char *events_parse_string(EventHandler *handler, char *message); + +#endif diff --git a/src/game.c b/src/game.c index 899dbc4..135c336 100644 --- a/src/game.c +++ b/src/game.c @@ -98,6 +98,8 @@ void draw(Game *game) { player_draw(game); render_map_by_layer(game, FOREGROUND); render_indicator( game ); + dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life); + dprint(8, 16, C_BLACK, "Mana: %d", game->mana); } /* Key management */ diff --git a/src/game.h b/src/game.h index 8d24797..d1cd86e 100644 --- a/src/game.h +++ b/src/game.h @@ -5,6 +5,8 @@ #include #include +#include "events.h" + /* The direction where the player is going to. */ @@ -130,7 +132,8 @@ typedef struct { * the world. */ typedef struct { Map *map_level; /* The level that the player is currently playing */ - Player player; /* The player data (see player.h). */ + Player player; /* The player data. */ + EventHandler handler; /* The event handler (see events.h). */ /* Some global variables */ /* Set to true when asked for exit */ bool exittoOS; @@ -145,6 +148,8 @@ typedef struct { bool debug_map; bool debug_player; bool debug_extra; + + int mana; /* Only for testing events TODO: Remove this! */ } Game; /* (Mibi88) TODO: Describe what this function is doing. */ diff --git a/src/main.c b/src/main.c index 0375212..86ccd61 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include "config.h" #include "npc.h" +#include "events.h" #if USB_FEATURE #include @@ -36,10 +37,11 @@ extern Map *worldRPG[]; Game game = { NULL, {12*PXSIZE, 36*PXSIZE, 0, 0, 12*PXSIZE, 36*PXSIZE, 100, SPEED, false, 0, false, false}, + {{}, {}, 0}, false, false, false, 0 /* debug variables*/ - , false, false, false + , false, false, false, 100 }; /* screen capture management code */ @@ -100,6 +102,9 @@ int main(void) { timer_start(timer); game.map_level = worldRPG[0]; + events_init_handler(&game.handler); + events_bind_variable(&game.handler, (int*)&game.player.life, "life"); + events_bind_variable(&game.handler, &game.mana, "mana"); reload_npc(&game); @@ -115,14 +120,6 @@ int main(void) { dgray(DGRAY_ON); #endif -/* - showtext_dialog(&game, &player_face_img, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet.", true, true); - int in = showtext_dialog_ask(&game, &player_face_img, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet.", true, false, "Lorem\0Ipsum\0Dolor", 3, 0); - if(in==2) showtext_dialog(&game, &player_face_img, "You choosed Dolor", false, true); - else if(in==1) showtext_dialog(&game, &player_face_img, "You choosed Ipsum", false, true); - else showtext_dialog(&game, &player_face_img, "You choosed Lorem", false, true); -*/ - do{ /* clear screen */ dclear(C_WHITE);