diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..bf85b5a --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +PointerAlignment: Right +SpaceBeforeParens: Custom +SpaceBeforeParensOptions: + AfterControlStatements: false + diff --git a/src/config.h b/src/config.h index a899255..83dbca1 100644 --- a/src/config.h +++ b/src/config.h @@ -1,7 +1,6 @@ #ifndef CONFIG_H #define CONFIG_H - #define USB_FEATURE 0 #define DEBUGMODE 0 @@ -9,48 +8,45 @@ /* Enable GrayMode on either FX and FX_G3A targets */ #if GINT_RENDER_MONO && defined(COLOR2BIT) - #define GRAYMODEOK 1 +#define GRAYMODEOK 1 #endif - - #if GINT_RENDER_RGB - /* The tile size */ - #define T_HEIGHT 16 - #define T_WIDTH 16 - /* The size of a pixel */ - #define PXSIZE 2 - #define PATH_COLOR C_RED - /* The size of the player */ - #define P_WIDTH 16 - #define P_HEIGHT 16 +/* The tile size */ +#define T_HEIGHT 16 +#define T_WIDTH 16 +/* The size of a pixel */ +#define PXSIZE 2 +#define PATH_COLOR C_RED +/* The size of the player */ +#define P_WIDTH 16 +#define P_HEIGHT 16 #else - /* The tile size */ - #define T_HEIGHT 8 - #define T_WIDTH 8 - /* The pixel size */ - #define PXSIZE 1 - #define PATH_COLOR C_BLACK - /* The player size */ - #define P_WIDTH 8 - #define P_HEIGHT 8 +/* The tile size */ +#define T_HEIGHT 8 +#define T_WIDTH 8 +/* The pixel size */ +#define PXSIZE 1 +#define PATH_COLOR C_BLACK +/* The player size */ +#define P_WIDTH 8 +#define P_HEIGHT 8 #endif - /* SPEED should NOT be 8 or bigger: it may cause bugs when handling * collisions! */ -#define SPEED (PXSIZE*2) +#define SPEED (PXSIZE * 2) /* The face size (in the dialogs) */ -#define F_WIDTH (32*PXSIZE) -#define F_HEIGHT (32*PXSIZE) +#define F_WIDTH (32 * PXSIZE) +#define F_HEIGHT (32 * PXSIZE) /* the color of the text to go to the next dialog phase */ /* it improves readability to have something lighter */ #if GRAYMODEOK || (GINT_RENDER_RGB && !defined(COLOR1BIT)) - #define NEXT_COLOR C_DARK +#define NEXT_COLOR C_DARK #else - #define NEXT_COLOR C_BLACK +#define NEXT_COLOR C_BLACK #endif #endif diff --git a/src/dialogs.c b/src/dialogs.c index dff74ad..657e940 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -1,197 +1,210 @@ #include "dialogs.h" -#include #include +#include #include #include "config.h" +#include "events.h" #include "game.h" #include "npc.h" -#include "events.h" - -#define BOX_HEIGHT (F_HEIGHT/PXSIZE+8) +#define BOX_HEIGHT (F_HEIGHT / PXSIZE + 8) #define CHOICE_BOX_HEIGHT 10 #define CHOICE_BOX_PADDING_TOP 3 - extern font_t fontRPG; #define FONT_USED fontRPG #if GRAYMODEOK - #include - uint32_t *lightVRAMnext, *darkVRAMnext; - uint32_t *lightVRAMcurrent, *darkVRAMcurrent; -#endif //GRAYMODEOK - +#include +uint32_t *lightVRAMnext, *darkVRAMnext; +uint32_t *lightVRAMcurrent, *darkVRAMcurrent; +#endif // GRAYMODEOK void blit() { - dupdate(); - - #if GRAYMODEOK && !GINT_HW_CG - dgray_getvram( &lightVRAMnext, &darkVRAMnext ); - dgray_getscreen( &lightVRAMcurrent, &darkVRAMcurrent ); - - memcpy( lightVRAMnext, lightVRAMcurrent, 256*sizeof( uint32_t) ); - memcpy( darkVRAMnext, darkVRAMcurrent, 256*sizeof( uint32_t) ); - #endif -} + dupdate(); +#if GRAYMODEOK && !GINT_HW_CG + dgray_getvram(&lightVRAMnext, &darkVRAMnext); + dgray_getscreen(&lightVRAMcurrent, &darkVRAMcurrent); + + memcpy(lightVRAMnext, lightVRAMcurrent, 256 * sizeof(uint32_t)); + memcpy(darkVRAMnext, darkVRAMcurrent, 256 * sizeof(uint32_t)); +#endif +} int dialogs_text_opt(Game *game, bopti_image_t *face, char *text, int call_before_end(Game *game, unsigned int i), - bool start_anim, - bool end_anim, + bool start_anim, bool end_anim, void for_each_screen(Game *game, unsigned int i), - int line_duration, bool update_screen, unsigned int start_i, - bool wait_continue) { + 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; - unsigned int max_lines_amount = (BOX_HEIGHT-2)*PXSIZE/ - (FONT_USED.line_height+PXSIZE); + unsigned int max_lines_amount = + (BOX_HEIGHT - 2) * PXSIZE / (FONT_USED.line_height + PXSIZE); const char *c; - if(start_anim){ + if(start_anim) { /* Run a little fancy animation. */ - for(i=0;i<=BOX_HEIGHT;i++){ + for(i = 0; i <= BOX_HEIGHT; i++) { /* Redrawing the entire screen, because maybe there was no dialog displayed before. */ update_npcs(game); game_draw(game); /* Fill the dialog box with white */ - drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE); + drect(0, 0, DWIDTH, i * PXSIZE, C_WHITE); /* Draw a thick black line on the bottom of the dialog. */ - drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK); + drect(0, i * PXSIZE, DWIDTH, (i + 1) * PXSIZE, C_BLACK); /* Draw the part of the face of the player that can fit correctly in * the dialog drawn. */ - dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE, - DIMAGE_NONE); + dsubimage(4 * PXSIZE, 2 * PXSIZE, face, 0, 0, F_WIDTH, + (i - 8) * PXSIZE, DIMAGE_NONE); blit(); - while(game->frame_duration < 20) sleep(); + while(game->frame_duration < 20) + sleep(); game->frame_duration = 0; } - }else{ + } else { /* Here I'm drawing the same as if start_anim is true, but whitout * making an animation. */ game_draw(game); - drect(0, 0, DWIDTH, BOX_HEIGHT*PXSIZE, C_WHITE); - drect(0, BOX_HEIGHT*PXSIZE, DWIDTH, (BOX_HEIGHT+1)*PXSIZE, C_BLACK); - dimage(4*PXSIZE, 2*PXSIZE, face); + drect(0, 0, DWIDTH, BOX_HEIGHT * PXSIZE, C_WHITE); + drect(0, BOX_HEIGHT * PXSIZE, DWIDTH, (BOX_HEIGHT + 1) * PXSIZE, + C_BLACK); + dimage(4 * PXSIZE, 2 * PXSIZE, face); - if(update_screen){ + if(update_screen) { blit(); - while(game->frame_duration < 20) sleep(); + while(game->frame_duration < 20) + sleep(); game->frame_duration = 0; } } /* We should start to drawing the text on the x axis at BOX_HEIGHT to avoid * drawing on the face. */ - for(i=start_i;i0; n--) { + for(n = line_max_chars; n > 0; n--) { /* If we found a space, we can draw this line and do the same - * for the next line. */ - if(text[i+n] == ' '){ - dtext_opt(BOX_HEIGHT*PXSIZE, y, C_BLACK, C_NONE, DTEXT_LEFT, - DTEXT_TOP, text+i, n); /* Draw everything. */ + * for the next line. */ + if(text[i + n] == ' ') { + dtext_opt(BOX_HEIGHT * PXSIZE, y, C_BLACK, C_NONE, + DTEXT_LEFT, DTEXT_TOP, text + i, + n); /* Draw everything. */ /* Increment y by the line height. */ - y += FONT_USED.line_height+PXSIZE; + y += FONT_USED.line_height + PXSIZE; i += n; /* We drew everything to i+n */ - l++; /* We drew one more line. */ + l++; /* We drew one more line. */ break; } } - }else{ + } else { /* If it is the last line of the text. */ - dtext_opt(BOX_HEIGHT*PXSIZE, y, C_BLACK, C_NONE, DTEXT_LEFT, - DTEXT_TOP, text+i, line_max_chars); - y += FONT_USED.line_height+PXSIZE; + dtext_opt(BOX_HEIGHT * PXSIZE, y, C_BLACK, C_NONE, DTEXT_LEFT, + DTEXT_TOP, text + i, line_max_chars); + y += FONT_USED.line_height + PXSIZE; i += line_max_chars; l++; } - if(l>=max_lines_amount-1){ + if(l >= max_lines_amount - 1) { /* We drew one entire screen, reset everything to draw the next one. */ /* Make a little animation :). */ - if(update_screen) blit(); - while(game->frame_duration < line_duration) sleep(); + if(update_screen) + blit(); + while(game->frame_duration < line_duration) + sleep(); game->frame_duration = 0; /* Ask the user to press SHIFT to continue. */ - dtext(BOX_HEIGHT*PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite..."); + dtext(BOX_HEIGHT * PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite..."); } /* Make a little animation :). */ - if(update_screen) blit(); - if(l>=max_lines_amount-1){ + if(update_screen) + blit(); + if(l >= max_lines_amount - 1) { /* If we drew one entire screen. */ /* Wait that the SHIFT key is pressed if we should. */ - if(wait_continue){ + if(wait_continue) { while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & - ~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){ + ~GETKEY_MOD_ALPHA, + NULL) + .key != KEY_SHIFT) { sleep(); } } /* Clear the text area. */ - drect(BOX_HEIGHT*PXSIZE, 0, DWIDTH, (BOX_HEIGHT-1)*PXSIZE-2, + drect(BOX_HEIGHT * PXSIZE, 0, DWIDTH, (BOX_HEIGHT - 1) * PXSIZE - 2, C_WHITE); /* Reset y and l. */ y = PXSIZE; l = 0; - } - else{ + } else { /* Else, wait a bit for the animation. */ - while(game->frame_duration < line_duration) sleep(); + while(game->frame_duration < line_duration) + sleep(); game->frame_duration = 0; } } - if(lframe_duration < line_duration) sleep(); + if(update_screen) + blit(); + while(game->frame_duration < line_duration) + sleep(); game->frame_duration = 0; /* Ask the user to press SHIFT to continue. */ - dtext(BOX_HEIGHT*PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite..."); + dtext(BOX_HEIGHT * PXSIZE, y, NEXT_COLOR, "[SHIFT] : suite..."); /* Update the screen and wait for SHIFT being pressed, if needed. */ - if(update_screen) blit(); - if(wait_continue){ + if(update_screen) + blit(); + if(wait_continue) { while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & - ~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){ + ~GETKEY_MOD_ALPHA, + NULL) + .key != KEY_SHIFT) { sleep(); } } } - if(call_before_end) return_int = call_before_end(game, i); - if(end_anim){ + if(call_before_end) + return_int = call_before_end(game, i); + if(end_anim) { /* Run another little fancy animation if we should. */ - for(i=BOX_HEIGHT;i>0;i--){ + for(i = BOX_HEIGHT; i > 0; i--) { /* It is the same as the start animation. */ update_npcs(game); game_draw(game); - drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE); - drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK); - dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE, - DIMAGE_NONE); + drect(0, 0, DWIDTH, i * PXSIZE, C_WHITE); + drect(0, i * PXSIZE, DWIDTH, (i + 1) * PXSIZE, C_BLACK); + dsubimage(4 * PXSIZE, 2 * PXSIZE, face, 0, 0, F_WIDTH, + (i - 8) * PXSIZE, DIMAGE_NONE); dupdate(); - while(game->frame_duration < 20) sleep(); + while(game->frame_duration < 20) + sleep(); game->frame_duration = 0; } } @@ -202,11 +215,10 @@ void dialogs_text(Game *game, bopti_image_t *face, char *text, bool dialog_start, bool dialog_end) { /* Run showtext_opt with some default values. It makes it easier to use in * simple dialogs. */ - dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100, - true, 0, true); + dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, + 100, true, 0, true); } - /* Some variables and pointers used to get some arguments passed in * showtext_dialog_ask in _choice_call_before_end. */ char *_choices, *_text; @@ -216,31 +228,33 @@ unsigned int _i; /* Get where I started drawing a dialog page, to be able to redraw the last page * for the end animation in _choice_call_before_end. */ -void _choice_screen_call( [[maybe_unused]] Game *game, unsigned int i) { +void _choice_screen_call([[maybe_unused]] Game *game, unsigned int i) { _i = i; } int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) { int i, key; /* Make a little animation because we looove little animations ;) */ - for(i=0;iframe_duration < 20) sleep(); + while(game->frame_duration < 20) + sleep(); game->frame_duration = 0; } /* Calculate the maximal size of a choice. */ - const int choice_size = DWIDTH/_choices_amount; + const int choice_size = DWIDTH / _choices_amount; /* arrow_width: The space taken by the arrow that shows the selected item. * arrow_height: The height of the arrow used to show which item is choosen. * Used to calculate the size of the rectangle used to remove @@ -256,65 +270,70 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) { dsize(">", &FONT_USED, &arrow_width, &arrow_height); /* Add the character spacing of the font to it. */ arrow_width += FONT_USED.char_spacing; - for(i=0;i<_choices_amount;i++){ - dtext(i*choice_size+arrow_width+PXSIZE, - (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, C_BLACK, - _choices+pos); - pos += strlen(_choices+pos)+1; + for(i = 0; i < _choices_amount; i++) { + dtext(i * choice_size + arrow_width + PXSIZE, + (BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE, C_BLACK, + _choices + pos); + pos += strlen(_choices + pos) + 1; } - do{ + do { /* Display the diffrent choices. */ - for(i=0;i<_choices_amount;i++){ - if(i == selected) dtext(i*choice_size+PXSIZE, - (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, - C_BLACK, ">"); + for(i = 0; i < _choices_amount; i++) { + if(i == selected) + dtext(i * choice_size + PXSIZE, + (BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE, C_BLACK, + ">"); } blit(); - key = getkey_opt( GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA, NULL).key; + key = getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA, + NULL) + .key; /* If the player pressed the left arrow key and has not already selected * the first possible choice. */ - if(key == KEY_LEFT && selected > 0){ + if(key == KEY_LEFT && selected > 0) { /* Remove the old arrow. */ - drect(selected*choice_size+PXSIZE, - (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, - selected*choice_size+PXSIZE+arrow_width, - (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE+arrow_height, + drect(selected * choice_size + PXSIZE, + (BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE, + selected * choice_size + PXSIZE + arrow_width, + (BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE + arrow_height, C_WHITE); - + /* Move the selection arrow and update the selected item. */ selected--; } /* If the player pressed the right arrow key and has not already * selected the last possible choice. */ - else if(key == KEY_RIGHT && selected < _choices_amount-1){ + else if(key == KEY_RIGHT && selected < _choices_amount - 1) { /* Remove the old arrow. */ - drect(selected*choice_size+PXSIZE, - (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE, - selected*choice_size+PXSIZE+arrow_width, - (BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE+arrow_height, + drect(selected * choice_size + PXSIZE, + (BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE, + selected * choice_size + PXSIZE + arrow_width, + (BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE + arrow_height, C_WHITE); - + /* Move the selection arrow and update the selected item. */ selected++; } - /* If the user has not validated his choice by pressing SHIFT, we loop one - * more time. */ - }while(key != KEY_SHIFT); + /* If the user has not validated his choice by pressing SHIFT, we loop + * one more time. */ + } while(key != KEY_SHIFT); /* Make a little animation because we looove little animations ;) */ - for(i=DWIDTH/8+1;i>0;i--){ + for(i = DWIDTH / 8 + 1; i > 0; i--) { /* I'm drawing the same box as on the start animation */ update_npcs(game); game_draw(game); dialogs_text_opt(game, _face, _text, NULL, false, false, NULL, 0, false, _i, false); - drect(0, (BOX_HEIGHT+1)*PXSIZE+1, i*(DWIDTH/8), - (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE); - drect(i*(DWIDTH/8), BOX_HEIGHT*PXSIZE, i*(DWIDTH/8)+PXSIZE-1, - (BOX_HEIGHT+CHOICE_BOX_HEIGHT+1)*PXSIZE, C_BLACK); - drect(0, (BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, i*(DWIDTH/8), - (BOX_HEIGHT+CHOICE_BOX_HEIGHT+1)*PXSIZE, C_BLACK); + drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8), + (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE); + drect(i * (DWIDTH / 8), BOX_HEIGHT * PXSIZE, + i * (DWIDTH / 8) + PXSIZE - 1, + (BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK); + drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8), + (BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK); dupdate(); - while(game->frame_duration < 20) sleep(); + while(game->frame_duration < 20) + sleep(); game->frame_duration = 0; } /* Return the selected item because he'll also be returned by showtext_opt. @@ -338,42 +357,41 @@ int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start, end, _choice_screen_call, 100, true, 0, true); } - - - void dialogs_initiate_sequence(Game *game, bopti_image_t *face, - uint32_t dialogNumber) { - Dialog *currentDiag = &game->map_level->dialogs[dialogNumber]; + uint32_t dialogNumber) { + Dialog *currentDiag = &game->map_level->dialogs[dialogNumber]; - /* we collect the information */ - char *text = currentDiag->dialog; + /* we collect the information */ + char *text = currentDiag->dialog; - char *choices = currentDiag->choices ; - char *conclusion1 = currentDiag->conclusion1; - int next1 = currentDiag->next1; - char *conclusion2 = currentDiag->conclusion2; - int next2 = currentDiag->next2; - int nextOther = currentDiag->nextOther; - int isQuestion = currentDiag->isQuestion; + char *choices = currentDiag->choices; + char *conclusion1 = currentDiag->conclusion1; + int next1 = currentDiag->next1; + char *conclusion2 = currentDiag->conclusion2; + int next2 = currentDiag->next2; + int nextOther = currentDiag->nextOther; + int isQuestion = currentDiag->isQuestion; - /* we treat the action - i.e. we show a dialog */ - if (isQuestion == 1){ - /* we have to manage a question */ - int answer = dialogs_ask(game, face, text, true, true, - choices, 2, 0); + /* we treat the action - i.e. we show a dialog */ + if(isQuestion == 1) { + /* we have to manage a question */ + int answer = dialogs_ask(game, face, text, true, true, choices, 2, 0); - /* TO DO we need to split the strings conclusion1 and conclusion2 */ - /* to extract the "gift" part */ + /* TO DO we need to split the strings conclusion1 and conclusion2 */ + /* to extract the "gift" part */ - if(answer==0){ - dialogs_text(game, face, conclusion1, true, true); - if (next1!=-1) dialogs_initiate_sequence(game, face, next1); - }else{ - dialogs_text(game, face, conclusion2, true, true); - if (next2!=-1) dialogs_initiate_sequence(game, face, next2); - } - }else{ - dialogs_text(game, face, text, true, true); - if (nextOther!=-1) dialogs_initiate_sequence(game, face, nextOther); - } + if(answer == 0) { + dialogs_text(game, face, conclusion1, true, true); + if(next1 != -1) + dialogs_initiate_sequence(game, face, next1); + } else { + dialogs_text(game, face, conclusion2, true, true); + if(next2 != -1) + dialogs_initiate_sequence(game, face, next2); + } + } else { + dialogs_text(game, face, text, true, true); + if(nextOther != -1) + dialogs_initiate_sequence(game, face, nextOther); + } } diff --git a/src/dialogs.h b/src/dialogs.h index d019d65..86be96e 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -1,11 +1,11 @@ #ifndef DIALOG_H #define DIALOG_H -#include -#include +#include "config.h" #include "game.h" #include "map.h" -#include "config.h" +#include +#include /* dialogs_text_opt() * @@ -37,8 +37,7 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text, int call_before_end(Game *game, unsigned int i), - bool start_anim, - bool end_anim, + bool start_anim, bool end_anim, void for_each_screen(Game *game, unsigned int i), int line_duration, bool update_screen, unsigned int start_i, bool wait_continue); diff --git a/src/events.c b/src/events.c index aee4472..df6ba9c 100644 --- a/src/events.c +++ b/src/events.c @@ -1,62 +1,45 @@ +#include "events.h" #include #include -#include "events.h" -void events_init_handler(EventHandler *handler) { - handler->vars = 0; -} +void events_init_handler(EventHandler *handler) { handler->vars = 0; } int events_bind_variable(EventHandler *handler, int *var, char *name) { - if(handler->vars < MAX_VARIABLES){ + if(handler->vars < MAX_VARIABLES) { handler->variables[handler->vars] = var; handler->var_names[handler->vars++] = name; - }else{ + } else { return 1; } return 0; } -char op_chars[OP_AMOUNT+1] = " =+-/*%"; +char op_chars[OP_AMOUNT + 1] = " =+-/*%"; -int _op_null(int a, int b) { - return 0; -} +int _op_null(int a, int b) { return 0; } -int _op_set(int a, int b) { - return b; -} +int _op_set(int a, int b) { return b; } -int _op_add(int a, int b) { - return a+b; -} +int _op_add(int a, int b) { return a + b; } -int _op_sub(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; + if(b == 0) + return 0; + return a / b; } -int _op_mul(int a, int b) { - 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; + 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 -}; +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 @@ -73,19 +56,19 @@ char *events_parse_string(EventHandler *handler, char *message) { char c; size_t i, n; int *var; - for(i=0;ivars;n++){ - if(!strcmp(var_name, handler->var_names[n])){ + for(n = 0; n < handler->vars; n++) { + if(!strcmp(var_name, handler->var_names[n])) { var = handler->variables[n]; - if(var_op){ + if(var_op) { *var = _operations[var_op](*var, atoi(num)); } break; @@ -98,22 +81,25 @@ char *events_parse_string(EventHandler *handler, char *message) { var_op = OP_NULL; num_pos = 0; } - }else if(!in_token){ - if(message_pos < TOKEN_MAX_SZ) _message_buffer[message_pos++] = c; + } 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(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(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(var_op == OP_NULL) { + if(name_pos < TOKEN_MAX_SZ) + var_name[name_pos++] = c; } } - if(c == '$'){ + if(c == '$') { tok_type = T_VAR_EDIT; } } diff --git a/src/events.h b/src/events.h index 0cd503d..f4a19bf 100644 --- a/src/events.h +++ b/src/events.h @@ -15,11 +15,7 @@ typedef struct { unsigned int vars; } EventHandler; -typedef enum { - T_NULL, - T_VAR_EDIT, - T_AMOUNT -} Token; +typedef enum { T_NULL, T_VAR_EDIT, T_AMOUNT } Token; typedef enum { OP_NULL, @@ -39,7 +35,7 @@ typedef enum { */ void events_init_handler(EventHandler *handler); /* events_bind_variable() - * + * * Bind a variable. Binding a variable allows it to be modified by messages * passed to the event handler using tags written as following: * `variable+number` (The backticks delimit the tag). Available operators: diff --git a/src/game.c b/src/game.c index dd2bb1c..a2a3020 100644 --- a/src/game.c +++ b/src/game.c @@ -4,39 +4,37 @@ #include "config.h" -#include -#include -#include #include #include +#include +#include +#include #include "npc.h" - extern bopti_image_t SignAction_img; extern Dialog *dialogRPG; extern NPC *npcRPG; extern uint32_t nbNPC; -#define MAX_INTERACTION_DISTANCE 12 - +#define MAX_INTERACTION_DISTANCE 12 void game_logic(Game *game) { - update_npcs( game ); + update_npcs(game); /* we check if interactions are possible close to the player */ - for( uint32_t i=0; imap_level->nbextradata; i++ ){ + for(uint32_t i = 0; i < game->map_level->nbextradata; i++) { /* simple distance check along X and Y axis */ /* Be careful to use world coordinates, not local (i.e.map) ones */ - if ((abs((int) game->player.wx - - (int) game->map_level->extradata[i].x*PXSIZE ) - < MAX_INTERACTION_DISTANCE*PXSIZE) - && (abs((int) game->player.wy - - (int) game->map_level->extradata[i].y*PXSIZE ) - < MAX_INTERACTION_DISTANCE*PXSIZE) - && strcmp(game->map_level->extradata[i].type, "NPC") != 0){ + if((abs((int)game->player.wx - + (int)game->map_level->extradata[i].x * PXSIZE) < + MAX_INTERACTION_DISTANCE * PXSIZE) && + (abs((int)game->player.wy - + (int)game->map_level->extradata[i].y * PXSIZE) < + MAX_INTERACTION_DISTANCE * PXSIZE) && + strcmp(game->map_level->extradata[i].type, "NPC") != 0) { /* the player can do something */ game->player.canDoSomething = true; /* we mark the action for futur treatment in player_action() */ @@ -47,16 +45,14 @@ void game_logic(Game *game) { } } - for(uint32_t i=0; iplayer.wx - - (int) npcRPG[i].curx*PXSIZE ) - < MAX_INTERACTION_DISTANCE*PXSIZE) - && (abs((int) game->player.wy - - (int) npcRPG[i].cury*PXSIZE ) - < MAX_INTERACTION_DISTANCE*PXSIZE) - && strcmp( game->map_level->extradata[i].type, "NPC") !=0){ + if((abs((int)game->player.wx - (int)npcRPG[i].curx * PXSIZE) < + MAX_INTERACTION_DISTANCE * PXSIZE) && + (abs((int)game->player.wy - (int)npcRPG[i].cury * PXSIZE) < + MAX_INTERACTION_DISTANCE * PXSIZE) && + strcmp(game->map_level->extradata[i].type, "NPC") != 0) { /* the player can do something */ game->player.canDoSomething = true; /* we mark the action for futur treatment in player_action() */ @@ -67,7 +63,6 @@ void game_logic(Game *game) { } } - /* else nothing to be done here */ game->player.canDoSomething = false; game->player.whichAction = -1; @@ -75,16 +70,15 @@ void game_logic(Game *game) { return; } - void game_render_indicator(Game *game) { /* nothing to do for the player so we quit */ - if(game->player.canDoSomething==false) return; + if(game->player.canDoSomething == false) + return; /* else we draw a small indicator on the screen */ dimage(5, 5, &SignAction_img); } - void game_draw(Game *game) { /* Draw everything. */ dclear(C_WHITE); @@ -106,18 +100,24 @@ void game_get_inputs(Game *game) { /*************************************/ - if(keydown(KEY_EXIT)) game->exittoOS = true; + if(keydown(KEY_EXIT)) + game->exittoOS = true; /* Player actions - Prototypes in player.h and implementation in player.c */ - if(keydown(KEY_LEFT)) player_move(game, D_LEFT); - if(keydown(KEY_RIGHT)) player_move(game, D_RIGHT); - if(keydown(KEY_UP)) player_move(game, D_UP); - if(keydown(KEY_DOWN)) player_move(game, D_DOWN); - if(keydown(KEY_SHIFT)) player_action(game); - if(keydown(KEY_OPTN)){ + if(keydown(KEY_LEFT)) + player_move(game, D_LEFT); + if(keydown(KEY_RIGHT)) + player_move(game, D_RIGHT); + if(keydown(KEY_UP)) + player_move(game, D_UP); + if(keydown(KEY_DOWN)) + player_move(game, D_DOWN); + if(keydown(KEY_SHIFT)) + player_action(game); + if(keydown(KEY_OPTN)) { game->player.is_male = !game->player.is_male; /* TODO: Make something cleaner */ - while(keydown(KEY_OPTN)){ + while(keydown(KEY_OPTN)) { clearevents(); sleep(); } @@ -136,12 +136,13 @@ void game_get_inputs(Game *game) { } #endif - /* if USB is enabled - keybinding for screencapture */ #if USB_FEATURE - if(keydown(KEY_7)) game->screenshot = true; - if(keydown(KEY_8)) game->record = !game->record; + if(keydown(KEY_7)) + game->screenshot = true; + if(keydown(KEY_8)) + game->record = !game->record; -#endif //USB_FEATURE +#endif // USB_FEATURE } diff --git a/src/game.h b/src/game.h index 77fb3a7..e03c385 100644 --- a/src/game.h +++ b/src/game.h @@ -1,44 +1,29 @@ #ifndef GAME_H #define GAME_H - #include #include #include "events.h" - - /* The direction where the player is going to. */ -typedef enum { - D_UP, - D_DOWN, - D_LEFT, - D_RIGHT -} Direction; - -typedef enum { - P_LEFTUP = -1, - P_CENTER = 0, - P_RIGHTDOWN = 1 -} Checkpos; - +typedef enum { D_UP, D_DOWN, D_LEFT, D_RIGHT } Direction; +typedef enum { P_LEFTUP = -1, P_CENTER = 0, P_RIGHTDOWN = 1 } Checkpos; /* Struct that define player parameters */ typedef struct { - int16_t x, y; /* The position of the player int the current map */ + int16_t x, y; /* The position of the player int the current map */ uint16_t px, py; /* The position of the player on screen */ - int16_t wx, wy; /* position of the player in the world */ - int8_t life; /* How many lives the player still has between 0 and 100. */ + int16_t wx, wy; /* position of the player in the world */ + int8_t life; /* How many lives the player still has between 0 and 100. */ int8_t speed; /* The speed of the movement of the player. */ - /* set to true if a action can be done in the current position of the map */ - bool canDoSomething; + bool canDoSomething; /* indicates which data are relevant to the current action in the */ /* extradata layer of the map */ - int32_t whichAction; + int32_t whichAction; /* the player is doing something */ bool isDoingAction; /* the player is interacting with a NPC */ @@ -46,7 +31,6 @@ typedef struct { bool is_male; } Player; - typedef struct { uint32_t ID; /* data to be shown in the dialog*/ @@ -64,7 +48,6 @@ typedef struct { int32_t nextOther; } Dialog; - typedef struct { /* position of the item */ uint32_t x; @@ -91,7 +74,6 @@ typedef struct { /* ... this can be extended as per needs ... */ } ExtraData; - typedef struct { /* width, height and the number of layer of the map */ uint32_t w; @@ -114,7 +96,8 @@ typedef struct { uint8_t *walkable; /* structure that contains all the items on the map to interract with */ - /* each portion of the map has its own list to avoid scrutinizing too much */ + /* each portion of the map has its own list to avoid scrutinizing too much + */ /* data when lloking for proximity of items */ uint32_t nbextradata; ExtraData *extradata; @@ -127,14 +110,12 @@ typedef struct { uint16_t *layers[]; } Map; - - /* This struct will contain all the data of the game. It will make it possible * to pass it to the NPCs to let them interact with the player and the rest of * the world. */ typedef struct { - Map *map_level; /* The level that the player is currently playing */ - Player player; /* The player data. */ + Map *map_level; /* The level that the player is currently playing */ + Player player; /* The player data. */ EventHandler handler; /* The event handler (see events.h). */ /* Some global variables */ /* Set to true when asked for exit */ @@ -165,7 +146,7 @@ void game_logic(Game *game); void game_draw(Game *game); /* game_render_indicator() - * + * * This render a small sign on the upper left corner of the screen * if the player can do an action * game: The game struct. @@ -173,11 +154,10 @@ void game_draw(Game *game); void game_render_indicator(Game *game); /* game_get_inputs() - * + * * Handle key presses. * game: The game struct. */ void game_get_inputs(Game *game); #endif - diff --git a/src/main.c b/src/main.c index 76655fd..97a2ccc 100644 --- a/src/main.c +++ b/src/main.c @@ -1,27 +1,26 @@ +#include #include #include #include -#include #include #include "config.h" -#include "npc.h" #include "events.h" +#include "npc.h" #if USB_FEATURE - #include - #include -#endif //USB_FEATURE - +#include +#include +#endif // USB_FEATURE #if GRAYMODEOK - #include -#endif //GRAYMODEOK +#include +#endif // GRAYMODEOK -#include #include +#include #include "game.h" #include "mapdata.h" @@ -30,56 +29,59 @@ extern bopti_image_t player_face_img; - extern Map *worldRPG[]; /* Game data (defined in "game.h")*/ -Game game = { - NULL, - {12*PXSIZE, 36*PXSIZE, 0, 0, 12*PXSIZE, 36*PXSIZE, 100, SPEED, false, 0, false, false, true}, - {{}, {}, 0}, - false, false, false, 0 +Game game = {NULL, + {12 * PXSIZE, 36 * PXSIZE, 0, 0, 12 * PXSIZE, 36 * PXSIZE, 100, + SPEED, false, 0, false, false, true}, + {{}, {}, 0}, + false, + false, + false, + 0 - /* debug variables*/ - , false, false, false, 100 -}; + /* debug variables*/ + , + false, + false, + false, + 100}; /* screen capture management code. TODO: Clean this up! */ #if USB_FEATURE - void USB_feature( void ) - { - if (game.screenshot && usb_is_open()) { +void USB_feature(void) { + if(game.screenshot && usb_is_open()) { - #if GRAYMODEOK // This is a trick, if GRAYMODEOK is defined then - // we make the code accessible +#if GRAYMODEOK // This is a trick, if GRAYMODEOK is defined then + // we make the code accessible - if (dgray_enabled()) - usb_fxlink_screenshot_gray(false); - else + if(dgray_enabled()) + usb_fxlink_screenshot_gray(false); + else - #endif +#endif // else we just let the usual screeshot function - usb_fxlink_screenshot(false); - game.screenshot = false; - } + usb_fxlink_screenshot(false); + game.screenshot = false; + } + if(game.record && usb_is_open()) { - if (game.record && usb_is_open()) { - - #if GRAYMODEOK +#if GRAYMODEOK - if (dgray_enabled()) - usb_fxlink_videocapture_gray(false); - else + if(dgray_enabled()) + usb_fxlink_videocapture_gray(false); + else - #endif +#endif usb_fxlink_videocapture(false); - } } +} #endif @@ -91,80 +93,81 @@ int update_time(void) { } int main(void) { - + __printf_enable_fp(); - + int timer; timer = timer_configure(TIMER_TMU, 1000, GINT_CALL(update_time)); - if(timer < 0){ + if(timer < 0) { return -1; } 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, (int *)&game.player.life, "life"); events_bind_variable(&game.handler, &game.mana, "mana"); reload_npc(&game); - #if USB_FEATURE - usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL}; - usb_open(interfaces, GINT_CALL_NULL); - #endif - +#if USB_FEATURE + usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL}; + usb_open(interfaces, GINT_CALL_NULL); +#endif /* start grayscale engine */ - #if GRAYMODEOK - dgray(DGRAY_ON); - #endif +#if GRAYMODEOK + dgray(DGRAY_ON); +#endif - do{ + do { /* clear screen */ dclear(C_WHITE); /* render the map */ game_draw(&game); - #if DEBUGMODE && GINT_RENDER_RGB - if (game.debug_map) - { - dfont( NULL ); - drect( 5, 5,390, 55, C_WHITE ); - dprint(10, 10, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", - 0, worldRPG[0]->xmin, worldRPG[0]->ymin, - worldRPG[0]->xmax, worldRPG[0]->ymax); - dprint(10, 20, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", - 1, worldRPG[1]->xmin, worldRPG[1]->ymin, - worldRPG[1]->xmax, worldRPG[1]->ymax); - dprint(10, 30, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", - 2, worldRPG[2]->xmin, worldRPG[2]->ymin, - worldRPG[2]->xmax, worldRPG[2]->ymax); - dprint(10, 40, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", - 3, worldRPG[3]->xmin, worldRPG[3]->ymin, - worldRPG[3]->xmax, worldRPG[3]->ymax); - } - if (game.debug_player) - { - dfont( NULL ); - drect( 5, 55,390, 75, C_WHITE ); - dprint( 10, 60, C_BLUE, "X= %d - Y= %d / Wx= %d - Wy= %d", - game.player.x, game.player.y, game.player.wx, - game.player.wy ); - } - if (game.debug_extra) - { - dfont( NULL ); - for (int i=0; inbextradata; i++ ) - dprint( 10, 90+i*15, C_RED, "X= %d - Y= %d - T: %d - ID: %d - S: %c", - game.map_level->extradata[i].x, - game.map_level->extradata[i].y, - game.map_level->extradata[i].dialogID, - game.map_level->dialogs[ game.map_level->extradata[i].dialogID ].ID, - game.map_level->dialogs[ game.map_level->extradata[i].dialogID ].conclusion1[0] ); - } - #endif +#if DEBUGMODE && GINT_RENDER_RGB + if(game.debug_map) { + dfont(NULL); + drect(5, 5, 390, 55, C_WHITE); + dprint(10, 10, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 0, + worldRPG[0]->xmin, worldRPG[0]->ymin, worldRPG[0]->xmax, + worldRPG[0]->ymax); + dprint(10, 20, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 1, + worldRPG[1]->xmin, worldRPG[1]->ymin, worldRPG[1]->xmax, + worldRPG[1]->ymax); + dprint(10, 30, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 2, + worldRPG[2]->xmin, worldRPG[2]->ymin, worldRPG[2]->xmax, + worldRPG[2]->ymax); + dprint(10, 40, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 3, + worldRPG[3]->xmin, worldRPG[3]->ymin, worldRPG[3]->xmax, + worldRPG[3]->ymax); + } + if(game.debug_player) { + dfont(NULL); + drect(5, 55, 390, 75, C_WHITE); + dprint(10, 60, C_BLUE, "X= %d - Y= %d / Wx= %d - Wy= %d", + game.player.x, game.player.y, game.player.wx, + game.player.wy); + } + if(game.debug_extra) { + dfont(NULL); + for(int i = 0; i < game.map_level->nbextradata; i++) + dprint(10, 90 + i * 15, C_RED, + "X= %d - Y= %d - T: %d - ID: %d - S: %c", + game.map_level->extradata[i].x, + game.map_level->extradata[i].y, + game.map_level->extradata[i].dialogID, + game.map_level + ->dialogs[game.map_level->extradata[i].dialogID] + .ID, + game.map_level + ->dialogs[game.map_level->extradata[i].dialogID] + .conclusion1[0]); + } +#endif /* start the logic of the game */ game_logic(&game); @@ -172,33 +175,30 @@ int main(void) { /* Screen blit */ dupdate(); - /* Screen capture feature if enabled */ - #if USB_FEATURE - USB_feature(); - #endif +/* Screen capture feature if enabled */ +#if USB_FEATURE + USB_feature(); +#endif /* Management of the inputs */ game_get_inputs(&game); /* Run the game at max. 50fps */ - while(game.frame_duration < 20) sleep(); + while(game.frame_duration < 20) + sleep(); /* Reset frame_duration for the next frame */ game.frame_duration = 0; - }while(!game.exittoOS); // want to exit ? + } while(!game.exittoOS); // want to exit ? +/* shutdown grayengine*/ +#if GRAYMODEOK + dgray(DGRAY_OFF); +#endif - - /* shutdown grayengine*/ - #if GRAYMODEOK - dgray(DGRAY_OFF); - #endif - - - /* close USB */ - #if USB_FEATURE - usb_close(); - #endif +/* close USB */ +#if USB_FEATURE + usb_close(); +#endif timer_stop(timer); return 1; } - diff --git a/src/map.c b/src/map.c index bb6efad..78901c4 100644 --- a/src/map.c +++ b/src/map.c @@ -5,8 +5,7 @@ #include extern Map *worldRPG[]; -//extern ExtraData *extraRPG[]; - +// extern ExtraData *extraRPG[]; void map_render(Game *game) { @@ -25,9 +24,10 @@ void map_render(Game *game) { unsigned char mx, my; /* dw and dh contain the amount of tiles that will be drawn on x and on * y. */ - unsigned char dw = DWIDTH/T_WIDTH+2, dh = DHEIGHT/T_HEIGHT+1; + unsigned char dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1; /* mw and mh will contain the height and the width of the map. */ - unsigned short int mw = map_level->w*T_WIDTH, mh = map_level->h*T_HEIGHT; + unsigned short int mw = map_level->w * T_WIDTH, + mh = map_level->h * T_HEIGHT; /* tile contains the tile to draw. */ short int tile; /* The position where I start drawing */ @@ -39,62 +39,62 @@ void map_render(Game *game) { /* The index of the current tile we're drawing in the layer. */ int current_index; /* Fix sx. */ - if(player->xx < DWIDTH / 2) { /* If I can't center the player because I'm near the left border of * the map. */ player->px = player->x; sx = 0; - }else if(player->x+DWIDTH/2>mw){ + } else if(player->x + DWIDTH / 2 > mw) { /* If I can't center the player because I'm near the right border of * the map. */ - sx = mw-DWIDTH; - player->px = player->x-sx; - }else{ + sx = mw - DWIDTH; + player->px = player->x - sx; + } else { /* I can center the player. */ - player->px = DWIDTH/2; - sx = player->x-player->px; + player->px = DWIDTH / 2; + sx = player->x - player->px; } /* Fix sy. */ - if(player->yy < DHEIGHT / 2) { /* If I can't center the player because I'm near the top border of * the map. */ player->py = player->y; sy = 0; - }else if(player->y+DHEIGHT/2>mh){ + } else if(player->y + DHEIGHT / 2 > mh) { /* If I can't center the player because I'm near the bottom border * of the map. */ - sy = mh-DHEIGHT; - player->py = player->y-sy; - }else{ + sy = mh - DHEIGHT; + player->py = player->y - sy; + } else { /* I can center the player. */ - player->py = DHEIGHT/2; - sy = player->y-player->py; + player->py = DHEIGHT / 2; + sy = player->y - player->py; } - tx = sx/T_WIDTH; - ty = sy/T_HEIGHT; - mx = sx-tx*T_WIDTH; - my = sy-ty*T_HEIGHT; - for (l = 0; l < map_level->nblayers-1; l++){ + tx = sx / T_WIDTH; + ty = sy / T_HEIGHT; + mx = sx - tx * T_WIDTH; + my = sy - ty * T_HEIGHT; + for(l = 0; l < map_level->nblayers - 1; l++) { /* Draw a layer of the map on screen. */ - for(y=0;y=0 && tx+x < map_level->w && - ty+y>=0 && ty+y < map_level->h){ + if(tx + x >= 0 && tx + x < map_level->w && ty + y >= 0 && + ty + y < map_level->h) { /* index of the current tile */ - current_index = (y+ty) * map_level->w + tx+x; + current_index = (y + ty) * map_level->w + tx + x; /* we get the ID of the tile in the current drawable layers */ tile = map_level->layers[l][current_index]; - + /* tile == -1 means nothing to be drawn */ - if(tile >= 0){ + if(tile >= 0) { /* get x and y position in the tileset image */ xtile = (tile % map_level->tileset_size) * T_WIDTH; ytile = (tile / map_level->tileset_size) * T_HEIGHT; /* render */ - dsubimage(x*T_WIDTH-mx, y*T_HEIGHT-my, + dsubimage(x * T_WIDTH - mx, y * T_HEIGHT - my, map_level->tileset, xtile, ytile, T_WIDTH, T_HEIGHT, DIMAGE_NONE); } @@ -105,7 +105,7 @@ void map_render(Game *game) { } void map_render_by_layer(Game *game, int layer) { - + Map *map_level = game->map_level; Player *player = &game->player; @@ -121,9 +121,10 @@ void map_render_by_layer(Game *game, int layer) { unsigned char mx, my; /* dw and dh contain the amount of tiles that will be drawn on x and on * y. */ - unsigned char dw = DWIDTH/T_WIDTH+2, dh = DHEIGHT/T_HEIGHT+1; + unsigned char dw = DWIDTH / T_WIDTH + 2, dh = DHEIGHT / T_HEIGHT + 1; /* mw and mh will contain the height and the width of the map. */ - unsigned short int mw = map_level->w*T_WIDTH, mh = map_level->h*T_HEIGHT; + unsigned short int mw = map_level->w * T_WIDTH, + mh = map_level->h * T_HEIGHT; /* tile contains the tile to draw. */ short int tile; /* The position where I start drawing */ @@ -131,63 +132,63 @@ void map_render_by_layer(Game *game, int layer) { /* The position of the tile in the tileset. */ unsigned short int xtile, ytile; /* Fix sx. */ - if(player->xx < DWIDTH / 2) { /* If I can't center the player because I'm near the left border of * the map. */ player->px = player->x; sx = 0; - }else if(player->x+DWIDTH/2>mw){ + } else if(player->x + DWIDTH / 2 > mw) { /* If I can't center the player because I'm near the right border of * the map. */ - sx = mw-DWIDTH; - player->px = player->x-sx; - }else{ + sx = mw - DWIDTH; + player->px = player->x - sx; + } else { /* I can center the player. */ - player->px = DWIDTH/2; - sx = player->x-player->px; + player->px = DWIDTH / 2; + sx = player->x - player->px; } /* Fix sy. */ - if(player->yy < DHEIGHT / 2) { /* If I can't center the player because I'm near the top border of * the map. */ player->py = player->y; sy = 0; - }else if(player->y+DHEIGHT/2>mh){ + } else if(player->y + DHEIGHT / 2 > mh) { /* If I can't center the player because I'm near the bottom border * of the map. */ - sy = mh-DHEIGHT; - player->py = player->y-sy; - }else{ + sy = mh - DHEIGHT; + player->py = player->y - sy; + } else { /* I can center the player. */ - player->py = DHEIGHT/2; - sy = player->y-player->py; + player->py = DHEIGHT / 2; + sy = player->y - player->py; } - tx = sx/T_WIDTH; - ty = sy/T_HEIGHT; - mx = sx-tx*T_WIDTH; - my = sy-ty*T_HEIGHT; + tx = sx / T_WIDTH; + ty = sy / T_HEIGHT; + mx = sx - tx * T_WIDTH; + my = sy - ty * T_HEIGHT; /* Draw a layer of the map on screen. */ - for(y=0;y=0 && tx+x < map_level->w && - ty+y>=0 && ty+y < map_level->h){ + * I draw it. */ + if(tx + x >= 0 && tx + x < map_level->w && ty + y >= 0 && + ty + y < map_level->h) { /* index of the current tile */ - int currentIndex = (y+ty) * map_level->w + tx+x; + int currentIndex = (y + ty) * map_level->w + tx + x; /* we get the ID of the tile in the current drawable layers - */ + */ tile = map_level->layers[layer][currentIndex]; - + /* tile == -1 means nothing to be drawn */ - if(tile >= 0){ + if(tile >= 0) { /* get x and y position in the tileset image */ xtile = (tile % map_level->tileset_size) * T_WIDTH; ytile = (tile / map_level->tileset_size) * T_HEIGHT; /* render */ - dsubimage(x*T_WIDTH-mx, y*T_HEIGHT-my, - map_level->tileset, xtile, ytile, T_WIDTH, - T_HEIGHT, DIMAGE_NONE); + dsubimage(x * T_WIDTH - mx, y * T_HEIGHT - my, + map_level->tileset, xtile, ytile, T_WIDTH, + T_HEIGHT, DIMAGE_NONE); } } } @@ -195,44 +196,45 @@ void map_render_by_layer(Game *game, int layer) { } short int map_get_tile(Game *game, int x, int y, int l) { - + Map *map_level = game->map_level; - + /* Get the tile at (x, y) on layer l. Returns the tile ID or MAP_OUTSIDE if * it's not found. */ - return (x>=0 && x < (int) map_level->w && y>=0 && y < (int) map_level->h) ? - map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE; + return (x >= 0 && x < (int)map_level->w && y >= 0 && y < (int)map_level->h) + ? map_level->layers[l][y * map_level->w + x] + : MAP_OUTSIDE; } short int map_get_walkable(Game *game, int x, int y) { - + Map *map_level = game->map_level; /* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not * found. */ - return (x>=0 && x < (int) map_level->w && y>=0 && y < (int) map_level->h) ? - map_level->walkable[y * map_level->w + x] : MAP_OUTSIDE; + return (x >= 0 && x < (int)map_level->w && y >= 0 && y < (int)map_level->h) + ? map_level->walkable[y * map_level->w + x] + : MAP_OUTSIDE; } /* return the pointer to the map containing the given position */ -Map *map_get_for_coordinates( Game *game, int x, int y ) -{ +Map *map_get_for_coordinates(Game *game, int x, int y) { /* check if the current map contains the point */ - if (x>= (int)game->map_level->xmin && x< (int)game->map_level->xmax && - y>= (int)game->map_level->ymin && y< (int)game->map_level->ymax){ + if(x >= (int)game->map_level->xmin && x < (int)game->map_level->xmax && + y >= (int)game->map_level->ymin && y < (int)game->map_level->ymax) { return game->map_level; } /* else we check in worldRPG if there is a mal containing that point */ int i = 0; Map *current = worldRPG[i]; - do{ - if (x>= (int)current->xmin && x< (int)current->xmax && - y>= (int)current->ymin && y< (int)current->ymax) + do { + if(x >= (int)current->xmin && x < (int)current->xmax && + y >= (int)current->ymin && y < (int)current->ymax) return current; i++; current = worldRPG[i]; - }while (current!=NULL); - + } while(current != NULL); + /* else we return NULL cause the point is a not within a map */ return NULL; } diff --git a/src/map.h b/src/map.h index 184948d..70a4b0e 100644 --- a/src/map.h +++ b/src/map.h @@ -1,33 +1,29 @@ #ifndef MAP_H #define MAP_H - #define BACKGROUND 0 #define FOREGROUND 1 -#define MAP_OUTSIDE -2 /* Returned by get_tile_at_pos if the point is outside of - * the map. */ +#define MAP_OUTSIDE \ + -2 /* Returned by get_tile_at_pos if the point is outside of \ + * the map. */ #include "game.h" #include "player.h" - - /* Structure 'Map' has been moved to game.h */ /* to avoid circular references between map.h, game.h and player.h */ /* only methods propotypes are now in dedicated header files */ - - /* map_render() - * + * * Draws the map map on the entire screen to be viewed by the player player. * game: The game struct. */ void map_render(Game *game); /* map_render_by_layer() - * + * * Draws the map layer on the entire screen to be viewed by the player player. * game: The game struct. * layer: The layer to render. @@ -35,7 +31,7 @@ void map_render(Game *game); void map_render_by_layer(Game *game, int layer); /* map_get_tile() - * + * * Get the tile at (x, y) of the map map. If the tile is located outside of the * screen, MAP_OUTSIDE is returned. * game: The game struct. @@ -46,7 +42,7 @@ void map_render_by_layer(Game *game, int layer); short int map_get_tile(Game *game, int x, int y, int l); /* map_get_walkable() - * + * * Returns what is in the walkable layer at (x, y). * game: The game struct. * x: The coordinates of the tile. @@ -55,12 +51,12 @@ short int map_get_tile(Game *game, int x, int y, int l); short int map_get_walkable(Game *game, int x, int y); /* map_get_for_coordinates() - * + * * return the pointer to the map containing the given position. * game: The game struct. * x: The coordinates to look at. * y: The coordinates to look at. */ -Map* map_get_for_coordinates(Game *game, int x, int y ); +Map *map_get_for_coordinates(Game *game, int x, int y); #endif diff --git a/src/mapdata.h b/src/mapdata.h index fb40c12..7b63f8c 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -1,10 +1,9 @@ #ifndef MAPDATA_H #define MAPDATA_H -#include #include "game.h" +#include extern Map *worldRPG[]; #endif - diff --git a/src/memory.c b/src/memory.c index 9bfcb47..99901c4 100644 --- a/src/memory.c +++ b/src/memory.c @@ -2,11 +2,10 @@ bool memory_is_in(short int *array, short int array_length, short int item) { short int i; - for(i=0;i /* memory_is_in() - * + * * returns true if item is in array. * array: The array to search in. * array_length: The length of the array. @@ -12,4 +12,3 @@ bool memory_is_in(short int *array, short int array_length, short int item); #endif - diff --git a/src/npc.c b/src/npc.c index dbdcf04..ac4ec35 100644 --- a/src/npc.c +++ b/src/npc.c @@ -1,32 +1,26 @@ #include "npc.h" +#include "config.h" #include "dialogs.h" #include "game.h" #include "map.h" -#include "config.h" #include #include /*debug*/ +#include #include #include -#include - extern bopti_image_t tiny_npc_male; extern bopti_image_t tiny_npc_female; extern bopti_image_t tiny_npc_milkman; extern bopti_image_t tiny_npc_police; - NPC *npcRPG; uint32_t nbNPC = 0; -float length( float x, float y ) -{ - return sqrtf( x*x+y*y ); -} +float length(float x, float y) { return sqrtf(x * x + y * y); } -int npc_clear_path(NPC *npc) -{ +int npc_clear_path(NPC *npc) { npc->currentPoint = 0; npc->hasPath = 0; npc->path_length = 0; @@ -34,47 +28,46 @@ int npc_clear_path(NPC *npc) free(npc->ypath); npc->xpath = malloc(4); npc->ypath = malloc(4); - if(npc->xpath == NULL || npc->ypath == NULL) return 1; + if(npc->xpath == NULL || npc->ypath == NULL) + return 1; return 0; } -int npc_append_path(uint16_t x, uint16_t y, NPC *npc) -{ - npc->xpath = realloc(npc->xpath, npc->path_length*2+2); - npc->ypath = realloc(npc->ypath, npc->path_length*2+2); - if(npc->xpath == NULL || npc->ypath == NULL) return 1; +int npc_append_path(uint16_t x, uint16_t y, NPC *npc) { + npc->xpath = realloc(npc->xpath, npc->path_length * 2 + 2); + npc->ypath = realloc(npc->ypath, npc->path_length * 2 + 2); + if(npc->xpath == NULL || npc->ypath == NULL) + return 1; npc->path_length++; - npc->xpath[npc->path_length-1] = x - npc->x; - npc->ypath[npc->path_length-1] = y - npc->y; + npc->xpath[npc->path_length - 1] = x - npc->x; + npc->ypath[npc->path_length - 1] = y - npc->y; return 0; } -void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) -{ +void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) { free(visited); free(gscore); free(fscore); } int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos, - int16_t dest, NPC *npc) -{ - if(npc_clear_path(npc)) goto as_recons_fail; + int16_t dest, NPC *npc) { + if(npc_clear_path(npc)) + goto as_recons_fail; int16_t next = came_from[dest]; unsigned int i; - for(i = 0; i < 64; i++) - { - if(npc_append_path((next%w)*T_WIDTH,(next/h)*T_HEIGHT, npc)) - { + for(i = 0; i < 64; i++) { + if(npc_append_path((next % w) * T_WIDTH, (next / h) * T_HEIGHT, npc)) { goto as_recons_fail; } next = came_from[next]; - if(next == spos){ - if(npc_append_path((spos%w)*T_WIDTH,(spos/h)*T_HEIGHT, npc)) + if(next == spos) { + if(npc_append_path((spos % w) * T_WIDTH, (spos / h) * T_HEIGHT, + npc)) goto as_recons_fail; break; } @@ -82,16 +75,15 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos, uint16_t tx, ty; - //Flip the path because it started from the end + // Flip the path because it started from the end - for(i = 0; i < npc->path_length/2; i++) - { + for(i = 0; i < npc->path_length / 2; i++) { tx = npc->xpath[i]; ty = npc->ypath[i]; - npc->xpath[i] = npc->xpath[npc->path_length-i-1]; - npc->ypath[i] = npc->ypath[npc->path_length-i-1]; - npc->ypath[npc->path_length-i-1] = tx; - npc->ypath[npc->path_length-i-1] = ty; + npc->xpath[i] = npc->xpath[npc->path_length - i - 1]; + npc->ypath[i] = npc->ypath[npc->path_length - i - 1]; + npc->ypath[npc->path_length - i - 1] = tx; + npc->ypath[npc->path_length - i - 1] = ty; } free(came_from); @@ -100,95 +92,103 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos, return 0; - as_recons_fail: +as_recons_fail: free(came_from); return 1; } -//Returns non zero error code on failure -//Custom a* implemetation -//Unoptimized, may become an issue -int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) -{ +// Returns non zero error code on failure +// Custom a* implemetation +// Unoptimized, may become an issue +int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { int32_t i, j; int32_t w = full_map->w; int32_t h = full_map->h; - int32_t x = floor(npc->curx)/T_WIDTH; - int32_t y = floor(npc->cury)/T_HEIGHT; + int32_t x = floor(npc->curx) / T_WIDTH; + int32_t y = floor(npc->cury) / T_HEIGHT; dest_x /= T_WIDTH; dest_y /= T_HEIGHT; - int32_t spos = y*w+x; + int32_t spos = y * w + x; uint8_t *map = full_map->walkable; - if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h) return 2; - if(map[spos]) return 2; - if(map[dest_y*w+dest_x]) return 2; + if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h) + return 2; + if(map[spos]) + return 2; + if(map[dest_y * w + dest_x]) + return 2; npc_clear_path(npc); - uint8_t *visited = malloc(w*h); - for(i=0; i bscore) continue; - bx = i%w; - by = i/w; + // Cheapest known tile + for(i = 0; i <= w * h; i++) { + if(visited[i]) + continue; + if(map[i] == 1) + continue; + if(fscore[i] > bscore) + continue; + bx = i % w; + by = i / w; bscore = fscore[i]; } - if(bx == dest_x && by == dest_y) - { + if(bx == dest_x && by == dest_y) { as_clean(visited, gscore, fscore); return as_reconstruct_path(came_from, w, h, spos, - dest_y*w+dest_x, npc); + dest_y * w + dest_x, npc); } - visited[by*w+bx] = 1; + visited[by * w + bx] = 1; int att_score; - for(i = bx-1; i < bx+2; i++) - { - if(i > w) break; - for(j = by-1; j < by+2; j++) - { - if(j > h) break; - if(map[j*w+i] == 1) continue; - if(i == bx && j == by) continue; - att_score = gscore[by*w+bx] + round(length(bx-i,by-j)); - if(att_score < gscore[j*w+i]) - { - came_from[j*w+i] = by*w+bx; - gscore[j*w+i] = att_score; - fscore[j*w+i] = att_score + round( - length(dest_x-i, dest_y-j)); - if(visited[j*w+i]) visited[j*w+i] = 0; + for(i = bx - 1; i < bx + 2; i++) { + if(i > w) + break; + for(j = by - 1; j < by + 2; j++) { + if(j > h) + break; + if(map[j * w + i] == 1) + continue; + if(i == bx && j == by) + continue; + att_score = gscore[by * w + bx] + round(length(bx - i, by - j)); + if(att_score < gscore[j * w + i]) { + came_from[j * w + i] = by * w + bx; + gscore[j * w + i] = att_score; + fscore[j * w + i] = + att_score + round(length(dest_x - i, dest_y - j)); + if(visited[j * w + i]) + visited[j * w + i] = 0; } } } @@ -200,105 +200,91 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) return 3; } -NPC *npc_create() -{ - //Use temp pointer to avoid breaking the whole npcRPG on failure - void *temp = realloc(npcRPG, (nbNPC+1)*sizeof(NPC)); - if(temp == NULL) return NULL; +NPC *npc_create() { + // Use temp pointer to avoid breaking the whole npcRPG on failure + void *temp = realloc(npcRPG, (nbNPC + 1) * sizeof(NPC)); + if(temp == NULL) + return NULL; npcRPG = temp; nbNPC++; - NPC *npc = &npcRPG[nbNPC-1]; + NPC *npc = &npcRPG[nbNPC - 1]; npc->xpath = malloc(2); npc->ypath = malloc(2); return npc; } -void npc_remove(NPC *npc) -{ - uint32_t pos = ((uint32_t)npc - (uint32_t)npcRPG)/sizeof(NPC); - if(pos > nbNPC-1) return; - if(pos == nbNPC-1) - { +void npc_remove(NPC *npc) { + uint32_t pos = ((uint32_t)npc - (uint32_t)npcRPG) / sizeof(NPC); + if(pos > nbNPC - 1) + return; + if(pos == nbNPC - 1) { nbNPC--; return; } - memmove(npc, &npc[1], (nbNPC-pos-1)*sizeof(NPC)); + memmove(npc, &npc[1], (nbNPC - pos - 1) * sizeof(NPC)); } -//Refactoring to make adding complexity cleaner -void update_npcs([[maybe_unused]] Game *game) -{ - for( uint32_t u=0; uhasPath || npc->paused==true) return; + if(!npc->hasPath || npc->paused == true) + return; - float vecX = (float) (npc->xpath[ npc->currentPoint ] + - npc->x) - npc->curx; - float vecY = (float) (npc->ypath[ npc->currentPoint ] + - npc->y) - npc->cury; + float vecX = (float)(npc->xpath[npc->currentPoint] + npc->x) - npc->curx; + float vecY = (float)(npc->ypath[npc->currentPoint] + npc->y) - npc->cury; float vecN = length(vecX, vecY); - if (vecN>0.5f) - { - vecX /= vecN*2.0; - vecY /= vecN*2.0; - } - else - { + if(vecN > 0.5f) { + vecX /= vecN * 2.0; + vecY /= vecN * 2.0; + } else { npc->currentPoint++; npc->currentPoint = npc->currentPoint % npc->path_length; } npc->curx += vecX; npc->cury += vecY; - } -void reload_npc(Game *game) -{ - if (npcRPG!=NULL) - { +void reload_npc(Game *game) { + if(npcRPG != NULL) { free(npcRPG); npcRPG = NULL; - } - + nbNPC = 0; - - for (uint32_t u=0; umap_level->nbextradata; u++) - { + for(uint32_t u = 0; u < game->map_level->nbextradata; u++) { ExtraData *Data = &game->map_level->extradata[u]; - if (strcmp(Data->type, "NPC")==0) /* the current data is a NPC */ + if(strcmp(Data->type, "NPC") == 0) /* the current data is a NPC */ { nbNPC++; } } - npcRPG = (NPC*) malloc( nbNPC * sizeof(NPC) ); - if(npcRPG == NULL) return; - int currentNPC=0; + npcRPG = (NPC *)malloc(nbNPC * sizeof(NPC)); + if(npcRPG == NULL) + return; + int currentNPC = 0; - for (uint32_t u=0; umap_level->nbextradata; u++) - { + for(uint32_t u = 0; u < game->map_level->nbextradata; u++) { ExtraData *Data = &game->map_level->extradata[u]; - if (strcmp(Data->type, "NPC")==0) /* the current data is a NPC */ + if(strcmp(Data->type, "NPC") == 0) /* the current data is a NPC */ { - npcRPG[currentNPC].curx = (float) Data->x; - npcRPG[currentNPC].cury = (float) Data->y; + npcRPG[currentNPC].curx = (float)Data->x; + npcRPG[currentNPC].cury = (float)Data->y; npcRPG[currentNPC].x = Data->x; npcRPG[currentNPC].y = Data->y; npcRPG[currentNPC].dialogID = Data->dialogID; - npcRPG[currentNPC].currentPoint = 1; + npcRPG[currentNPC].currentPoint = 1; npcRPG[currentNPC].hasPath = Data->hasPath; npcRPG[currentNPC].path_length = Data->path_length; npcRPG[currentNPC].xpath = Data->xpath; @@ -313,107 +299,107 @@ void reload_npc(Game *game) void npc_draw(Game *game) { Player *pl = &game->player; size_t i; - const Face npc_sprites[FACES] = { - {"MALE", &tiny_npc_male}, - {"FEMALE", &tiny_npc_female}, - {"MILKMAN", &tiny_npc_milkman}, - {"POLICE", &tiny_npc_police} - }; + const Face npc_sprites[FACES] = {{"MALE", &tiny_npc_male}, + {"FEMALE", &tiny_npc_female}, + {"MILKMAN", &tiny_npc_milkman}, + {"POLICE", &tiny_npc_police}}; - for (uint32_t u=0; uhasPath==1) /* this NPC has a trajectory */ - { - int NbPoints = Data->path_length+1; - for(int v=0; vx + - Data->xpath[v % NbPoints]) * PXSIZE) - -(int16_t) pl->wx; - int16_t deltaY1=((int16_t) (Data->y + - Data->ypath[v % NbPoints]) * PXSIZE) - -(int16_t) pl->wy; - int16_t deltaX2=((int16_t) (Data->x + - Data->xpath[(v+1) % NbPoints]) * PXSIZE) - -(int16_t) pl->wx; - int16_t deltaY2=((int16_t) (Data->y + - Data->ypath[(v+1) % NbPoints]) * PXSIZE) - -(int16_t) pl->wy; - - dline( pl->px + deltaX1, pl->py + deltaY1, - pl->px + deltaX2, pl->py + deltaY2, - PATH_COLOR); - } - } - #endif // DEBUGMODE - int16_t delX=((int16_t) (Data->curx * PXSIZE))-(int16_t) pl->wx; - int16_t delY=((int16_t) (Data->cury * PXSIZE))-(int16_t) pl->wy; +/* Render the path if in debug*/ +#if DEBUGMODE + if(Data->hasPath == 1) /* this NPC has a trajectory */ + { + int NbPoints = Data->path_length + 1; + for(int v = 0; v < NbPoints; v++) { + + int16_t deltaX1 = + ((int16_t)(Data->x + Data->xpath[v % NbPoints]) * PXSIZE) - + (int16_t)pl->wx; + int16_t deltaY1 = + ((int16_t)(Data->y + Data->ypath[v % NbPoints]) * PXSIZE) - + (int16_t)pl->wy; + int16_t deltaX2 = + ((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) * + PXSIZE) - + (int16_t)pl->wx; + int16_t deltaY2 = + ((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) * + PXSIZE) - + (int16_t)pl->wy; + + dline(pl->px + deltaX1, pl->py + deltaY1, pl->px + deltaX2, + pl->py + deltaY2, PATH_COLOR); + } + } +#endif // DEBUGMODE + + int16_t delX = ((int16_t)(Data->curx * PXSIZE)) - (int16_t)pl->wx; + int16_t delY = ((int16_t)(Data->cury * PXSIZE)) - (int16_t)pl->wy; bopti_image_t *face = &tiny_npc_male; - for(i=0;iface)){ + for(i = 0; i < FACES; i++) { + if(!strcmp(npc_sprites[i].name, Data->face)) { face = npc_sprites[i].face; } } - dimage( pl->px-P_WIDTH/2+delX, pl->py-P_HEIGHT/2+delY, face); + dimage(pl->px - P_WIDTH / 2 + delX, pl->py - P_HEIGHT / 2 + delY, face); } } - - - void OLD_npc_draw(Game *game) { Player *player = &game->player; - for (uint32_t u=0; umap_level->nbextradata; u++) //uint pour enlever un warning + for(uint32_t u = 0; u < game->map_level->nbextradata; + u++) // uint pour enlever un warning { ExtraData *Data = &game->map_level->extradata[u]; - - if (strcmp(Data->type, "NPC")==0) /* the current data is a NPC */ + if(strcmp(Data->type, "NPC") == 0) /* the current data is a NPC */ { /* TODO : This is for debugging purpose, JUste to render the path */ /* to be followed by the NPC when this will be implemented */ - #if DEBUGMODE +#if DEBUGMODE - if (Data->hasPath==1) /* this NPC has a trajectory */ - { - int NbPoints = Data->path_length+1; - for(int v=0; vhasPath == 1) /* this NPC has a trajectory */ + { + int NbPoints = Data->path_length + 1; + for(int v = 0; v < NbPoints; v++) { - - int16_t deltaX1=((int16_t) (Data->x + Data->xpath[v % NbPoints]) * PXSIZE)-(int16_t) player->wx; - int16_t deltaY1=((int16_t) (Data->y + Data->ypath[v % NbPoints]) * PXSIZE)-(int16_t) player->wy; + int16_t deltaX1 = + ((int16_t)(Data->x + Data->xpath[v % NbPoints]) * + PXSIZE) - + (int16_t)player->wx; + int16_t deltaY1 = + ((int16_t)(Data->y + Data->ypath[v % NbPoints]) * + PXSIZE) - + (int16_t)player->wy; - int16_t deltaX2=((int16_t) (Data->x + Data->xpath[(v+1) % NbPoints]) * PXSIZE)-(int16_t) player->wx; - int16_t deltaY2=((int16_t) (Data->y + Data->ypath[(v+1) % NbPoints]) * PXSIZE)-(int16_t) player->wy; - - dline( player->px + deltaX1, player->py + deltaY1, - player->px + deltaX2, player->py + deltaY2, - PATH_COLOR); - } + int16_t deltaX2 = + ((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) * + PXSIZE) - + (int16_t)player->wx; + int16_t deltaY2 = + ((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) * + PXSIZE) - + (int16_t)player->wy; + + dline(player->px + deltaX1, player->py + deltaY1, + player->px + deltaX2, player->py + deltaY2, + PATH_COLOR); } + } - #endif // DEBUGMODE +#endif // DEBUGMODE - int16_t deltaX=((int16_t) (Data->x * PXSIZE))-(int16_t) player->wx; - int16_t deltaY=((int16_t) (Data->y * PXSIZE))-(int16_t) player->wy; - dimage( player->px-P_WIDTH/2+deltaX, - player->py-P_HEIGHT/2+deltaY, - &tiny_npc_male); - + int16_t deltaX = + ((int16_t)(Data->x * PXSIZE)) - (int16_t)player->wx; + int16_t deltaY = + ((int16_t)(Data->y * PXSIZE)) - (int16_t)player->wy; + dimage(player->px - P_WIDTH / 2 + deltaX, + player->py - P_HEIGHT / 2 + deltaY, &tiny_npc_male); } - } - - } - diff --git a/src/npc.h b/src/npc.h index d6c17cb..aa26b32 100644 --- a/src/npc.h +++ b/src/npc.h @@ -1,29 +1,27 @@ #ifndef NPC_H #define NPC_H - #include #include #include "game.h" #include "memory.h" -enum -{ +enum { NPC_NONE = 0, - NPC_FRIENDLY = 1, //The player's team - NPC_HOSTILE = 2, //to the player + NPC_FRIENDLY = 1, // The player's team + NPC_HOSTILE = 2, // to the player NPC_ALL = 3 }; -typedef struct -{ +typedef struct { /* current coordinates of the NPC */ float curx, cury; - /* initial coordinates of the NPC (needed to get absolute coordinates of path) */ + /* initial coordinates of the NPC (needed to get absolute coordinates of + * path) */ uint32_t x; uint32_t y; /* the ID of the first element of the dialog */ @@ -49,24 +47,24 @@ typedef struct char *face; } NPC; -//Frees then malloc()s a new path to npc -//Useful if you want to safely edit a path +// Frees then malloc()s a new path to npc +// Useful if you want to safely edit a path int npc_clear_path(NPC *npc); -//Adds point x,y to the path of npc -//Won't work on static NPCs, use npc_clear_path before or make them on the heap +// Adds point x,y to the path of npc +// Won't work on static NPCs, use npc_clear_path before or make them on the heap int npc_append_path(uint16_t x, uint16_t y, NPC *npc); -//Clears the NPCs path and creates a new one going to dest, -//avoiding non-walkable tiles -//Returns non-zero on failure +// Clears the NPCs path and creates a new one going to dest, +// avoiding non-walkable tiles +// Returns non-zero on failure int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc); -//realloc()s npcRPG to adequate size and returns a pointer to the new element -//Returns NULL on failure +// realloc()s npcRPG to adequate size and returns a pointer to the new element +// Returns NULL on failure NPC *npc_create(); -//Pops the NPC from npcRPG +// Pops the NPC from npcRPG void npc_remove(NPC *npc); /* Draws the player player. This function should be called after drawing the @@ -80,4 +78,3 @@ void update_npc(NPC *npc); void reload_npc(Game *game); #endif - diff --git a/src/player.c b/src/player.c index dbb443a..fc90f44 100644 --- a/src/player.c +++ b/src/player.c @@ -1,8 +1,8 @@ #include "player.h" +#include "config.h" #include "dialogs.h" #include "game.h" #include "map.h" -#include "config.h" #include "npc.h" #include @@ -15,83 +15,74 @@ extern bopti_image_t npc_police; extern bopti_image_t SGN_Icon_img; extern bopti_image_t INFO_Icon_img; -const Face faces[FACES] = { - {"MALE", &npc_male}, - {"FEMALE", &npc_female}, - {"MILKMAN", &npc_milkman}, - {"POLICE", &npc_police} -}; +const Face faces[FACES] = {{"MALE", &npc_male}, + {"FEMALE", &npc_female}, + {"MILKMAN", &npc_milkman}, + {"POLICE", &npc_police}}; const char one_px_mov[8] = { - 0, -1, /* Up */ - 0, 1, /* Down */ - -1, 0, /* Left */ - 1, 0 /* Right */ + 0, -1, /* Up */ + 0, 1, /* Down */ + -1, 0, /* Left */ + 1, 0 /* Right */ }; /* TODO: Search for all hard tiles in the tileset. hard_tiles is a list of their * IDs */ /* The speed of the player on the diffrent tiles in the walkable layer. */ #define WALKABLE_TILE_MAX 4 -const short int walkable_speed[WALKABLE_TILE_MAX] = { - SPEED, 0, PXSIZE, PXSIZE -}; +const short int walkable_speed[WALKABLE_TILE_MAX] = {SPEED, 0, PXSIZE, PXSIZE}; /* How much damage the player takes on the diffrent tiles in the walkable * layer. */ -const char damage_taken_walkable[WALKABLE_TILE_MAX] = { - 0, 0, 5, 0 -}; +const char damage_taken_walkable[WALKABLE_TILE_MAX] = {0, 0, 5, 0}; extern bopti_image_t demo_player_img; extern NPC *npcRPG; extern uint32_t nbNPC; - void player_draw(Game *game) { Player *player = &game->player; - dimage(player->px-P_WIDTH/2, player->py-P_HEIGHT/2, + dimage(player->px - P_WIDTH / 2, player->py - P_HEIGHT / 2, player->is_male ? &player_male_img : &player_female_img); } -void player_move(Game *game, Direction direction) { +void player_move(Game *game, Direction direction) { Player *player = &game->player; - /* How this player movement will modify the player x and y. */ char dx, dy; - + /* If the player will collide with a hard tile or if the will go outside of * the map. */ - - if(player_collision(game, direction, P_CENTER)){ - + + if(player_collision(game, direction, P_CENTER)) { + /* If the will collide with the center of the player. */ - dx = one_px_mov[direction*2]*player->speed; - dy = one_px_mov[direction*2+1]*player->speed; - + dx = one_px_mov[direction * 2] * player->speed; + dy = one_px_mov[direction * 2 + 1] * player->speed; + player_fix_position(game, dx, dy); - } - else{ + } else { if(player_collision(game, direction, P_RIGHTDOWN) || - player_collision(game, direction, P_LEFTUP)){ - + player_collision(game, direction, P_LEFTUP)) { + /* If the will collide with the edges of the player. */ /* I fix his position so he won't be partially in the tile. */ /* I invert dx and dy to fix the axis where he is not moving on. */ /* Do not replace dx==0 with !dx or dy==0 with !dy, it won't work! */ - dx = one_px_mov[direction*2]*player->speed; - dy = one_px_mov[direction*2+1]*player->speed; - - player_fix_position(game, dx==0, dy==0); + dx = one_px_mov[direction * 2] * player->speed; + dy = one_px_mov[direction * 2 + 1] * player->speed; + + player_fix_position(game, dx == 0, dy == 0); } - + /* If he won't collide with the center, so I just move him normally */ - dx = one_px_mov[direction*2]*player->speed; - dy = one_px_mov[direction*2+1]*player->speed; - + dx = one_px_mov[direction * 2] * player->speed; + dy = one_px_mov[direction * 2 + 1] * player->speed; + player->x += dx; player->y += dy; } @@ -103,38 +94,39 @@ void player_move(Game *game, Direction direction) { void player_action(Game *game) { register size_t i; /* already doing something (action IS NOT with an NPC) */ - if(game->player.isDoingAction) return; + if(game->player.isDoingAction) + return; - if(game->player.canDoSomething && !game->player.isInteractingWithNPC){ + if(game->player.canDoSomething && !game->player.isInteractingWithNPC) { /* we can do something */ /* we indicate that the player is occupied */ game->player.isDoingAction = true; - ExtraData *currentData = &game->map_level->extradata[game->player.whichAction]; + ExtraData *currentData = + &game->map_level->extradata[game->player.whichAction]; - /* we use the correct image as per the class of the item */ + /* we use the correct image as per the class of the item */ bopti_image_t *face; - /* we use the correct image as per the class of the item */ - + /* we use the correct image as per the class of the item */ - if (strcmp("INFO", currentData->type)==0){ + if(strcmp("INFO", currentData->type) == 0) { face = &INFO_Icon_img; - }else if (strcmp("SGN", currentData->type)==0){ + } else if(strcmp("SGN", currentData->type) == 0) { face = &SGN_Icon_img; - }else{ + } else { /* It's a NPC */ /* (Mibi88) TODO: Use string hash + strcmp if the hashes match for * fast string comparison. */ face = NULL; - for(i=0;iface)){ + if(!strcmp(current_face.name, currentData->face)) { face = current_face.face; } } - if(!face) face = &npc_male; - + if(!face) + face = &npc_male; } uint32_t dialogStart = currentData->dialogID; @@ -143,27 +135,30 @@ void player_action(Game *game) { /* when done we release the occupied status of the player */ game->player.isDoingAction = false; - }else if(game->player.canDoSomething && game->player.isInteractingWithNPC){ + } else if(game->player.canDoSomething && + game->player.isInteractingWithNPC) { /* we can do something (action IS with an NPC) */ /* we indicate that the player is occupied */ game->player.isDoingAction = true; NPC *currentNPC = &npcRPG[game->player.whichAction]; - /* we use the correct image as per the class of the item */ + /* we use the correct image as per the class of the item */ - ExtraData *currentData = &game->map_level->extradata[game->player.whichAction]; + ExtraData *currentData = + &game->map_level->extradata[game->player.whichAction]; bopti_image_t *face = &npc_male; /* It's a NPC */ /* (Mibi88) TODO: Use string hash + strcmp if the hashes match for - * fast string comparison. */ + * fast string comparison. */ face = NULL; - for(i=0;iface)){ + if(!strcmp(current_face.name, currentNPC->face)) { face = current_face.face; } - if(!face) face = &npc_male; + if(!face) + face = &npc_male; } dtext(2, 64, C_BLACK, currentData->type); uint32_t dialogStart = currentNPC->dialogID; @@ -172,7 +167,6 @@ void player_action(Game *game) { * talking (the rest of the NPCs pursue their action) */ currentNPC->paused = true; - dialogs_initiate_sequence(game, face, dialogStart); /* when done we release the occupied status of the player */ @@ -180,43 +174,40 @@ void player_action(Game *game) { currentNPC->paused = false; } - - - } bool player_collision(Game *game, Direction direction, - Checkpos nomov_axis_check) { + Checkpos nomov_axis_check) { Player *player = &game->player; /* Where is the tile where he will go to from his position. */ - char dx = one_px_mov[direction*2]; - char dy = one_px_mov[direction*2+1]; + char dx = one_px_mov[direction * 2]; + char dy = one_px_mov[direction * 2 + 1]; - if(!dx){ + if(!dx) { dx += nomov_axis_check; - }else if(!dy){ + } else if(!dy) { dy += nomov_axis_check; } - - dx = dx*(P_WIDTH/2+1); - dy = dy*(P_HEIGHT/2+1); - + + dx = dx * (P_WIDTH / 2 + 1); + dy = dy * (P_HEIGHT / 2 + 1); + /* The tile he will go to. */ - int player_tile_x = player->x+dx; - int player_tile_y = player->y+dy; - + int player_tile_x = player->x + dx; + int player_tile_y = player->y + dy; + /* check where the player is expected to go on the next move */ /* if outside the map, we check if there is a map on the other */ /* side of the current map*/ - if (map_get_walkable(game, player_tile_x, player_tile_y) == MAP_OUTSIDE){ + if(map_get_walkable(game, player_tile_x, player_tile_y) == MAP_OUTSIDE) { // we compute the expected world coordinates accordingly // while taking care of the scaling between fx and cg models (PXSIZE) - int worldX = (player->wx+dx) / PXSIZE; - int worldY = (player->wy+dy) / PXSIZE; + int worldX = (player->wx + dx) / PXSIZE; + int worldY = (player->wy + dy) / PXSIZE; Map *map = map_get_for_coordinates(game, worldX, worldY); - if (map!=NULL && map!=game->map_level){ + if(map != NULL && map != game->map_level) { Map *backupmap = game->map_level; int backupx = player->x; int backupy = player->y; @@ -228,19 +219,20 @@ bool player_collision(Game *game, Direction direction, player->wx = worldX * PXSIZE; player->wy = worldY * PXSIZE; - player->x = (worldX - map->xmin ) * PXSIZE; - player->y = (worldY - map->ymin ) * PXSIZE; + player->x = (worldX - map->xmin) * PXSIZE; + player->y = (worldY - map->ymin) * PXSIZE; + + int on_walkable = map_get_walkable(game, player->x / T_WIDTH, + player->y / T_HEIGHT); + + int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) + ? walkable_speed[on_walkable] + : 0; - int on_walkable = map_get_walkable(game, player->x/T_WIDTH, - player->y/T_HEIGHT); - - int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ? - walkable_speed[on_walkable] : 0; - /* if he's on a hard tile and we need to revert the changes as */ /* tile on the next side of the border is not walkable */ - if(!speed){ + if(!speed) { game->map_level = backupmap; player->x = backupx; player->y = backupy; @@ -257,45 +249,50 @@ bool player_collision(Game *game, Direction direction, } } - /* Handle a negative position differently than a positive one. */ - if(player_tile_x < 0) player_tile_x = player_tile_x/T_WIDTH-1; - else player_tile_x = player_tile_x/T_WIDTH; - - if(player_tile_y < 0) player_tile_y = player_tile_y/T_HEIGHT-1; - else player_tile_y = player_tile_y/T_HEIGHT; - + if(player_tile_x < 0) + player_tile_x = player_tile_x / T_WIDTH - 1; + else + player_tile_x = player_tile_x / T_WIDTH; + + if(player_tile_y < 0) + player_tile_y = player_tile_y / T_HEIGHT - 1; + else + player_tile_y = player_tile_y / T_HEIGHT; + int on_walkable = map_get_walkable(game, player_tile_x, player_tile_y); - - int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ? - walkable_speed[on_walkable] : 0; - + + int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) + ? walkable_speed[on_walkable] + : 0; + /* if he's on a hard tile */ - if(!speed){ + if(!speed) { return true; /* He will collide with it. */ } - + player->speed = speed; - + return false; /* He won't collide with a hard tile. */ } void player_fix_position(Game *game, bool fix_x, bool fix_y) { Player *player = &game->player; - + /* I fix his poition on x or/and on y if y need to, so that he won't be over * the hard tile that he collided with. */ - if(fix_x) player->x = player->x/T_WIDTH*T_WIDTH+P_WIDTH/2; - - if(fix_y) player->y = player->y/T_HEIGHT*T_HEIGHT+P_HEIGHT/2; + if(fix_x) + player->x = player->x / T_WIDTH * T_WIDTH + P_WIDTH / 2; + + if(fix_y) + player->y = player->y / T_HEIGHT * T_HEIGHT + P_HEIGHT / 2; } void player_damage(Game *game, int amount) { Player *player = &game->player; - - player->life-=amount; + + player->life -= amount; /* TODO: Let the player dye if life < 1. */ }; - diff --git a/src/player.h b/src/player.h index 5e246c9..82ae0db 100644 --- a/src/player.h +++ b/src/player.h @@ -1,10 +1,10 @@ #ifndef PLAYER_H #define PLAYER_H -#include #include "config.h" #include "game.h" #include "memory.h" +#include typedef struct { const char *name; @@ -17,9 +17,8 @@ typedef struct { /* to avoid circular references between map.h, game.h and player.h */ /* only methods propotypes are now in dedicated header files */ - /* player_draw() - * + * * Draws the player. This function should be called after drawing the * map! * game: The game struct which contains the player struct used. @@ -27,7 +26,7 @@ typedef struct { void player_draw(Game *game); /* player_move() - * + * * Move the player in a direction. * game: The game struct. * direction: The direction to move the player in. @@ -38,7 +37,7 @@ void player_move(Game *game, Direction direction); void player_action(Game *game); /* player_collision() - * + * * Check if the player is in collision with the map or a NPC. Checkpos is used * to check the axis where the player is not moving. * game: The game struct. @@ -49,7 +48,7 @@ bool player_collision(Game *game, Direction direction, Checkpos nomov_axis_check); /* player_fix_position() - * + * * Fix the position of the player so that he's not a bit inside of a hard block * after a collision. * game: The game struct. @@ -58,9 +57,8 @@ bool player_collision(Game *game, Direction direction, */ void player_fix_position(Game *game, bool fix_x, bool fix_y); - /* player_damage() - * + * * Apply damage to player * game: The game struct. * amount: The amount of damage to apply. @@ -68,4 +66,3 @@ void player_fix_position(Game *game, bool fix_x, bool fix_y); void player_damage(Game *game, int amount); #endif -