mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2024-12-29 13:03:43 +01:00
Using clang-format
This commit is contained in:
parent
eb6cd35830
commit
dafe7032f3
18 changed files with 839 additions and 884 deletions
7
.clang-format
Normal file
7
.clang-format
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
PointerAlignment: Right
|
||||||
|
SpaceBeforeParens: Custom
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: false
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
|
|
||||||
#define USB_FEATURE 0
|
#define USB_FEATURE 0
|
||||||
#define DEBUGMODE 0
|
#define DEBUGMODE 0
|
||||||
|
|
||||||
|
@ -12,8 +11,6 @@
|
||||||
#define GRAYMODEOK 1
|
#define GRAYMODEOK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if GINT_RENDER_RGB
|
#if GINT_RENDER_RGB
|
||||||
/* The tile size */
|
/* The tile size */
|
||||||
#define T_HEIGHT 16
|
#define T_HEIGHT 16
|
||||||
|
@ -36,7 +33,6 @@
|
||||||
#define P_HEIGHT 8
|
#define P_HEIGHT 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* SPEED should NOT be 8 or bigger: it may cause bugs when handling
|
/* SPEED should NOT be 8 or bigger: it may cause bugs when handling
|
||||||
* collisions! */
|
* collisions! */
|
||||||
#define SPEED (PXSIZE * 2)
|
#define SPEED (PXSIZE * 2)
|
||||||
|
|
132
src/dialogs.c
132
src/dialogs.c
|
@ -1,22 +1,20 @@
|
||||||
#include "dialogs.h"
|
#include "dialogs.h"
|
||||||
|
|
||||||
#include <gint/keyboard.h>
|
|
||||||
#include <gint/cpu.h>
|
#include <gint/cpu.h>
|
||||||
|
#include <gint/keyboard.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "events.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "npc.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_HEIGHT 10
|
||||||
#define CHOICE_BOX_PADDING_TOP 3
|
#define CHOICE_BOX_PADDING_TOP 3
|
||||||
|
|
||||||
|
|
||||||
extern font_t fontRPG;
|
extern font_t fontRPG;
|
||||||
#define FONT_USED fontRPG
|
#define FONT_USED fontRPG
|
||||||
|
|
||||||
|
@ -26,7 +24,6 @@ extern font_t fontRPG;
|
||||||
uint32_t *lightVRAMcurrent, *darkVRAMcurrent;
|
uint32_t *lightVRAMcurrent, *darkVRAMcurrent;
|
||||||
#endif // GRAYMODEOK
|
#endif // GRAYMODEOK
|
||||||
|
|
||||||
|
|
||||||
void blit() {
|
void blit() {
|
||||||
dupdate();
|
dupdate();
|
||||||
|
|
||||||
|
@ -39,20 +36,18 @@ void blit() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
int call_before_end(Game *game, unsigned int i),
|
int call_before_end(Game *game, unsigned int i),
|
||||||
bool start_anim,
|
bool start_anim, bool end_anim,
|
||||||
bool end_anim,
|
|
||||||
void for_each_screen(Game *game, unsigned int i),
|
void for_each_screen(Game *game, unsigned int i),
|
||||||
int line_duration, bool update_screen, unsigned int start_i,
|
int line_duration, bool update_screen,
|
||||||
bool wait_continue) {
|
unsigned int start_i, bool wait_continue) {
|
||||||
text = events_parse_string(&game->handler, text);
|
text = events_parse_string(&game->handler, text);
|
||||||
dfont(&FONT_USED);
|
dfont(&FONT_USED);
|
||||||
unsigned int i, n, y = PXSIZE, l = 0;
|
unsigned int i, n, y = PXSIZE, l = 0;
|
||||||
int line_max_chars, return_int = 0;
|
int line_max_chars, return_int = 0;
|
||||||
unsigned int max_lines_amount = (BOX_HEIGHT-2)*PXSIZE/
|
unsigned int max_lines_amount =
|
||||||
(FONT_USED.line_height+PXSIZE);
|
(BOX_HEIGHT - 2) * PXSIZE / (FONT_USED.line_height + PXSIZE);
|
||||||
const char *c;
|
const char *c;
|
||||||
if(start_anim) {
|
if(start_anim) {
|
||||||
/* Run a little fancy animation. */
|
/* Run a little fancy animation. */
|
||||||
|
@ -69,12 +64,13 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
|
|
||||||
/* Draw the part of the face of the player that can fit correctly in
|
/* Draw the part of the face of the player that can fit correctly in
|
||||||
* the dialog drawn. */
|
* the dialog drawn. */
|
||||||
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
|
dsubimage(4 * PXSIZE, 2 * PXSIZE, face, 0, 0, F_WIDTH,
|
||||||
DIMAGE_NONE);
|
(i - 8) * PXSIZE, DIMAGE_NONE);
|
||||||
|
|
||||||
blit();
|
blit();
|
||||||
|
|
||||||
while(game->frame_duration < 20) sleep();
|
while(game->frame_duration < 20)
|
||||||
|
sleep();
|
||||||
game->frame_duration = 0;
|
game->frame_duration = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,23 +78,27 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
* making an animation. */
|
* making an animation. */
|
||||||
game_draw(game);
|
game_draw(game);
|
||||||
drect(0, 0, DWIDTH, BOX_HEIGHT * PXSIZE, C_WHITE);
|
drect(0, 0, DWIDTH, BOX_HEIGHT * PXSIZE, C_WHITE);
|
||||||
drect(0, BOX_HEIGHT*PXSIZE, DWIDTH, (BOX_HEIGHT+1)*PXSIZE, C_BLACK);
|
drect(0, BOX_HEIGHT * PXSIZE, DWIDTH, (BOX_HEIGHT + 1) * PXSIZE,
|
||||||
|
C_BLACK);
|
||||||
dimage(4 * PXSIZE, 2 * PXSIZE, face);
|
dimage(4 * PXSIZE, 2 * PXSIZE, face);
|
||||||
|
|
||||||
if(update_screen) {
|
if(update_screen) {
|
||||||
blit();
|
blit();
|
||||||
|
|
||||||
while(game->frame_duration < 20) sleep();
|
while(game->frame_duration < 20)
|
||||||
|
sleep();
|
||||||
game->frame_duration = 0;
|
game->frame_duration = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* We should start to drawing the text on the x axis at BOX_HEIGHT to avoid
|
/* We should start to drawing the text on the x axis at BOX_HEIGHT to avoid
|
||||||
* drawing on the face. */
|
* drawing on the face. */
|
||||||
for(i = start_i; i < strlen(text); i++) {
|
for(i = start_i; i < strlen(text); i++) {
|
||||||
if(!l && for_each_screen) for_each_screen(game, i);
|
if(!l && for_each_screen)
|
||||||
|
for_each_screen(game, i);
|
||||||
/* Get how many chars we can draw on screen with a padding on the left
|
/* Get how many chars we can draw on screen with a padding on the left
|
||||||
* of BOX_HEIGHT px and on the right of 1 px. */
|
* of BOX_HEIGHT px and on the right of 1 px. */
|
||||||
c = drsize(text+i, &FONT_USED, DWIDTH-(BOX_HEIGHT*PXSIZE+PXSIZE), NULL);
|
c = drsize(text + i, &FONT_USED,
|
||||||
|
DWIDTH - (BOX_HEIGHT * PXSIZE + PXSIZE), NULL);
|
||||||
/* c is a pointer to the last char that can be drawn. So: */
|
/* c is a pointer to the last char that can be drawn. So: */
|
||||||
line_max_chars = c - (text + i);
|
line_max_chars = c - (text + i);
|
||||||
/* TODO: Handle lines that are longer than what I can draw and '\n'. */
|
/* TODO: Handle lines that are longer than what I can draw and '\n'. */
|
||||||
|
@ -109,8 +109,9 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
/* If we found a space, we can draw this line and do the same
|
/* If we found a space, we can draw this line and do the same
|
||||||
* for the next line. */
|
* for the next line. */
|
||||||
if(text[i + n] == ' ') {
|
if(text[i + n] == ' ') {
|
||||||
dtext_opt(BOX_HEIGHT*PXSIZE, y, C_BLACK, C_NONE, DTEXT_LEFT,
|
dtext_opt(BOX_HEIGHT * PXSIZE, y, C_BLACK, C_NONE,
|
||||||
DTEXT_TOP, text+i, n); /* Draw everything. */
|
DTEXT_LEFT, DTEXT_TOP, text + i,
|
||||||
|
n); /* Draw everything. */
|
||||||
/* Increment y by the line height. */
|
/* 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 */
|
i += n; /* We drew everything to i+n */
|
||||||
|
@ -130,20 +131,25 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
/* We drew one entire screen, reset everything to draw the next one.
|
/* We drew one entire screen, reset everything to draw the next one.
|
||||||
*/
|
*/
|
||||||
/* Make a little animation :). */
|
/* Make a little animation :). */
|
||||||
if(update_screen) blit();
|
if(update_screen)
|
||||||
while(game->frame_duration < line_duration) sleep();
|
blit();
|
||||||
|
while(game->frame_duration < line_duration)
|
||||||
|
sleep();
|
||||||
game->frame_duration = 0;
|
game->frame_duration = 0;
|
||||||
/* Ask the user to press SHIFT to continue. */
|
/* 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 :). */
|
/* Make a little animation :). */
|
||||||
if(update_screen) blit();
|
if(update_screen)
|
||||||
|
blit();
|
||||||
if(l >= max_lines_amount - 1) {
|
if(l >= max_lines_amount - 1) {
|
||||||
/* If we drew one entire screen. */
|
/* If we drew one entire screen. */
|
||||||
/* Wait that the SHIFT key is pressed if we should. */
|
/* Wait that the SHIFT key is pressed if we should. */
|
||||||
if(wait_continue) {
|
if(wait_continue) {
|
||||||
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
|
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
|
||||||
~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){
|
~GETKEY_MOD_ALPHA,
|
||||||
|
NULL)
|
||||||
|
.key != KEY_SHIFT) {
|
||||||
sleep();
|
sleep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,31 +159,37 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
/* Reset y and l. */
|
/* Reset y and l. */
|
||||||
y = PXSIZE;
|
y = PXSIZE;
|
||||||
l = 0;
|
l = 0;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
/* Else, wait a bit for the animation. */
|
/* 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;
|
game->frame_duration = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(l < max_lines_amount - 1) {
|
if(l < max_lines_amount - 1) {
|
||||||
/* If we have not filled everthing with text at the end. */
|
/* If we have not filled everthing with text at the end. */
|
||||||
/* Make a little animation :). */
|
/* Make a little animation :). */
|
||||||
if(update_screen) blit();
|
if(update_screen)
|
||||||
while(game->frame_duration < line_duration) sleep();
|
blit();
|
||||||
|
while(game->frame_duration < line_duration)
|
||||||
|
sleep();
|
||||||
game->frame_duration = 0;
|
game->frame_duration = 0;
|
||||||
/* Ask the user to press SHIFT to continue. */
|
/* 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. */
|
/* Update the screen and wait for SHIFT being pressed, if needed. */
|
||||||
if(update_screen) blit();
|
if(update_screen)
|
||||||
|
blit();
|
||||||
if(wait_continue) {
|
if(wait_continue) {
|
||||||
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
|
while(getkey_opt(GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT &
|
||||||
~GETKEY_MOD_ALPHA, NULL).key != KEY_SHIFT){
|
~GETKEY_MOD_ALPHA,
|
||||||
|
NULL)
|
||||||
|
.key != KEY_SHIFT) {
|
||||||
sleep();
|
sleep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(call_before_end) return_int = call_before_end(game, i);
|
if(call_before_end)
|
||||||
|
return_int = call_before_end(game, i);
|
||||||
if(end_anim) {
|
if(end_anim) {
|
||||||
/* Run another little fancy animation if we should. */
|
/* Run another little fancy animation if we should. */
|
||||||
for(i = BOX_HEIGHT; i > 0; i--) {
|
for(i = BOX_HEIGHT; i > 0; i--) {
|
||||||
|
@ -186,12 +198,13 @@ int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
game_draw(game);
|
game_draw(game);
|
||||||
drect(0, 0, DWIDTH, i * PXSIZE, C_WHITE);
|
drect(0, 0, DWIDTH, i * PXSIZE, C_WHITE);
|
||||||
drect(0, i * PXSIZE, DWIDTH, (i + 1) * PXSIZE, C_BLACK);
|
drect(0, i * PXSIZE, DWIDTH, (i + 1) * PXSIZE, C_BLACK);
|
||||||
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
|
dsubimage(4 * PXSIZE, 2 * PXSIZE, face, 0, 0, F_WIDTH,
|
||||||
DIMAGE_NONE);
|
(i - 8) * PXSIZE, DIMAGE_NONE);
|
||||||
|
|
||||||
dupdate();
|
dupdate();
|
||||||
|
|
||||||
while(game->frame_duration < 20) sleep();
|
while(game->frame_duration < 20)
|
||||||
|
sleep();
|
||||||
game->frame_duration = 0;
|
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) {
|
bool dialog_start, bool dialog_end) {
|
||||||
/* Run showtext_opt with some default values. It makes it easier to use in
|
/* Run showtext_opt with some default values. It makes it easier to use in
|
||||||
* simple dialogs. */
|
* simple dialogs. */
|
||||||
dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100,
|
dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL,
|
||||||
true, 0, true);
|
100, true, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Some variables and pointers used to get some arguments passed in
|
/* Some variables and pointers used to get some arguments passed in
|
||||||
* showtext_dialog_ask in _choice_call_before_end. */
|
* showtext_dialog_ask in _choice_call_before_end. */
|
||||||
char *_choices, *_text;
|
char *_choices, *_text;
|
||||||
|
@ -228,7 +240,8 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
|
||||||
drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8),
|
drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8),
|
||||||
(BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE);
|
(BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE);
|
||||||
/* Draw a thick border on the right of the box. */
|
/* Draw a thick border on the right of the box. */
|
||||||
drect(i*(DWIDTH/8), BOX_HEIGHT*PXSIZE, i*(DWIDTH/8)+PXSIZE-1,
|
drect(i * (DWIDTH / 8), BOX_HEIGHT * PXSIZE,
|
||||||
|
i * (DWIDTH / 8) + PXSIZE - 1,
|
||||||
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
|
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
|
||||||
/* Draw a thick border on the bottom of the box. */
|
/* Draw a thick border on the bottom of the box. */
|
||||||
drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8),
|
drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8),
|
||||||
|
@ -236,7 +249,8 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
|
||||||
/* Show everyting on screen. */
|
/* Show everyting on screen. */
|
||||||
blit();
|
blit();
|
||||||
/* Wait some ms so that the animation isn't too fast. */
|
/* Wait some ms so that the animation isn't too fast. */
|
||||||
while(game->frame_duration < 20) sleep();
|
while(game->frame_duration < 20)
|
||||||
|
sleep();
|
||||||
game->frame_duration = 0;
|
game->frame_duration = 0;
|
||||||
}
|
}
|
||||||
/* Calculate the maximal size of a choice. */
|
/* Calculate the maximal size of a choice. */
|
||||||
|
@ -265,12 +279,15 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
|
||||||
do {
|
do {
|
||||||
/* Display the diffrent choices. */
|
/* Display the diffrent choices. */
|
||||||
for(i = 0; i < _choices_amount; i++) {
|
for(i = 0; i < _choices_amount; i++) {
|
||||||
if(i == selected) dtext(i*choice_size+PXSIZE,
|
if(i == selected)
|
||||||
(BOX_HEIGHT+CHOICE_BOX_PADDING_TOP)*PXSIZE,
|
dtext(i * choice_size + PXSIZE,
|
||||||
C_BLACK, ">");
|
(BOX_HEIGHT + CHOICE_BOX_PADDING_TOP) * PXSIZE, C_BLACK,
|
||||||
|
">");
|
||||||
}
|
}
|
||||||
blit();
|
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
|
/* If the player pressed the left arrow key and has not already selected
|
||||||
* the first possible choice. */
|
* the first possible choice. */
|
||||||
if(key == KEY_LEFT && selected > 0) {
|
if(key == KEY_LEFT && selected > 0) {
|
||||||
|
@ -297,8 +314,8 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
|
||||||
/* Move the selection arrow and update the selected item. */
|
/* Move the selection arrow and update the selected item. */
|
||||||
selected++;
|
selected++;
|
||||||
}
|
}
|
||||||
/* If the user has not validated his choice by pressing SHIFT, we loop one
|
/* If the user has not validated his choice by pressing SHIFT, we loop
|
||||||
* more time. */
|
* one more time. */
|
||||||
} while(key != KEY_SHIFT);
|
} while(key != KEY_SHIFT);
|
||||||
/* Make a little animation because we looove little animations ;) */
|
/* 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--) {
|
||||||
|
@ -309,12 +326,14 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
|
||||||
_i, false);
|
_i, false);
|
||||||
drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8),
|
drect(0, (BOX_HEIGHT + 1) * PXSIZE + 1, i * (DWIDTH / 8),
|
||||||
(BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE);
|
(BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, C_WHITE);
|
||||||
drect(i*(DWIDTH/8), BOX_HEIGHT*PXSIZE, i*(DWIDTH/8)+PXSIZE-1,
|
drect(i * (DWIDTH / 8), BOX_HEIGHT * PXSIZE,
|
||||||
|
i * (DWIDTH / 8) + PXSIZE - 1,
|
||||||
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
|
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
|
||||||
drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8),
|
drect(0, (BOX_HEIGHT + CHOICE_BOX_HEIGHT) * PXSIZE, i * (DWIDTH / 8),
|
||||||
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
|
(BOX_HEIGHT + CHOICE_BOX_HEIGHT + 1) * PXSIZE, C_BLACK);
|
||||||
dupdate();
|
dupdate();
|
||||||
while(game->frame_duration < 20) sleep();
|
while(game->frame_duration < 20)
|
||||||
|
sleep();
|
||||||
game->frame_duration = 0;
|
game->frame_duration = 0;
|
||||||
}
|
}
|
||||||
/* Return the selected item because he'll also be returned by showtext_opt.
|
/* Return the selected item because he'll also be returned by showtext_opt.
|
||||||
|
@ -338,9 +357,6 @@ int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start,
|
||||||
end, _choice_screen_call, 100, true, 0, true);
|
end, _choice_screen_call, 100, true, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
|
void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
|
||||||
uint32_t dialogNumber) {
|
uint32_t dialogNumber) {
|
||||||
Dialog *currentDiag = &game->map_level->dialogs[dialogNumber];
|
Dialog *currentDiag = &game->map_level->dialogs[dialogNumber];
|
||||||
|
@ -359,21 +375,23 @@ void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
|
||||||
/* we treat the action - i.e. we show a dialog */
|
/* we treat the action - i.e. we show a dialog */
|
||||||
if(isQuestion == 1) {
|
if(isQuestion == 1) {
|
||||||
/* we have to manage a question */
|
/* we have to manage a question */
|
||||||
int answer = dialogs_ask(game, face, text, true, true,
|
int answer = dialogs_ask(game, face, text, true, true, choices, 2, 0);
|
||||||
choices, 2, 0);
|
|
||||||
|
|
||||||
/* TO DO we need to split the strings conclusion1 and conclusion2 */
|
/* TO DO we need to split the strings conclusion1 and conclusion2 */
|
||||||
/* to extract the "gift" part */
|
/* to extract the "gift" part */
|
||||||
|
|
||||||
if(answer == 0) {
|
if(answer == 0) {
|
||||||
dialogs_text(game, face, conclusion1, true, true);
|
dialogs_text(game, face, conclusion1, true, true);
|
||||||
if (next1!=-1) dialogs_initiate_sequence(game, face, next1);
|
if(next1 != -1)
|
||||||
|
dialogs_initiate_sequence(game, face, next1);
|
||||||
} else {
|
} else {
|
||||||
dialogs_text(game, face, conclusion2, true, true);
|
dialogs_text(game, face, conclusion2, true, true);
|
||||||
if (next2!=-1) dialogs_initiate_sequence(game, face, next2);
|
if(next2 != -1)
|
||||||
|
dialogs_initiate_sequence(game, face, next2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dialogs_text(game, face, text, true, true);
|
dialogs_text(game, face, text, true, true);
|
||||||
if (nextOther!=-1) dialogs_initiate_sequence(game, face, nextOther);
|
if(nextOther != -1)
|
||||||
|
dialogs_initiate_sequence(game, face, nextOther);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#ifndef DIALOG_H
|
#ifndef DIALOG_H
|
||||||
#define DIALOG_H
|
#define DIALOG_H
|
||||||
|
|
||||||
#include <gint/display.h>
|
#include "config.h"
|
||||||
#include <string.h>
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "config.h"
|
#include <gint/display.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/* dialogs_text_opt()
|
/* dialogs_text_opt()
|
||||||
*
|
*
|
||||||
|
@ -37,8 +37,7 @@
|
||||||
|
|
||||||
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
int call_before_end(Game *game, unsigned int i),
|
int call_before_end(Game *game, unsigned int i),
|
||||||
bool start_anim,
|
bool start_anim, bool end_anim,
|
||||||
bool end_anim,
|
|
||||||
void for_each_screen(Game *game, unsigned int i),
|
void for_each_screen(Game *game, unsigned int i),
|
||||||
int line_duration, bool update_screen,
|
int line_duration, bool update_screen,
|
||||||
unsigned int start_i, bool wait_continue);
|
unsigned int start_i, bool wait_continue);
|
||||||
|
|
52
src/events.c
52
src/events.c
|
@ -1,10 +1,8 @@
|
||||||
|
#include "events.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "events.h"
|
|
||||||
|
|
||||||
void events_init_handler(EventHandler *handler) {
|
void events_init_handler(EventHandler *handler) { handler->vars = 0; }
|
||||||
handler->vars = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int events_bind_variable(EventHandler *handler, int *var, char *name) {
|
int events_bind_variable(EventHandler *handler, int *var, char *name) {
|
||||||
if(handler->vars < MAX_VARIABLES) {
|
if(handler->vars < MAX_VARIABLES) {
|
||||||
|
@ -18,45 +16,30 @@ int events_bind_variable(EventHandler *handler, int *var, char *name) {
|
||||||
|
|
||||||
char op_chars[OP_AMOUNT + 1] = " =+-/*%";
|
char op_chars[OP_AMOUNT + 1] = " =+-/*%";
|
||||||
|
|
||||||
int _op_null(int a, int b) {
|
int _op_null(int a, int b) { return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _op_set(int a, int b) {
|
int _op_set(int a, int b) { return b; }
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _op_add(int a, int b) {
|
int _op_add(int a, int b) { return a + b; }
|
||||||
return a+b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _op_sub(int a, int b) {
|
int _op_sub(int a, int b) { return a - b; }
|
||||||
return a-b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _op_div(int a, int b) {
|
int _op_div(int a, int b) {
|
||||||
if(b == 0) return 0;
|
if(b == 0)
|
||||||
|
return 0;
|
||||||
return a / b;
|
return a / b;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _op_mul(int a, int b) {
|
int _op_mul(int a, int b) { return a * b; }
|
||||||
return a*b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _op_mod(int a, int b) {
|
int _op_mod(int a, int b) {
|
||||||
if(b == 0) return 0;
|
if(b == 0)
|
||||||
|
return 0;
|
||||||
return a % b;
|
return a % b;
|
||||||
}
|
}
|
||||||
|
|
||||||
int (*_operations[OP_AMOUNT])(int, int) = {
|
int (*_operations[OP_AMOUNT])(int, int) = {_op_null, _op_set, _op_add, _op_sub,
|
||||||
_op_null,
|
_op_div, _op_mul, _op_mod};
|
||||||
_op_set,
|
|
||||||
_op_add,
|
|
||||||
_op_sub,
|
|
||||||
_op_div,
|
|
||||||
_op_mul,
|
|
||||||
_op_mod
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MIN(a, b) a < b ? a : b
|
#define MIN(a, b) a < b ? a : b
|
||||||
|
|
||||||
|
@ -99,18 +82,21 @@ char *events_parse_string(EventHandler *handler, char *message) {
|
||||||
num_pos = 0;
|
num_pos = 0;
|
||||||
}
|
}
|
||||||
} else if(!in_token) {
|
} else if(!in_token) {
|
||||||
if(message_pos < TOKEN_MAX_SZ) _message_buffer[message_pos++] = c;
|
if(message_pos < TOKEN_MAX_SZ)
|
||||||
|
_message_buffer[message_pos++] = c;
|
||||||
}
|
}
|
||||||
if(in_token && c != ' ') {
|
if(in_token && c != ' ') {
|
||||||
if(tok_type == T_VAR_EDIT) {
|
if(tok_type == T_VAR_EDIT) {
|
||||||
if(var_op != OP_NULL) {
|
if(var_op != OP_NULL) {
|
||||||
if(num_pos < TOKEN_MAX_SZ) num[num_pos++] = c;
|
if(num_pos < TOKEN_MAX_SZ)
|
||||||
|
num[num_pos++] = c;
|
||||||
}
|
}
|
||||||
if(strchr(op_chars, c)) {
|
if(strchr(op_chars, c)) {
|
||||||
var_op = (Operation)(strchr(op_chars, c) - op_chars);
|
var_op = (Operation)(strchr(op_chars, c) - op_chars);
|
||||||
}
|
}
|
||||||
if(var_op == OP_NULL) {
|
if(var_op == OP_NULL) {
|
||||||
if(name_pos < TOKEN_MAX_SZ) var_name[name_pos++] = c;
|
if(name_pos < TOKEN_MAX_SZ)
|
||||||
|
var_name[name_pos++] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c == '$') {
|
if(c == '$') {
|
||||||
|
|
|
@ -15,11 +15,7 @@ typedef struct {
|
||||||
unsigned int vars;
|
unsigned int vars;
|
||||||
} EventHandler;
|
} EventHandler;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { T_NULL, T_VAR_EDIT, T_AMOUNT } Token;
|
||||||
T_NULL,
|
|
||||||
T_VAR_EDIT,
|
|
||||||
T_AMOUNT
|
|
||||||
} Token;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OP_NULL,
|
OP_NULL,
|
||||||
|
|
63
src/game.c
63
src/game.c
|
@ -4,15 +4,14 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <gint/keyboard.h>
|
|
||||||
#include <gint/cpu.h>
|
#include <gint/cpu.h>
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
|
#include <gint/keyboard.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
|
|
||||||
|
|
||||||
extern bopti_image_t SignAction_img;
|
extern bopti_image_t SignAction_img;
|
||||||
|
|
||||||
extern Dialog *dialogRPG;
|
extern Dialog *dialogRPG;
|
||||||
|
@ -21,7 +20,6 @@ extern uint32_t nbNPC;
|
||||||
|
|
||||||
#define MAX_INTERACTION_DISTANCE 12
|
#define MAX_INTERACTION_DISTANCE 12
|
||||||
|
|
||||||
|
|
||||||
void game_logic(Game *game) {
|
void game_logic(Game *game) {
|
||||||
|
|
||||||
update_npcs(game);
|
update_npcs(game);
|
||||||
|
@ -31,12 +29,12 @@ void game_logic(Game *game) {
|
||||||
/* simple distance check along X and Y axis */
|
/* simple distance check along X and Y axis */
|
||||||
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
||||||
if((abs((int)game->player.wx -
|
if((abs((int)game->player.wx -
|
||||||
(int) game->map_level->extradata[i].x*PXSIZE )
|
(int)game->map_level->extradata[i].x * PXSIZE) <
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
MAX_INTERACTION_DISTANCE * PXSIZE) &&
|
||||||
&& (abs((int) game->player.wy -
|
(abs((int)game->player.wy -
|
||||||
(int) game->map_level->extradata[i].y*PXSIZE )
|
(int)game->map_level->extradata[i].y * PXSIZE) <
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
MAX_INTERACTION_DISTANCE * PXSIZE) &&
|
||||||
&& strcmp(game->map_level->extradata[i].type, "NPC") != 0){
|
strcmp(game->map_level->extradata[i].type, "NPC") != 0) {
|
||||||
/* the player can do something */
|
/* the player can do something */
|
||||||
game->player.canDoSomething = true;
|
game->player.canDoSomething = true;
|
||||||
/* we mark the action for futur treatment in player_action() */
|
/* we mark the action for futur treatment in player_action() */
|
||||||
|
@ -50,13 +48,11 @@ void game_logic(Game *game) {
|
||||||
for(uint32_t i = 0; i < nbNPC; i++) {
|
for(uint32_t i = 0; i < nbNPC; i++) {
|
||||||
/* simple distance check along X and Y axis */
|
/* simple distance check along X and Y axis */
|
||||||
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
||||||
if ((abs((int) game->player.wx -
|
if((abs((int)game->player.wx - (int)npcRPG[i].curx * PXSIZE) <
|
||||||
(int) npcRPG[i].curx*PXSIZE )
|
MAX_INTERACTION_DISTANCE * PXSIZE) &&
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
(abs((int)game->player.wy - (int)npcRPG[i].cury * PXSIZE) <
|
||||||
&& (abs((int) game->player.wy -
|
MAX_INTERACTION_DISTANCE * PXSIZE) &&
|
||||||
(int) npcRPG[i].cury*PXSIZE )
|
strcmp(game->map_level->extradata[i].type, "NPC") != 0) {
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
|
||||||
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0){
|
|
||||||
/* the player can do something */
|
/* the player can do something */
|
||||||
game->player.canDoSomething = true;
|
game->player.canDoSomething = true;
|
||||||
/* we mark the action for futur treatment in player_action() */
|
/* 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 */
|
/* else nothing to be done here */
|
||||||
game->player.canDoSomething = false;
|
game->player.canDoSomething = false;
|
||||||
game->player.whichAction = -1;
|
game->player.whichAction = -1;
|
||||||
|
@ -75,16 +70,15 @@ void game_logic(Game *game) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void game_render_indicator(Game *game) {
|
void game_render_indicator(Game *game) {
|
||||||
/* nothing to do for the player so we quit */
|
/* 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 */
|
/* else we draw a small indicator on the screen */
|
||||||
dimage(5, 5, &SignAction_img);
|
dimage(5, 5, &SignAction_img);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void game_draw(Game *game) {
|
void game_draw(Game *game) {
|
||||||
/* Draw everything. */
|
/* Draw everything. */
|
||||||
dclear(C_WHITE);
|
dclear(C_WHITE);
|
||||||
|
@ -106,14 +100,20 @@ 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 */
|
/* Player actions - Prototypes in player.h and implementation in player.c */
|
||||||
if(keydown(KEY_LEFT)) player_move(game, D_LEFT);
|
if(keydown(KEY_LEFT))
|
||||||
if(keydown(KEY_RIGHT)) player_move(game, D_RIGHT);
|
player_move(game, D_LEFT);
|
||||||
if(keydown(KEY_UP)) player_move(game, D_UP);
|
if(keydown(KEY_RIGHT))
|
||||||
if(keydown(KEY_DOWN)) player_move(game, D_DOWN);
|
player_move(game, D_RIGHT);
|
||||||
if(keydown(KEY_SHIFT)) player_action(game);
|
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_OPTN)) {
|
||||||
game->player.is_male = !game->player.is_male;
|
game->player.is_male = !game->player.is_male;
|
||||||
/* TODO: Make something cleaner */
|
/* TODO: Make something cleaner */
|
||||||
|
@ -136,12 +136,13 @@ void game_get_inputs(Game *game) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* if USB is enabled - keybinding for screencapture */
|
/* if USB is enabled - keybinding for screencapture */
|
||||||
#if USB_FEATURE
|
#if USB_FEATURE
|
||||||
|
|
||||||
if(keydown(KEY_7)) game->screenshot = true;
|
if(keydown(KEY_7))
|
||||||
if(keydown(KEY_8)) game->record = !game->record;
|
game->screenshot = true;
|
||||||
|
if(keydown(KEY_8))
|
||||||
|
game->record = !game->record;
|
||||||
|
|
||||||
#endif // USB_FEATURE
|
#endif // USB_FEATURE
|
||||||
}
|
}
|
||||||
|
|
28
src/game.h
28
src/game.h
|
@ -1,29 +1,15 @@
|
||||||
#ifndef GAME_H
|
#ifndef GAME_H
|
||||||
#define GAME_H
|
#define GAME_H
|
||||||
|
|
||||||
|
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The direction where the player is going to. */
|
/* The direction where the player is going to. */
|
||||||
typedef enum {
|
typedef enum { D_UP, D_DOWN, D_LEFT, D_RIGHT } Direction;
|
||||||
D_UP,
|
|
||||||
D_DOWN,
|
|
||||||
D_LEFT,
|
|
||||||
D_RIGHT
|
|
||||||
} Direction;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
P_LEFTUP = -1,
|
|
||||||
P_CENTER = 0,
|
|
||||||
P_RIGHTDOWN = 1
|
|
||||||
} Checkpos;
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum { P_LEFTUP = -1, P_CENTER = 0, P_RIGHTDOWN = 1 } Checkpos;
|
||||||
|
|
||||||
/* Struct that define player parameters */
|
/* Struct that define player parameters */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -33,7 +19,6 @@ typedef struct {
|
||||||
int8_t life; /* How many lives the player still has between 0 and 100. */
|
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. */
|
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 */
|
/* 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 */
|
/* indicates which data are relevant to the current action in the */
|
||||||
|
@ -46,7 +31,6 @@ typedef struct {
|
||||||
bool is_male;
|
bool is_male;
|
||||||
} Player;
|
} Player;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t ID;
|
uint32_t ID;
|
||||||
/* data to be shown in the dialog*/
|
/* data to be shown in the dialog*/
|
||||||
|
@ -64,7 +48,6 @@ typedef struct {
|
||||||
int32_t nextOther;
|
int32_t nextOther;
|
||||||
} Dialog;
|
} Dialog;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* position of the item */
|
/* position of the item */
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
@ -91,7 +74,6 @@ typedef struct {
|
||||||
/* ... this can be extended as per needs ... */
|
/* ... this can be extended as per needs ... */
|
||||||
} ExtraData;
|
} ExtraData;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* width, height and the number of layer of the map */
|
/* width, height and the number of layer of the map */
|
||||||
uint32_t w;
|
uint32_t w;
|
||||||
|
@ -114,7 +96,8 @@ typedef struct {
|
||||||
uint8_t *walkable;
|
uint8_t *walkable;
|
||||||
|
|
||||||
/* structure that contains all the items on the map to interract with */
|
/* 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 */
|
/* data when lloking for proximity of items */
|
||||||
uint32_t nbextradata;
|
uint32_t nbextradata;
|
||||||
ExtraData *extradata;
|
ExtraData *extradata;
|
||||||
|
@ -127,8 +110,6 @@ typedef struct {
|
||||||
uint16_t *layers[];
|
uint16_t *layers[];
|
||||||
} Map;
|
} Map;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* This struct will contain all the data of the game. It will make it possible
|
/* 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
|
* to pass it to the NPCs to let them interact with the player and the rest of
|
||||||
* the world. */
|
* the world. */
|
||||||
|
@ -180,4 +161,3 @@ void game_render_indicator(Game *game);
|
||||||
void game_get_inputs(Game *game);
|
void game_get_inputs(Game *game);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
82
src/main.c
82
src/main.c
|
@ -1,27 +1,26 @@
|
||||||
|
|
||||||
|
#include <gint/cpu.h>
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
#include <gint/keyboard.h>
|
#include <gint/keyboard.h>
|
||||||
#include <gint/timer.h>
|
#include <gint/timer.h>
|
||||||
#include <gint/cpu.h>
|
|
||||||
|
|
||||||
#include <fxlibc/printf.h>
|
#include <fxlibc/printf.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "npc.h"
|
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
#include "npc.h"
|
||||||
|
|
||||||
#if USB_FEATURE
|
#if USB_FEATURE
|
||||||
#include <gint/usb-ff-bulk.h>
|
#include <gint/usb-ff-bulk.h>
|
||||||
#include <gint/usb.h>
|
#include <gint/usb.h>
|
||||||
#endif // USB_FEATURE
|
#endif // USB_FEATURE
|
||||||
|
|
||||||
|
|
||||||
#if GRAYMODEOK
|
#if GRAYMODEOK
|
||||||
#include <gint/gray.h>
|
#include <gint/gray.h>
|
||||||
#endif // GRAYMODEOK
|
#endif // GRAYMODEOK
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "mapdata.h"
|
#include "mapdata.h"
|
||||||
|
@ -30,26 +29,30 @@
|
||||||
|
|
||||||
extern bopti_image_t player_face_img;
|
extern bopti_image_t player_face_img;
|
||||||
|
|
||||||
|
|
||||||
extern Map *worldRPG[];
|
extern Map *worldRPG[];
|
||||||
|
|
||||||
/* Game data (defined in "game.h")*/
|
/* Game data (defined in "game.h")*/
|
||||||
Game game = {
|
Game game = {NULL,
|
||||||
NULL,
|
{12 * PXSIZE, 36 * PXSIZE, 0, 0, 12 * PXSIZE, 36 * PXSIZE, 100,
|
||||||
{12*PXSIZE, 36*PXSIZE, 0, 0, 12*PXSIZE, 36*PXSIZE, 100, SPEED, false, 0, false, false, true},
|
SPEED, false, 0, false, false, true},
|
||||||
{{}, {}, 0},
|
{{}, {}, 0},
|
||||||
false, false, false, 0
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
0
|
||||||
|
|
||||||
/* debug variables*/
|
/* debug variables*/
|
||||||
, false, false, false, 100
|
,
|
||||||
};
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
100};
|
||||||
|
|
||||||
/* screen capture management code. TODO: Clean this up! */
|
/* screen capture management code. TODO: Clean this up! */
|
||||||
|
|
||||||
#if USB_FEATURE
|
#if USB_FEATURE
|
||||||
|
|
||||||
void USB_feature( void )
|
void USB_feature(void) {
|
||||||
{
|
|
||||||
if(game.screenshot && usb_is_open()) {
|
if(game.screenshot && usb_is_open()) {
|
||||||
|
|
||||||
#if GRAYMODEOK // This is a trick, if GRAYMODEOK is defined then
|
#if GRAYMODEOK // This is a trick, if GRAYMODEOK is defined then
|
||||||
|
@ -66,7 +69,6 @@ Game game = {
|
||||||
game.screenshot = false;
|
game.screenshot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(game.record && usb_is_open()) {
|
if(game.record && usb_is_open()) {
|
||||||
|
|
||||||
#if GRAYMODEOK
|
#if GRAYMODEOK
|
||||||
|
@ -113,7 +115,6 @@ int main(void) {
|
||||||
usb_open(interfaces, GINT_CALL_NULL);
|
usb_open(interfaces, GINT_CALL_NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* start grayscale engine */
|
/* start grayscale engine */
|
||||||
|
|
||||||
#if GRAYMODEOK
|
#if GRAYMODEOK
|
||||||
|
@ -128,41 +129,43 @@ int main(void) {
|
||||||
game_draw(&game);
|
game_draw(&game);
|
||||||
|
|
||||||
#if DEBUGMODE && GINT_RENDER_RGB
|
#if DEBUGMODE && GINT_RENDER_RGB
|
||||||
if (game.debug_map)
|
if(game.debug_map) {
|
||||||
{
|
|
||||||
dfont(NULL);
|
dfont(NULL);
|
||||||
drect(5, 5, 390, 55, C_WHITE);
|
drect(5, 5, 390, 55, C_WHITE);
|
||||||
dprint(10, 10, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d",
|
dprint(10, 10, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 0,
|
||||||
0, worldRPG[0]->xmin, worldRPG[0]->ymin,
|
worldRPG[0]->xmin, worldRPG[0]->ymin, worldRPG[0]->xmax,
|
||||||
worldRPG[0]->xmax, worldRPG[0]->ymax);
|
worldRPG[0]->ymax);
|
||||||
dprint(10, 20, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d",
|
dprint(10, 20, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 1,
|
||||||
1, worldRPG[1]->xmin, worldRPG[1]->ymin,
|
worldRPG[1]->xmin, worldRPG[1]->ymin, worldRPG[1]->xmax,
|
||||||
worldRPG[1]->xmax, worldRPG[1]->ymax);
|
worldRPG[1]->ymax);
|
||||||
dprint(10, 30, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d",
|
dprint(10, 30, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 2,
|
||||||
2, worldRPG[2]->xmin, worldRPG[2]->ymin,
|
worldRPG[2]->xmin, worldRPG[2]->ymin, worldRPG[2]->xmax,
|
||||||
worldRPG[2]->xmax, worldRPG[2]->ymax);
|
worldRPG[2]->ymax);
|
||||||
dprint(10, 40, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d",
|
dprint(10, 40, C_RED, "Map[%d] : Xmn %d Ymn %d Xmx %d Ymx %d", 3,
|
||||||
3, worldRPG[3]->xmin, worldRPG[3]->ymin,
|
worldRPG[3]->xmin, worldRPG[3]->ymin, worldRPG[3]->xmax,
|
||||||
worldRPG[3]->xmax, worldRPG[3]->ymax);
|
worldRPG[3]->ymax);
|
||||||
}
|
}
|
||||||
if (game.debug_player)
|
if(game.debug_player) {
|
||||||
{
|
|
||||||
dfont(NULL);
|
dfont(NULL);
|
||||||
drect(5, 55, 390, 75, C_WHITE);
|
drect(5, 55, 390, 75, C_WHITE);
|
||||||
dprint(10, 60, C_BLUE, "X= %d - Y= %d / Wx= %d - Wy= %d",
|
dprint(10, 60, C_BLUE, "X= %d - Y= %d / Wx= %d - Wy= %d",
|
||||||
game.player.x, game.player.y, game.player.wx,
|
game.player.x, game.player.y, game.player.wx,
|
||||||
game.player.wy);
|
game.player.wy);
|
||||||
}
|
}
|
||||||
if (game.debug_extra)
|
if(game.debug_extra) {
|
||||||
{
|
|
||||||
dfont(NULL);
|
dfont(NULL);
|
||||||
for(int i = 0; i < game.map_level->nbextradata; i++)
|
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",
|
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].x,
|
||||||
game.map_level->extradata[i].y,
|
game.map_level->extradata[i].y,
|
||||||
game.map_level->extradata[i].dialogID,
|
game.map_level->extradata[i].dialogID,
|
||||||
game.map_level->dialogs[ game.map_level->extradata[i].dialogID ].ID,
|
game.map_level
|
||||||
game.map_level->dialogs[ game.map_level->extradata[i].dialogID ].conclusion1[0] );
|
->dialogs[game.map_level->extradata[i].dialogID]
|
||||||
|
.ID,
|
||||||
|
game.map_level
|
||||||
|
->dialogs[game.map_level->extradata[i].dialogID]
|
||||||
|
.conclusion1[0]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -180,19 +183,17 @@ int main(void) {
|
||||||
/* Management of the inputs */
|
/* Management of the inputs */
|
||||||
game_get_inputs(&game);
|
game_get_inputs(&game);
|
||||||
/* Run the game at max. 50fps */
|
/* 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 */
|
/* Reset frame_duration for the next frame */
|
||||||
game.frame_duration = 0;
|
game.frame_duration = 0;
|
||||||
} while(!game.exittoOS); // want to exit ?
|
} while(!game.exittoOS); // want to exit ?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* shutdown grayengine*/
|
/* shutdown grayengine*/
|
||||||
#if GRAYMODEOK
|
#if GRAYMODEOK
|
||||||
dgray(DGRAY_OFF);
|
dgray(DGRAY_OFF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* close USB */
|
/* close USB */
|
||||||
#if USB_FEATURE
|
#if USB_FEATURE
|
||||||
usb_close();
|
usb_close();
|
||||||
|
@ -201,4 +202,3 @@ int main(void) {
|
||||||
timer_stop(timer);
|
timer_stop(timer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
src/map.c
28
src/map.c
|
@ -7,7 +7,6 @@
|
||||||
extern Map *worldRPG[];
|
extern Map *worldRPG[];
|
||||||
// extern ExtraData *extraRPG[];
|
// extern ExtraData *extraRPG[];
|
||||||
|
|
||||||
|
|
||||||
void map_render(Game *game) {
|
void map_render(Game *game) {
|
||||||
|
|
||||||
Map *map_level = game->map_level;
|
Map *map_level = game->map_level;
|
||||||
|
@ -27,7 +26,8 @@ void map_render(Game *game) {
|
||||||
* y. */
|
* 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. */
|
/* 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. */
|
/* tile contains the tile to draw. */
|
||||||
short int tile;
|
short int tile;
|
||||||
/* The position where I start drawing */
|
/* The position where I start drawing */
|
||||||
|
@ -80,8 +80,8 @@ void map_render(Game *game) {
|
||||||
for(x = 0; x < dw; x++) {
|
for(x = 0; x < dw; x++) {
|
||||||
/* I get the tile number if his position is inside the map. Then
|
/* I get the tile number if his position is inside the map. Then
|
||||||
* I draw it. */
|
* I draw it. */
|
||||||
if(tx+x>=0 && tx+x < map_level->w &&
|
if(tx + x >= 0 && tx + x < map_level->w && ty + y >= 0 &&
|
||||||
ty+y>=0 && ty+y < map_level->h){
|
ty + y < map_level->h) {
|
||||||
/* index of the current tile */
|
/* 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
|
/* we get the ID of the tile in the current drawable layers
|
||||||
|
@ -123,7 +123,8 @@ void map_render_by_layer(Game *game, int layer) {
|
||||||
* y. */
|
* 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. */
|
/* 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. */
|
/* tile contains the tile to draw. */
|
||||||
short int tile;
|
short int tile;
|
||||||
/* The position where I start drawing */
|
/* The position where I start drawing */
|
||||||
|
@ -171,8 +172,8 @@ void map_render_by_layer(Game *game, int layer) {
|
||||||
for(x = 0; x < dw; x++) {
|
for(x = 0; x < dw; x++) {
|
||||||
/* I get the tile number if his position is inside the map. Then
|
/* I get the tile number if his position is inside the map. Then
|
||||||
* I draw it. */
|
* I draw it. */
|
||||||
if(tx+x>=0 && tx+x < map_level->w &&
|
if(tx + x >= 0 && tx + x < map_level->w && ty + y >= 0 &&
|
||||||
ty+y>=0 && ty+y < map_level->h){
|
ty + y < map_level->h) {
|
||||||
/* index of the current tile */
|
/* 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
|
/* we get the ID of the tile in the current drawable layers
|
||||||
|
@ -200,8 +201,9 @@ short int map_get_tile(Game *game, int x, int y, int l) {
|
||||||
|
|
||||||
/* Get the tile at (x, y) on layer l. Returns the tile ID or MAP_OUTSIDE if
|
/* Get the tile at (x, y) on layer l. Returns the tile ID or MAP_OUTSIDE if
|
||||||
* it's not found. */
|
* it's not found. */
|
||||||
return (x>=0 && x < (int) map_level->w && y>=0 && y < (int) map_level->h) ?
|
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;
|
? map_level->layers[l][y * map_level->w + x]
|
||||||
|
: MAP_OUTSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
short int map_get_walkable(Game *game, int x, int y) {
|
short int map_get_walkable(Game *game, int x, int y) {
|
||||||
|
@ -209,13 +211,13 @@ short int map_get_walkable(Game *game, int x, int y) {
|
||||||
Map *map_level = game->map_level;
|
Map *map_level = game->map_level;
|
||||||
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
|
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
|
||||||
* found. */
|
* found. */
|
||||||
return (x>=0 && x < (int) map_level->w && y>=0 && y < (int) map_level->h) ?
|
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;
|
? map_level->walkable[y * map_level->w + x]
|
||||||
|
: MAP_OUTSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the pointer to the map containing the given position */
|
/* 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 */
|
/* check if the current map contains the point */
|
||||||
if(x >= (int)game->map_level->xmin && x < (int)game->map_level->xmax &&
|
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) {
|
y >= (int)game->map_level->ymin && y < (int)game->map_level->ymax) {
|
||||||
|
|
|
@ -1,24 +1,20 @@
|
||||||
#ifndef MAP_H
|
#ifndef MAP_H
|
||||||
#define MAP_H
|
#define MAP_H
|
||||||
|
|
||||||
|
|
||||||
#define BACKGROUND 0
|
#define BACKGROUND 0
|
||||||
#define FOREGROUND 1
|
#define FOREGROUND 1
|
||||||
|
|
||||||
#define MAP_OUTSIDE -2 /* Returned by get_tile_at_pos if the point is outside of
|
#define MAP_OUTSIDE \
|
||||||
|
-2 /* Returned by get_tile_at_pos if the point is outside of \
|
||||||
* the map. */
|
* the map. */
|
||||||
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Structure 'Map' has been moved to game.h */
|
/* Structure 'Map' has been moved to game.h */
|
||||||
/* to avoid circular references between map.h, game.h and player.h */
|
/* to avoid circular references between map.h, game.h and player.h */
|
||||||
/* only methods propotypes are now in dedicated header files */
|
/* only methods propotypes are now in dedicated header files */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* map_render()
|
/* map_render()
|
||||||
*
|
*
|
||||||
* Draws the map map on the entire screen to be viewed by the player player.
|
* Draws the map map on the entire screen to be viewed by the player player.
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
#ifndef MAPDATA_H
|
#ifndef MAPDATA_H
|
||||||
#define MAPDATA_H
|
#define MAPDATA_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
extern Map *worldRPG[];
|
extern Map *worldRPG[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,3 @@ bool memory_is_in(short int *array, short int array_length, short int item) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,4 +12,3 @@
|
||||||
bool memory_is_in(short int *array, short int array_length, short int item);
|
bool memory_is_in(short int *array, short int array_length, short int item);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
260
src/npc.c
260
src/npc.c
|
@ -1,32 +1,26 @@
|
||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
|
#include "config.h"
|
||||||
#include "dialogs.h"
|
#include "dialogs.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "config.h"
|
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
#include <gint/keyboard.h> /*debug*/
|
#include <gint/keyboard.h> /*debug*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern bopti_image_t tiny_npc_male;
|
extern bopti_image_t tiny_npc_male;
|
||||||
extern bopti_image_t tiny_npc_female;
|
extern bopti_image_t tiny_npc_female;
|
||||||
extern bopti_image_t tiny_npc_milkman;
|
extern bopti_image_t tiny_npc_milkman;
|
||||||
extern bopti_image_t tiny_npc_police;
|
extern bopti_image_t tiny_npc_police;
|
||||||
|
|
||||||
|
|
||||||
NPC *npcRPG;
|
NPC *npcRPG;
|
||||||
uint32_t nbNPC = 0;
|
uint32_t nbNPC = 0;
|
||||||
|
|
||||||
float length( float x, float y )
|
float length(float x, float y) { return sqrtf(x * x + y * y); }
|
||||||
{
|
|
||||||
return sqrtf( x*x+y*y );
|
|
||||||
}
|
|
||||||
|
|
||||||
int npc_clear_path(NPC *npc)
|
int npc_clear_path(NPC *npc) {
|
||||||
{
|
|
||||||
npc->currentPoint = 0;
|
npc->currentPoint = 0;
|
||||||
npc->hasPath = 0;
|
npc->hasPath = 0;
|
||||||
npc->path_length = 0;
|
npc->path_length = 0;
|
||||||
|
@ -34,47 +28,46 @@ int npc_clear_path(NPC *npc)
|
||||||
free(npc->ypath);
|
free(npc->ypath);
|
||||||
npc->xpath = malloc(4);
|
npc->xpath = malloc(4);
|
||||||
npc->ypath = 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int npc_append_path(uint16_t x, uint16_t y, NPC *npc)
|
int npc_append_path(uint16_t x, uint16_t y, NPC *npc) {
|
||||||
{
|
|
||||||
npc->xpath = realloc(npc->xpath, npc->path_length * 2 + 2);
|
npc->xpath = realloc(npc->xpath, npc->path_length * 2 + 2);
|
||||||
npc->ypath = realloc(npc->ypath, npc->path_length * 2 + 2);
|
npc->ypath = realloc(npc->ypath, npc->path_length * 2 + 2);
|
||||||
if(npc->xpath == NULL || npc->ypath == NULL) return 1;
|
if(npc->xpath == NULL || npc->ypath == NULL)
|
||||||
|
return 1;
|
||||||
npc->path_length++;
|
npc->path_length++;
|
||||||
npc->xpath[npc->path_length - 1] = x - npc->x;
|
npc->xpath[npc->path_length - 1] = x - npc->x;
|
||||||
npc->ypath[npc->path_length - 1] = y - npc->y;
|
npc->ypath[npc->path_length - 1] = y - npc->y;
|
||||||
return 0;
|
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(visited);
|
||||||
free(gscore);
|
free(gscore);
|
||||||
free(fscore);
|
free(fscore);
|
||||||
}
|
}
|
||||||
|
|
||||||
int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
|
int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
|
||||||
int16_t dest, NPC *npc)
|
int16_t dest, NPC *npc) {
|
||||||
{
|
if(npc_clear_path(npc))
|
||||||
if(npc_clear_path(npc)) goto as_recons_fail;
|
goto as_recons_fail;
|
||||||
|
|
||||||
int16_t next = came_from[dest];
|
int16_t next = came_from[dest];
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for(i = 0; i < 64; i++)
|
for(i = 0; i < 64; i++) {
|
||||||
{
|
if(npc_append_path((next % w) * T_WIDTH, (next / h) * T_HEIGHT, npc)) {
|
||||||
if(npc_append_path((next%w)*T_WIDTH,(next/h)*T_HEIGHT, npc))
|
|
||||||
{
|
|
||||||
goto as_recons_fail;
|
goto as_recons_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
next = came_from[next];
|
next = came_from[next];
|
||||||
if(next == spos) {
|
if(next == spos) {
|
||||||
if(npc_append_path((spos%w)*T_WIDTH,(spos/h)*T_HEIGHT, npc))
|
if(npc_append_path((spos % w) * T_WIDTH, (spos / h) * T_HEIGHT,
|
||||||
|
npc))
|
||||||
goto as_recons_fail;
|
goto as_recons_fail;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -84,8 +77,7 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
|
||||||
|
|
||||||
// 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];
|
tx = npc->xpath[i];
|
||||||
ty = npc->ypath[i];
|
ty = npc->ypath[i];
|
||||||
npc->xpath[i] = npc->xpath[npc->path_length - i - 1];
|
npc->xpath[i] = npc->xpath[npc->path_length - i - 1];
|
||||||
|
@ -110,8 +102,7 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
|
||||||
// Returns non zero error code on failure
|
// Returns non zero error code on failure
|
||||||
// Custom a* implemetation
|
// Custom a* implemetation
|
||||||
// Unoptimized, may become an issue
|
// Unoptimized, may become an issue
|
||||||
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
|
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
|
||||||
{
|
|
||||||
int32_t i, j;
|
int32_t i, j;
|
||||||
|
|
||||||
int32_t w = full_map->w;
|
int32_t w = full_map->w;
|
||||||
|
@ -124,46 +115,53 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
|
||||||
|
|
||||||
uint8_t *map = full_map->walkable;
|
uint8_t *map = full_map->walkable;
|
||||||
|
|
||||||
if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h) return 2;
|
if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h)
|
||||||
if(map[spos]) return 2;
|
return 2;
|
||||||
if(map[dest_y*w+dest_x]) return 2;
|
if(map[spos])
|
||||||
|
return 2;
|
||||||
|
if(map[dest_y * w + dest_x])
|
||||||
|
return 2;
|
||||||
|
|
||||||
npc_clear_path(npc);
|
npc_clear_path(npc);
|
||||||
|
|
||||||
uint8_t *visited = malloc(w * h);
|
uint8_t *visited = malloc(w * h);
|
||||||
for(i=0; i<w*h; i++) visited[i] = 1;
|
for(i = 0; i < w * h; i++)
|
||||||
|
visited[i] = 1;
|
||||||
visited[spos] = 0;
|
visited[spos] = 0;
|
||||||
|
|
||||||
int16_t *came_from = malloc(w * h * 2);
|
int16_t *came_from = malloc(w * h * 2);
|
||||||
for(i=0; i<w*h; i++) came_from[i] = -1;
|
for(i = 0; i < w * h; i++)
|
||||||
|
came_from[i] = -1;
|
||||||
|
|
||||||
uint8_t *gscore = malloc(w * h * 2);
|
uint8_t *gscore = malloc(w * h * 2);
|
||||||
for(i=0; i<w*h; i++) gscore[i] = 255;
|
for(i = 0; i < w * h; i++)
|
||||||
|
gscore[i] = 255;
|
||||||
gscore[spos] = 0;
|
gscore[spos] = 0;
|
||||||
|
|
||||||
uint8_t *fscore = malloc(w * h * 2);
|
uint8_t *fscore = malloc(w * h * 2);
|
||||||
for(i=0; i<w*h; i++) fscore[i] = 255;
|
for(i = 0; i < w * h; i++)
|
||||||
|
fscore[i] = 255;
|
||||||
fscore[spos] = length(dest_x - x, dest_y - y);
|
fscore[spos] = length(dest_x - x, dest_y - y);
|
||||||
|
|
||||||
uint8_t bscore;
|
uint8_t bscore;
|
||||||
int32_t bx = x;
|
int32_t bx = x;
|
||||||
int32_t by = y;
|
int32_t by = y;
|
||||||
|
|
||||||
for(int iter=0; iter < 64; iter++)
|
for(int iter = 0; iter < 64; iter++) {
|
||||||
{
|
|
||||||
bscore = 255;
|
bscore = 255;
|
||||||
// Cheapest known tile
|
// Cheapest known tile
|
||||||
for(i = 0; i <= w*h; i++)
|
for(i = 0; i <= w * h; i++) {
|
||||||
{
|
if(visited[i])
|
||||||
if(visited[i]) continue;
|
continue;
|
||||||
if(map[i] == 1) continue;
|
if(map[i] == 1)
|
||||||
if(fscore[i] > bscore) continue;
|
continue;
|
||||||
|
if(fscore[i] > bscore)
|
||||||
|
continue;
|
||||||
bx = i % w;
|
bx = i % w;
|
||||||
by = i / w;
|
by = i / w;
|
||||||
bscore = fscore[i];
|
bscore = fscore[i];
|
||||||
}
|
}
|
||||||
if(bx == dest_x && by == dest_y)
|
if(bx == dest_x && by == dest_y) {
|
||||||
{
|
|
||||||
as_clean(visited, gscore, fscore);
|
as_clean(visited, gscore, fscore);
|
||||||
return as_reconstruct_path(came_from, w, h, spos,
|
return as_reconstruct_path(came_from, w, h, spos,
|
||||||
dest_y * w + dest_x, npc);
|
dest_y * w + dest_x, npc);
|
||||||
|
@ -173,22 +171,24 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
|
||||||
|
|
||||||
int att_score;
|
int att_score;
|
||||||
|
|
||||||
for(i = bx-1; i < bx+2; i++)
|
for(i = bx - 1; i < bx + 2; i++) {
|
||||||
{
|
if(i > w)
|
||||||
if(i > w) break;
|
break;
|
||||||
for(j = by-1; j < by+2; j++)
|
for(j = by - 1; j < by + 2; j++) {
|
||||||
{
|
if(j > h)
|
||||||
if(j > h) break;
|
break;
|
||||||
if(map[j*w+i] == 1) continue;
|
if(map[j * w + i] == 1)
|
||||||
if(i == bx && j == by) continue;
|
continue;
|
||||||
|
if(i == bx && j == by)
|
||||||
|
continue;
|
||||||
att_score = gscore[by * w + bx] + round(length(bx - i, by - j));
|
att_score = gscore[by * w + bx] + round(length(bx - i, by - j));
|
||||||
if(att_score < gscore[j*w+i])
|
if(att_score < gscore[j * w + i]) {
|
||||||
{
|
|
||||||
came_from[j * w + i] = by * w + bx;
|
came_from[j * w + i] = by * w + bx;
|
||||||
gscore[j * w + i] = att_score;
|
gscore[j * w + i] = att_score;
|
||||||
fscore[j*w+i] = att_score + round(
|
fscore[j * w + i] =
|
||||||
length(dest_x-i, dest_y-j));
|
att_score + round(length(dest_x - i, dest_y - j));
|
||||||
if(visited[j*w+i]) visited[j*w+i] = 0;
|
if(visited[j * w + i])
|
||||||
|
visited[j * w + i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,11 +200,11 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc)
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
NPC *npc_create()
|
NPC *npc_create() {
|
||||||
{
|
|
||||||
// Use temp pointer to avoid breaking the whole npcRPG on failure
|
// Use temp pointer to avoid breaking the whole npcRPG on failure
|
||||||
void *temp = realloc(npcRPG, (nbNPC + 1) * sizeof(NPC));
|
void *temp = realloc(npcRPG, (nbNPC + 1) * sizeof(NPC));
|
||||||
if(temp == NULL) return NULL;
|
if(temp == NULL)
|
||||||
|
return NULL;
|
||||||
npcRPG = temp;
|
npcRPG = temp;
|
||||||
nbNPC++;
|
nbNPC++;
|
||||||
NPC *npc = &npcRPG[nbNPC - 1];
|
NPC *npc = &npcRPG[nbNPC - 1];
|
||||||
|
@ -213,12 +213,11 @@ NPC *npc_create()
|
||||||
return npc;
|
return npc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void npc_remove(NPC *npc)
|
void npc_remove(NPC *npc) {
|
||||||
{
|
|
||||||
uint32_t pos = ((uint32_t)npc - (uint32_t)npcRPG) / sizeof(NPC);
|
uint32_t pos = ((uint32_t)npc - (uint32_t)npcRPG) / sizeof(NPC);
|
||||||
if(pos > nbNPC-1) return;
|
if(pos > nbNPC - 1)
|
||||||
if(pos == nbNPC-1)
|
return;
|
||||||
{
|
if(pos == nbNPC - 1) {
|
||||||
nbNPC--;
|
nbNPC--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -226,55 +225,42 @@ void npc_remove(NPC *npc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refactoring to make adding complexity cleaner
|
// Refactoring to make adding complexity cleaner
|
||||||
void update_npcs([[maybe_unused]] Game *game)
|
void update_npcs([[maybe_unused]] Game *game) {
|
||||||
{
|
for(uint32_t u = 0; u < nbNPC; u++) {
|
||||||
for( uint32_t u=0; u<nbNPC; u++ )
|
|
||||||
{
|
|
||||||
update_npc(&npcRPG[u]);
|
update_npc(&npcRPG[u]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_npc(NPC *npc)
|
void update_npc(NPC *npc) {
|
||||||
{
|
|
||||||
/* if the NPC has no path or is paused, skip it */
|
/* if the NPC has no path or is paused, skip it */
|
||||||
if (!npc->hasPath || npc->paused==true) return;
|
if(!npc->hasPath || npc->paused == true)
|
||||||
|
return;
|
||||||
|
|
||||||
float vecX = (float) (npc->xpath[ npc->currentPoint ] +
|
float vecX = (float)(npc->xpath[npc->currentPoint] + npc->x) - npc->curx;
|
||||||
npc->x) - npc->curx;
|
float vecY = (float)(npc->ypath[npc->currentPoint] + npc->y) - npc->cury;
|
||||||
float vecY = (float) (npc->ypath[ npc->currentPoint ] +
|
|
||||||
npc->y) - npc->cury;
|
|
||||||
float vecN = length(vecX, vecY);
|
float vecN = length(vecX, vecY);
|
||||||
|
|
||||||
if (vecN>0.5f)
|
if(vecN > 0.5f) {
|
||||||
{
|
|
||||||
vecX /= vecN * 2.0;
|
vecX /= vecN * 2.0;
|
||||||
vecY /= vecN * 2.0;
|
vecY /= vecN * 2.0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
npc->currentPoint++;
|
npc->currentPoint++;
|
||||||
npc->currentPoint = npc->currentPoint % npc->path_length;
|
npc->currentPoint = npc->currentPoint % npc->path_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
npc->curx += vecX;
|
npc->curx += vecX;
|
||||||
npc->cury += vecY;
|
npc->cury += vecY;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reload_npc(Game *game)
|
void reload_npc(Game *game) {
|
||||||
{
|
if(npcRPG != NULL) {
|
||||||
if (npcRPG!=NULL)
|
|
||||||
{
|
|
||||||
free(npcRPG);
|
free(npcRPG);
|
||||||
npcRPG = NULL;
|
npcRPG = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nbNPC = 0;
|
nbNPC = 0;
|
||||||
|
|
||||||
|
for(uint32_t u = 0; u < game->map_level->nbextradata; u++) {
|
||||||
for (uint32_t u=0; u<game->map_level->nbextradata; u++)
|
|
||||||
{
|
|
||||||
ExtraData *Data = &game->map_level->extradata[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 */
|
||||||
|
@ -284,11 +270,11 @@ void reload_npc(Game *game)
|
||||||
}
|
}
|
||||||
|
|
||||||
npcRPG = (NPC *)malloc(nbNPC * sizeof(NPC));
|
npcRPG = (NPC *)malloc(nbNPC * sizeof(NPC));
|
||||||
if(npcRPG == NULL) return;
|
if(npcRPG == NULL)
|
||||||
|
return;
|
||||||
int currentNPC = 0;
|
int currentNPC = 0;
|
||||||
|
|
||||||
for (uint32_t u=0; u<game->map_level->nbextradata; u++)
|
for(uint32_t u = 0; u < game->map_level->nbextradata; u++) {
|
||||||
{
|
|
||||||
ExtraData *Data = &game->map_level->extradata[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 */
|
||||||
|
@ -313,15 +299,12 @@ void reload_npc(Game *game)
|
||||||
void npc_draw(Game *game) {
|
void npc_draw(Game *game) {
|
||||||
Player *pl = &game->player;
|
Player *pl = &game->player;
|
||||||
size_t i;
|
size_t i;
|
||||||
const Face npc_sprites[FACES] = {
|
const Face npc_sprites[FACES] = {{"MALE", &tiny_npc_male},
|
||||||
{"MALE", &tiny_npc_male},
|
|
||||||
{"FEMALE", &tiny_npc_female},
|
{"FEMALE", &tiny_npc_female},
|
||||||
{"MILKMAN", &tiny_npc_milkman},
|
{"MILKMAN", &tiny_npc_milkman},
|
||||||
{"POLICE", &tiny_npc_police}
|
{"POLICE", &tiny_npc_police}};
|
||||||
};
|
|
||||||
|
|
||||||
for (uint32_t u=0; u<nbNPC; u++)
|
for(uint32_t u = 0; u < nbNPC; u++) {
|
||||||
{
|
|
||||||
NPC *Data = &npcRPG[u];
|
NPC *Data = &npcRPG[u];
|
||||||
|
|
||||||
/* Render the path if in debug*/
|
/* Render the path if in debug*/
|
||||||
|
@ -329,25 +312,25 @@ void npc_draw(Game *game) {
|
||||||
if(Data->hasPath == 1) /* this NPC has a trajectory */
|
if(Data->hasPath == 1) /* this NPC has a trajectory */
|
||||||
{
|
{
|
||||||
int NbPoints = Data->path_length + 1;
|
int NbPoints = Data->path_length + 1;
|
||||||
for(int v=0; v<NbPoints; v++)
|
for(int v = 0; v < NbPoints; v++) {
|
||||||
{
|
|
||||||
|
|
||||||
int16_t deltaX1=((int16_t) (Data->x +
|
int16_t deltaX1 =
|
||||||
Data->xpath[v % NbPoints]) * PXSIZE)
|
((int16_t)(Data->x + Data->xpath[v % NbPoints]) * PXSIZE) -
|
||||||
-(int16_t) pl->wx;
|
(int16_t)pl->wx;
|
||||||
int16_t deltaY1=((int16_t) (Data->y +
|
int16_t deltaY1 =
|
||||||
Data->ypath[v % NbPoints]) * PXSIZE)
|
((int16_t)(Data->y + Data->ypath[v % NbPoints]) * PXSIZE) -
|
||||||
-(int16_t) pl->wy;
|
(int16_t)pl->wy;
|
||||||
int16_t deltaX2=((int16_t) (Data->x +
|
int16_t deltaX2 =
|
||||||
Data->xpath[(v+1) % NbPoints]) * PXSIZE)
|
((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) *
|
||||||
-(int16_t) pl->wx;
|
PXSIZE) -
|
||||||
int16_t deltaY2=((int16_t) (Data->y +
|
(int16_t)pl->wx;
|
||||||
Data->ypath[(v+1) % NbPoints]) * PXSIZE)
|
int16_t deltaY2 =
|
||||||
-(int16_t) pl->wy;
|
((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) *
|
||||||
|
PXSIZE) -
|
||||||
|
(int16_t)pl->wy;
|
||||||
|
|
||||||
dline( pl->px + deltaX1, pl->py + deltaY1,
|
dline(pl->px + deltaX1, pl->py + deltaY1, pl->px + deltaX2,
|
||||||
pl->px + deltaX2, pl->py + deltaY2,
|
pl->py + deltaY2, PATH_COLOR);
|
||||||
PATH_COLOR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // DEBUGMODE
|
#endif // DEBUGMODE
|
||||||
|
@ -364,17 +347,14 @@ void npc_draw(Game *game) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OLD_npc_draw(Game *game) {
|
void OLD_npc_draw(Game *game) {
|
||||||
Player *player = &game->player;
|
Player *player = &game->player;
|
||||||
|
|
||||||
for (uint32_t u=0; u<game->map_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];
|
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 */
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -386,15 +366,25 @@ void OLD_npc_draw(Game *game) {
|
||||||
if(Data->hasPath == 1) /* this NPC has a trajectory */
|
if(Data->hasPath == 1) /* this NPC has a trajectory */
|
||||||
{
|
{
|
||||||
int NbPoints = Data->path_length + 1;
|
int NbPoints = Data->path_length + 1;
|
||||||
for(int v=0; v<NbPoints; v++)
|
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 deltaX2 =
|
||||||
int16_t deltaY1=((int16_t) (Data->y + Data->ypath[v % NbPoints]) * PXSIZE)-(int16_t) player->wy;
|
((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) *
|
||||||
|
PXSIZE) -
|
||||||
int16_t deltaX2=((int16_t) (Data->x + Data->xpath[(v+1) % NbPoints]) * PXSIZE)-(int16_t) player->wx;
|
(int16_t)player->wx;
|
||||||
int16_t deltaY2=((int16_t) (Data->y + Data->ypath[(v+1) % NbPoints]) * PXSIZE)-(int16_t) player->wy;
|
int16_t deltaY2 =
|
||||||
|
((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) *
|
||||||
|
PXSIZE) -
|
||||||
|
(int16_t)player->wy;
|
||||||
|
|
||||||
dline(player->px + deltaX1, player->py + deltaY1,
|
dline(player->px + deltaX1, player->py + deltaY1,
|
||||||
player->px + deltaX2, player->py + deltaY2,
|
player->px + deltaX2, player->py + deltaY2,
|
||||||
|
@ -404,16 +394,12 @@ void OLD_npc_draw(Game *game) {
|
||||||
|
|
||||||
#endif // DEBUGMODE
|
#endif // DEBUGMODE
|
||||||
|
|
||||||
int16_t deltaX=((int16_t) (Data->x * PXSIZE))-(int16_t) player->wx;
|
int16_t deltaX =
|
||||||
int16_t deltaY=((int16_t) (Data->y * PXSIZE))-(int16_t) player->wy;
|
((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,
|
dimage(player->px - P_WIDTH / 2 + deltaX,
|
||||||
player->py-P_HEIGHT/2+deltaY,
|
player->py - P_HEIGHT / 2 + deltaY, &tiny_npc_male);
|
||||||
&tiny_npc_male);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
src/npc.h
11
src/npc.h
|
@ -1,15 +1,13 @@
|
||||||
#ifndef NPC_H
|
#ifndef NPC_H
|
||||||
#define NPC_H
|
#define NPC_H
|
||||||
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
|
|
||||||
NPC_NONE = 0,
|
NPC_NONE = 0,
|
||||||
NPC_FRIENDLY = 1, // The player's team
|
NPC_FRIENDLY = 1, // The player's team
|
||||||
|
@ -18,12 +16,12 @@ enum
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
/* current coordinates of the NPC */
|
/* current coordinates of the NPC */
|
||||||
float curx, cury;
|
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 x;
|
||||||
uint32_t y;
|
uint32_t y;
|
||||||
/* the ID of the first element of the dialog */
|
/* the ID of the first element of the dialog */
|
||||||
|
@ -80,4 +78,3 @@ void update_npc(NPC *npc);
|
||||||
void reload_npc(Game *game);
|
void reload_npc(Game *game);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
75
src/player.c
75
src/player.c
|
@ -1,8 +1,8 @@
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "config.h"
|
||||||
#include "dialogs.h"
|
#include "dialogs.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "config.h"
|
|
||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
|
|
||||||
|
@ -15,12 +15,10 @@ extern bopti_image_t npc_police;
|
||||||
extern bopti_image_t SGN_Icon_img;
|
extern bopti_image_t SGN_Icon_img;
|
||||||
extern bopti_image_t INFO_Icon_img;
|
extern bopti_image_t INFO_Icon_img;
|
||||||
|
|
||||||
const Face faces[FACES] = {
|
const Face faces[FACES] = {{"MALE", &npc_male},
|
||||||
{"MALE", &npc_male},
|
|
||||||
{"FEMALE", &npc_female},
|
{"FEMALE", &npc_female},
|
||||||
{"MILKMAN", &npc_milkman},
|
{"MILKMAN", &npc_milkman},
|
||||||
{"POLICE", &npc_police}
|
{"POLICE", &npc_police}};
|
||||||
};
|
|
||||||
|
|
||||||
const char one_px_mov[8] = {
|
const char one_px_mov[8] = {
|
||||||
0, -1, /* Up */
|
0, -1, /* Up */
|
||||||
|
@ -33,22 +31,17 @@ const char one_px_mov[8] = {
|
||||||
* IDs */
|
* IDs */
|
||||||
/* The speed of the player on the diffrent tiles in the walkable layer. */
|
/* The speed of the player on the diffrent tiles in the walkable layer. */
|
||||||
#define WALKABLE_TILE_MAX 4
|
#define WALKABLE_TILE_MAX 4
|
||||||
const short int walkable_speed[WALKABLE_TILE_MAX] = {
|
const short int walkable_speed[WALKABLE_TILE_MAX] = {SPEED, 0, PXSIZE, PXSIZE};
|
||||||
SPEED, 0, PXSIZE, PXSIZE
|
|
||||||
};
|
|
||||||
|
|
||||||
/* How much damage the player takes on the diffrent tiles in the walkable
|
/* How much damage the player takes on the diffrent tiles in the walkable
|
||||||
* layer. */
|
* layer. */
|
||||||
const char damage_taken_walkable[WALKABLE_TILE_MAX] = {
|
const char damage_taken_walkable[WALKABLE_TILE_MAX] = {0, 0, 5, 0};
|
||||||
0, 0, 5, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
extern bopti_image_t demo_player_img;
|
extern bopti_image_t demo_player_img;
|
||||||
|
|
||||||
extern NPC *npcRPG;
|
extern NPC *npcRPG;
|
||||||
extern uint32_t nbNPC;
|
extern uint32_t nbNPC;
|
||||||
|
|
||||||
|
|
||||||
void player_draw(Game *game) {
|
void player_draw(Game *game) {
|
||||||
Player *player = &game->player;
|
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,
|
||||||
|
@ -58,7 +51,6 @@ void player_draw(Game *game) {
|
||||||
void player_move(Game *game, Direction direction) {
|
void player_move(Game *game, Direction direction) {
|
||||||
Player *player = &game->player;
|
Player *player = &game->player;
|
||||||
|
|
||||||
|
|
||||||
/* How this player movement will modify the player x and y. */
|
/* How this player movement will modify the player x and y. */
|
||||||
char dx, dy;
|
char dx, dy;
|
||||||
|
|
||||||
|
@ -72,8 +64,7 @@ void player_move(Game *game, Direction direction) {
|
||||||
dy = one_px_mov[direction * 2 + 1] * player->speed;
|
dy = one_px_mov[direction * 2 + 1] * player->speed;
|
||||||
|
|
||||||
player_fix_position(game, dx, dy);
|
player_fix_position(game, dx, dy);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
if(player_collision(game, direction, P_RIGHTDOWN) ||
|
if(player_collision(game, direction, P_RIGHTDOWN) ||
|
||||||
player_collision(game, direction, P_LEFTUP)) {
|
player_collision(game, direction, P_LEFTUP)) {
|
||||||
|
|
||||||
|
@ -103,21 +94,22 @@ void player_move(Game *game, Direction direction) {
|
||||||
void player_action(Game *game) {
|
void player_action(Game *game) {
|
||||||
register size_t i;
|
register size_t i;
|
||||||
/* already doing something (action IS NOT with an NPC) */
|
/* 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 can do something */
|
||||||
/* we indicate that the player is occupied */
|
/* we indicate that the player is occupied */
|
||||||
game->player.isDoingAction = true;
|
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;
|
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;
|
face = &INFO_Icon_img;
|
||||||
} else if(strcmp("SGN", currentData->type) == 0) {
|
} else if(strcmp("SGN", currentData->type) == 0) {
|
||||||
|
@ -133,8 +125,8 @@ void player_action(Game *game) {
|
||||||
face = current_face.face;
|
face = current_face.face;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!face) face = &npc_male;
|
if(!face)
|
||||||
|
face = &npc_male;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t dialogStart = currentData->dialogID;
|
uint32_t dialogStart = currentData->dialogID;
|
||||||
|
@ -143,7 +135,8 @@ void player_action(Game *game) {
|
||||||
|
|
||||||
/* when done we release the occupied status of the player */
|
/* when done we release the occupied status of the player */
|
||||||
game->player.isDoingAction = false;
|
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 can do something (action IS with an NPC) */
|
||||||
/* we indicate that the player is occupied */
|
/* we indicate that the player is occupied */
|
||||||
game->player.isDoingAction = true;
|
game->player.isDoingAction = true;
|
||||||
|
@ -152,7 +145,8 @@ void player_action(Game *game) {
|
||||||
|
|
||||||
/* 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;
|
bopti_image_t *face = &npc_male;
|
||||||
/* It's a NPC */
|
/* It's a NPC */
|
||||||
/* (Mibi88) TODO: Use string hash + strcmp if the hashes match for
|
/* (Mibi88) TODO: Use string hash + strcmp if the hashes match for
|
||||||
|
@ -163,7 +157,8 @@ void player_action(Game *game) {
|
||||||
if(!strcmp(current_face.name, currentNPC->face)) {
|
if(!strcmp(current_face.name, currentNPC->face)) {
|
||||||
face = current_face.face;
|
face = current_face.face;
|
||||||
}
|
}
|
||||||
if(!face) face = &npc_male;
|
if(!face)
|
||||||
|
face = &npc_male;
|
||||||
}
|
}
|
||||||
dtext(2, 64, C_BLACK, currentData->type);
|
dtext(2, 64, C_BLACK, currentData->type);
|
||||||
uint32_t dialogStart = currentNPC->dialogID;
|
uint32_t dialogStart = currentNPC->dialogID;
|
||||||
|
@ -172,7 +167,6 @@ void player_action(Game *game) {
|
||||||
* talking (the rest of the NPCs pursue their action) */
|
* talking (the rest of the NPCs pursue their action) */
|
||||||
currentNPC->paused = true;
|
currentNPC->paused = true;
|
||||||
|
|
||||||
|
|
||||||
dialogs_initiate_sequence(game, face, dialogStart);
|
dialogs_initiate_sequence(game, face, dialogStart);
|
||||||
|
|
||||||
/* when done we release the occupied status of the player */
|
/* when done we release the occupied status of the player */
|
||||||
|
@ -180,9 +174,6 @@ void player_action(Game *game) {
|
||||||
|
|
||||||
currentNPC->paused = false;
|
currentNPC->paused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool player_collision(Game *game, Direction direction,
|
bool player_collision(Game *game, Direction direction,
|
||||||
|
@ -234,8 +225,9 @@ bool player_collision(Game *game, Direction direction,
|
||||||
int on_walkable = map_get_walkable(game, player->x / T_WIDTH,
|
int on_walkable = map_get_walkable(game, player->x / T_WIDTH,
|
||||||
player->y / T_HEIGHT);
|
player->y / T_HEIGHT);
|
||||||
|
|
||||||
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
|
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX)
|
||||||
walkable_speed[on_walkable] : 0;
|
? walkable_speed[on_walkable]
|
||||||
|
: 0;
|
||||||
|
|
||||||
/* if he's on a hard tile and we need to revert the changes as */
|
/* 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 */
|
/* tile on the next side of the border is not walkable */
|
||||||
|
@ -257,18 +249,22 @@ bool player_collision(Game *game, Direction direction,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Handle a negative position differently than a positive one. */
|
/* Handle a negative position differently than a positive one. */
|
||||||
if(player_tile_x < 0) player_tile_x = player_tile_x/T_WIDTH-1;
|
if(player_tile_x < 0)
|
||||||
else player_tile_x = player_tile_x/T_WIDTH;
|
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;
|
if(player_tile_y < 0)
|
||||||
else player_tile_y = player_tile_y/T_HEIGHT;
|
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 on_walkable = map_get_walkable(game, player_tile_x, player_tile_y);
|
||||||
|
|
||||||
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
|
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX)
|
||||||
walkable_speed[on_walkable] : 0;
|
? walkable_speed[on_walkable]
|
||||||
|
: 0;
|
||||||
|
|
||||||
/* if he's on a hard tile */
|
/* if he's on a hard tile */
|
||||||
if(!speed) {
|
if(!speed) {
|
||||||
|
@ -286,9 +282,11 @@ void player_fix_position(Game *game, bool fix_x, bool fix_y) {
|
||||||
|
|
||||||
/* I fix his poition on x or/and on y if y need to, so that he won't be over
|
/* 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. */
|
* the hard tile that he collided with. */
|
||||||
if(fix_x) player->x = player->x/T_WIDTH*T_WIDTH+P_WIDTH/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;
|
if(fix_y)
|
||||||
|
player->y = player->y / T_HEIGHT * T_HEIGHT + P_HEIGHT / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_damage(Game *game, int amount) {
|
void player_damage(Game *game, int amount) {
|
||||||
|
@ -298,4 +296,3 @@ void player_damage(Game *game, int amount) {
|
||||||
player->life -= amount;
|
player->life -= amount;
|
||||||
/* TODO: Let the player dye if life < 1. */
|
/* TODO: Let the player dye if life < 1. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#ifndef PLAYER_H
|
#ifndef PLAYER_H
|
||||||
#define PLAYER_H
|
#define PLAYER_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -17,7 +17,6 @@ typedef struct {
|
||||||
/* to avoid circular references between map.h, game.h and player.h */
|
/* to avoid circular references between map.h, game.h and player.h */
|
||||||
/* only methods propotypes are now in dedicated header files */
|
/* only methods propotypes are now in dedicated header files */
|
||||||
|
|
||||||
|
|
||||||
/* player_draw()
|
/* player_draw()
|
||||||
*
|
*
|
||||||
* Draws the player. This function should be called after drawing the
|
* Draws the player. This function should be called after drawing the
|
||||||
|
@ -58,7 +57,6 @@ bool player_collision(Game *game, Direction direction,
|
||||||
*/
|
*/
|
||||||
void player_fix_position(Game *game, bool fix_x, bool fix_y);
|
void player_fix_position(Game *game, bool fix_x, bool fix_y);
|
||||||
|
|
||||||
|
|
||||||
/* player_damage()
|
/* player_damage()
|
||||||
*
|
*
|
||||||
* Apply damage to player
|
* Apply damage to player
|
||||||
|
@ -68,4 +66,3 @@ void player_fix_position(Game *game, bool fix_x, bool fix_y);
|
||||||
void player_damage(Game *game, int amount);
|
void player_damage(Game *game, int amount);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue