Compare commits

...

3 commits

Author SHA1 Message Date
attilavs2
7b3e3aaec8 npc : Résolution du problème de free() sur statique, amélioration de npc_remove
(Setup de débug de npc_pathfind() partiellement commenté également)
2024-08-02 12:04:20 +02:00
attilavs2
66c579db60 npc : npc_remove correct et npc_remove_pos 2024-08-02 09:29:41 +02:00
attilavs2
77d3cc9c9b Revert "npc : Debug, crash pre-main"
This reverts commit 0d8b522543.
2024-08-01 23:33:05 +02:00
6 changed files with 100 additions and 89 deletions

View file

@ -314,9 +314,10 @@ def convert_map(input: str, output: str, params: dict, target):
npc_struct += fxconv.u32(i["dialogID"]) npc_struct += fxconv.u32(i["dialogID"])
npc_struct += fxconv.u32(i["needAction"]) npc_struct += fxconv.u32(i["needAction"])
npc_struct += fxconv.string(i["name"]) npc_struct += fxconv.string(i["name"])
npc_struct += fxconv.u32(len(i["path"]) > 2) npc_struct += fxconv.u8(len(i["path"]) > 2)
npc_struct += fxconv.u32(len(i["path"])//2) npc_struct += fxconv.u8(0)
npc_struct += fxconv.u32(0) npc_struct += fxconv.u8(len(i["path"])//2)
npc_struct += fxconv.u8(0)
xpath = bytes() xpath = bytes()
ypath = bytes() ypath = bytes()
@ -332,7 +333,7 @@ def convert_map(input: str, output: str, params: dict, target):
npc_struct += fxconv.u32(0) # TODO: Type npc_struct += fxconv.u32(0) # TODO: Type
npc_struct += fxconv.u8(0) # TODO: Group npc_struct += fxconv.u8(0) # TODO: Group
npc_struct += fxconv.u8(0) # TODO: Hostile to npc_struct += fxconv.u8(0) # TODO: Hostile to
npc_struct += fxconv.u16(0) # TODO: Padding (what is it ?) npc_struct += fxconv.u16(0) # Padding
map_struct += fxconv.ptr(npc_struct) map_struct += fxconv.ptr(npc_struct)
# Load signs # Load signs
map_struct += fxconv.u32(len(signs)) map_struct += fxconv.u32(len(signs))

View file

@ -2,7 +2,7 @@
#define CONFIG_H #define CONFIG_H
#define USB_FEATURE 0 #define USB_FEATURE 0
#define DEBUGMODE 1 #define DEBUGMODE 0
#define PRECISION 8 #define PRECISION 8
#include <gint/display.h> #include <gint/display.h>

View file

@ -201,12 +201,21 @@ void game_get_inputs(Game *game) {
mynpc->x = player->x; mynpc->x = player->x;
mynpc->y = player->x; mynpc->y = player->x;
mynpc->hasPath = 0; mynpc->hasPath = 0;
mynpc->face = 0; mynpc->owns_path = false;
mynpc->face = 1;
mynpc->paused = 0; mynpc->paused = 0;
mynpc->has_dialog = 0; mynpc->has_dialog = 0;
mynpc->xpath = NULL; mynpc->xpath = NULL;
mynpc->ypath = NULL; mynpc->ypath = NULL;
npc_alloc_path(mynpc); }
while(keydown(KEY_F1)) {
clearevents();
}
}
if(keydown(KEY_F2)) {
npc_remove_pos(0);
while(keydown(KEY_F2)) {
clearevents();
} }
} }

View file

