Merge pull request 'Gestion des événements.' (#41) from events into master

Reviewed-on: https://git.planet-casio.com/Slyvtt/Collab_RPG/pulls/41
This commit is contained in:
mibi88 2024-07-20 17:52:45 +02:00
commit 841d9621a0
7 changed files with 175 additions and 10 deletions

View file

@ -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

View file

@ -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;

123
src/events.c Normal file
View file

@ -0,0 +1,123 @@
#include <stdlib.h>
#include <string.h>
#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;i<strlen(message);i++){
c = message[i];
if(c == '`'){
in_token = !in_token;
if(!in_token){
if(tok_type == T_VAR_EDIT){
/* Do the calculation */
var_name[MIN(name_pos, TOKEN_MAX_SZ)] = '\0';
num[MIN(num_pos, TOKEN_MAX_SZ)] = '\0';
for(n=0;n<handler->vars;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;
}

35
src/events.h Normal file
View file

@ -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

View file

@ -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 */

View file

@ -5,6 +5,8 @@
#include <gint/display.h>
#include <stdint.h>
#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. */

View file

@ -8,6 +8,7 @@
#include "config.h"
#include "npc.h"
#include "events.h"
#if USB_FEATURE
#include <gint/usb-ff-bulk.h>
@ -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);