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..df7f9e3 --- /dev/null +++ b/src/events.c @@ -0,0 +1,100 @@ +#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 +}; + +char _message_buffer[MESSAGE_BUFFER_SZ]; +char *events_parse_string(EventHandler *handler, char *message) { + char *message_ptr = _message_buffer; + char in_op = message[0] == '`'; + char *token; + int *var; + unsigned int n, i; + size_t len; + char *sign; + size_t left; + size_t size; + if(!strlen(message)) return message; + for(token=strtok(message,"`");token!=NULL;in_op=!in_op, + token=strtok(NULL,"`")){ + len = strlen(token); + if(in_op && len){ + sign = NULL; + for(n=0;sign==NULL&&nvars;i++){ + if(!strncmp(token+1, handler->var_names[i], sign-token-1)){ + var = handler->variables[i]; + break; + } + } + if(var){ + *var = _operations[n](*var, atoi(sign+1)); + } + } + }else{ + left = (_message_buffer+MESSAGE_BUFFER_SZ)-message_ptr; + size = len < left ? len : left; + memcpy(message_ptr, token, size); + message_ptr += size; + } + } + *message_ptr = '\0'; + return _message_buffer; +} diff --git a/src/events.h b/src/events.h new file mode 100644 index 0000000..91f1923 --- /dev/null +++ b/src/events.h @@ -0,0 +1,35 @@ +#ifndef EVENTS_H +#define EVENTS_H + +#define MAX_VARIABLES 32 +#define MESSAGE_BUFFER_SZ 256 +#define TOKEN_MAX_SZ 32 + +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);