@ -97,9 +97,10 @@ typedef struct {
char *name; char *name;
/* data for NPC's trajectories */ /* data for NPC's trajectories */
uint32_t hasPath; uint8_t hasPath;
uint32_t path_length; uint8_t owns_path;
uint32_t currentPoint; uint8_t path_length;
uint8_t currentPoint;
int16_t *xpath; int16_t *xpath;
int16_t *ypath; int16_t *ypath;

144
src/npc.c
View file

@ -30,58 +30,53 @@ NPC *npc_create() {
void npc_remove(NPC *npc) { void npc_remove(NPC *npc) {
uint32_t pos = (uint32_t)npc - (uint32_t)npc_stack; uint32_t pos = (uint32_t)npc - (uint32_t)npc_stack;
/*if(npc->xpath) if(pos >= NPC_STACK_SIZE)
free(npc->xpath); return;
if(npc->ypath)
free(npc->ypath);*/
if(pos == npc_count) { if(npc->owns_path) {
npc_count--; free(npc->xpath);
free(npc->ypath);
}
if(pos == NPC_STACK_SIZE) {
if(npc_count)
npc_count--;
return; return;
} }
memmove(npc, npc + sizeof(NPC), sizeof(NPC) * (npc_count - pos)); uint32_t move_size = sizeof(NPC) * (npc_count - pos);
if(move_size + pos > NPC_STACK_SIZE)
move_size = NPC_STACK_SIZE - pos;
return; memmove(npc, &npc_stack[++pos], move_size);
if(npc_count)
npc_count--;
} }
void npc_remove_pos(uint32_t pos) { npc_remove(&npc_stack[pos]); }
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_alloc_path(NPC *npc) { int npc_clear_path(NPC *npc) {
npc_clear_path(npc); npc->currentPoint = 0;
npc->hasPath = 0;
npc->path_length = 0;
/*if(npc->xpath) if(npc->owns_path) {
free(npc->xpath); free(npc->xpath);
if(npc->ypath) 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) if(npc->xpath == NULL || npc->ypath == NULL)
return 1; return 1;
return 0; npc->owns_path = true;
}
int npc_clear_path(NPC *npc) {
npc->currentPoint = 0;
npc->hasPath = 0;
if(npc->xpath == NULL || npc->ypath == NULL) {
npc->path_length = 0;
return 1;
}
memset(npc->xpath, 0, npc->path_length * sizeof(uint16_t));
memset(npc->ypath, 0, npc->path_length * sizeof(uint16_t));
npc->path_length = 0;
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 * sizeof(uint16_t) + npc->xpath = realloc(npc->xpath, npc->path_length * 2 + 2);
sizeof(uint16_t)); npc->ypath = realloc(npc->ypath, npc->path_length * 2 + 2);
npc->ypath = realloc(npc->ypath, npc->path_length * sizeof(uint16_t) +
sizeof(uint16_t));
if(npc->xpath == NULL || npc->ypath == NULL) if(npc->xpath == NULL || npc->ypath == NULL)
return 1; return 1;
npc->xpath[npc->path_length] = x - npc->x; npc->xpath[npc->path_length] = x - npc->x;
@ -98,7 +93,7 @@ void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) {
// TODO : Fix // TODO : Fix
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, bool is_alloc) { int16_t dest, NPC *npc) {
if(npc_clear_path(npc)) if(npc_clear_path(npc))
goto as_recons_fail; goto as_recons_fail;
@ -133,8 +128,7 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
npc->ypath[npc->path_length - i - 1] = ty; npc->ypath[npc->path_length - i - 1] = ty;
} }
if(is_alloc) free(came_from);
free(came_from);
npc->hasPath = true; npc->hasPath = true;
@ -142,8 +136,7 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
as_recons_fail: as_recons_fail:
if(is_alloc) free(came_from);
free(came_from);
return 1; return 1;
} }
@ -172,42 +165,49 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
if(map[dest_y * w + dest_x]) if(map[dest_y * w + dest_x])
return 2; return 2;
uint8_t *visited, *gscore, *fscore; npc_clear_path(npc);
int16_t *came_from;
bool is_alloc; uint8_t *visited;
int16_t *came_from;
uint8_t *gscore;
uint8_t *fscore;
/*if we can, take advantage of the on-chip memory*/
if(isSH3() || w * h * 5 > 1024 * 15) { if(isSH3() || w * h * 5 > 1024 * 15) {
is_alloc = true;
visited = malloc(w * h); visited = malloc(w * h);
came_from = malloc(w * h * 2); came_from = malloc(w * h * 2);
gscore = malloc(w * h * 2); gscore = malloc(w * h * 2);
fscore = malloc(w * h * 2); fscore = malloc(w * h * 2);
/*If the buffers won't fit on xyram and we are on fx, alloc will likely if(!visited || !came_from || !gscore || !fscore) {
* fail*/ as_clean(visited, gscore, fscore);
if(!visited || !came_from || !gscore || !fscore) free(came_from);
return 1; return 4;
}
for(i = 0; i < w * h; i++)
visited[i] = 1;
for(i = 0; i < w * h; i++)
came_from[i] = -1;
for(i = 0; i < w * h; i++)
gscore[i] = 255;
for(i = 0; i < w * h; i++)
fscore[i] = 255;
} else { } else {
is_alloc = false;
visited = (void *)xyram; visited = (void *)xyram;
came_from = (void *)(xyram + w * h * sizeof(uint16_t)); gscore = (void *)(xyram + w * h);
gscore = (void *)(xyram + 3 * (w * h)); fscore = (void *)(xyram + w * h * 2);
fscore = (void *)(xyram + 4 * (w * h)); came_from = (void *)(xyram + w * h * 3);
for(i = 0; i < w * h; i++)
visited[i] = 1;
for(i = 0; i < w * h; i++)
came_from[i] = -1;
for(i = 0; i < w * h; i++)
gscore[i] = 255;
for(i = 0; i < w * h; i++)
fscore[i] = 255;
} }
npc_clear_path(npc);
for(i = 0; i < w * h; i++)
visited[i] = 1;
visited[spos] = 0;
for(i = 0; i < w * h; i++)
came_from[i] = -1;
for(i = 0; i < w * h; i++)
gscore[i] = 255;
gscore[spos] = 0;
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);
visited[spos] = 0;
gscore[spos] = 0;
uint8_t bscore; uint8_t bscore;
int32_t bx = x; int32_t bx = x;
@ -229,10 +229,10 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
bscore = fscore[i]; bscore = fscore[i];
} }
if(bx == dest_x && by == dest_y) { if(bx == dest_x && by == dest_y) {
if(is_alloc) as_clean(visited, gscore, fscore);
as_clean(visited, gscore, fscore); return 1 /*as_reconstruct_path(came_from, w, h, spos,
return 0; /*as_reconstruct_path(came_from, w, h, spos, dest_y * w + dest_x, npc)*/
dest_y * w + dest_x, npc, is_alloc);*/ ;
} }
visited[by * w + bx] = 1; visited[by * w + bx] = 1;
@ -262,11 +262,9 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
} }
} }
if(is_alloc){ as_clean(visited, gscore, fscore);
as_clean(visited, gscore, fscore);
free(came_from);
}
free(came_from);
return 3; return 3;
} }
@ -278,8 +276,8 @@ void update_npcs(Game *game) {
} }
for(i = 0; i < npc_count; i++) { for(i = 0; i < npc_count; i++) {
update_npc(&npc_stack[i]); update_npc(&npc_stack[i]);
npc_pathfind(game->player.x, game->player.y, game->map_level, /*npc_pathfind(game->player.x, game->player.y, game->map_level,
&npc_stack[i]); &npc_stack[i]);*/
} }
} }

View file

@ -28,12 +28,14 @@ NPC *npc_create();
* Consider this as a free */ * Consider this as a free */
void npc_remove(NPC *npc); void npc_remove(NPC *npc);
/*Sets the adequate variables of npc so that it's path is cleared*/ /* Pops the NPC at pos from the NPC stack. You would most likely want to use
int npc_clear_path(NPC *npc); * npc_remove instead
* Consider this as a free */
void npc_remove_pos(uint32_t pos);
/* Tries to free then malloc()s a new path to npc /* Frees then malloc()s a new path to npc
* Useful if you want to safely edit a path */ * Useful if you want to safely edit a path */
int npc_alloc_path(NPC *npc); int npc_clear_path(NPC *npc);
/* Adds point x,y to the path of 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 * Won't work on static NPCs, use npc_clear_path before or make them on the
@ -45,8 +47,8 @@ int npc_append_path(uint16_t x, uint16_t y, NPC *npc);
* Returns non-zero on failure */ * Returns non-zero on failure */
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);
/* Draws the player player. This function should be called after drawing the /* Draws every NPC. This function should be called after drawing the
* map! */ * background */
void npc_draw(Game *game); void npc_draw(Game *game);
/* Updates the static NPCs and the NPC stack */ /* Updates the static NPCs and the NPC stack */