diff --git a/src/config.h b/src/config.h index 8410f3a..b6a5bdc 100644 --- a/src/config.h +++ b/src/config.h @@ -2,7 +2,7 @@ #define CONFIG_H #define USB_FEATURE 0 -#define DEBUGMODE 0 +#define DEBUGMODE 1 #define PRECISION 8 #include diff --git a/src/game.c b/src/game.c index 36e86b3..99dd091 100644 --- a/src/game.c +++ b/src/game.c @@ -2,8 +2,8 @@ #include "config.h" #include "map.h" -#include "npc.h" #include "mapdata.h" +#include "npc.h" #include #include @@ -204,6 +204,9 @@ void game_get_inputs(Game *game) { mynpc->face = 0; mynpc->paused = 0; mynpc->has_dialog = 0; + mynpc->xpath = NULL; + mynpc->ypath = NULL; + npc_alloc_path(mynpc); } } diff --git a/src/npc.c b/src/npc.c index b9cf88e..cfaf665 100644 --- a/src/npc.c +++ b/src/npc.c @@ -6,6 +6,7 @@ #include "map.h" #include +#include #include /*debug*/ #include #include @@ -29,6 +30,11 @@ NPC *npc_create() { void npc_remove(NPC *npc) { uint32_t pos = (uint32_t)npc - (uint32_t)npc_stack; + /*if(npc->xpath) + free(npc->xpath); + if(npc->ypath) + free(npc->ypath);*/ + if(pos == npc_count) { npc_count--; return; @@ -40,12 +46,14 @@ void npc_remove(NPC *npc) { float length(float x, float y) { return sqrtf(x * x + y * y); } -int npc_clear_path(NPC *npc) { - npc->currentPoint = 0; - npc->hasPath = 0; - npc->path_length = 0; - free(npc->xpath); - free(npc->ypath); +int npc_alloc_path(NPC *npc) { + npc_clear_path(npc); + + /*if(npc->xpath) + free(npc->xpath); + if(npc->ypath) + free(npc->ypath);*/ + npc->xpath = malloc(4); npc->ypath = malloc(4); if(npc->xpath == NULL || npc->ypath == NULL) @@ -53,9 +61,27 @@ int npc_clear_path(NPC *npc) { return 0; } +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; +} + int npc_append_path(uint16_t x, uint16_t y, NPC *npc) { - npc->xpath = realloc(npc->xpath, npc->path_length * 2 + 2); - npc->ypath = realloc(npc->ypath, npc->path_length * 2 + 2); + npc->xpath = realloc(npc->xpath, npc->path_length * sizeof(uint16_t) + + sizeof(uint16_t)); + npc->ypath = realloc(npc->ypath, npc->path_length * sizeof(uint16_t) + + sizeof(uint16_t)); if(npc->xpath == NULL || npc->ypath == NULL) return 1; npc->xpath[npc->path_length] = x - npc->x; @@ -72,7 +98,7 @@ void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) { // TODO : Fix 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, bool is_alloc) { if(npc_clear_path(npc)) goto as_recons_fail; @@ -107,7 +133,8 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos, npc->ypath[npc->path_length - i - 1] = ty; } - free(came_from); + if(is_alloc) + free(came_from); npc->hasPath = true; @@ -115,11 +142,14 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos, as_recons_fail: - free(came_from); + if(is_alloc) + free(came_from); return 1; } +uint32_t xyram = 0xe500e000 + 32; + /* Custom a* implemetation * Unoptimized, may become an issue */ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { @@ -142,23 +172,39 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { if(map[dest_y * w + dest_x]) return 2; + uint8_t *visited, *gscore, *fscore; + int16_t *came_from; + bool is_alloc; + + /*if we can, take advantage of the on-chip memory*/ + if(isSH3() || w * h * 5 > 1024 * 15) { + is_alloc = true; + visited = malloc(w * h); + came_from = malloc(w * h * 2); + gscore = 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 + * fail*/ + if(!visited || !came_from || !gscore || !fscore) + return 1; + } else { + is_alloc = false; + visited = (void *)xyram; + came_from = (void *)(xyram + w * h * sizeof(uint16_t)); + gscore = (void *)(xyram + 3 * (w * h)); + fscore = (void *)(xyram + 4 * (w * h)); + } + npc_clear_path(npc); - uint8_t *visited = malloc(w * h); for(i = 0; i < w * h; i++) visited[i] = 1; visited[spos] = 0; - - int16_t *came_from = malloc(w * h * 2); for(i = 0; i < w * h; i++) came_from[i] = -1; - - uint8_t *gscore = malloc(w * h * 2); for(i = 0; i < w * h; i++) gscore[i] = 255; gscore[spos] = 0; - - uint8_t *fscore = malloc(w * h * 2); for(i = 0; i < w * h; i++) fscore[i] = 255; fscore[spos] = length(dest_x - x, dest_y - y); @@ -183,9 +229,10 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { bscore = fscore[i]; } if(bx == dest_x && by == dest_y) { - as_clean(visited, gscore, fscore); - return as_reconstruct_path(came_from, w, h, spos, - dest_y * w + dest_x, npc); + if(is_alloc) + as_clean(visited, gscore, fscore); + return 0; /*as_reconstruct_path(came_from, w, h, spos, + dest_y * w + dest_x, npc, is_alloc);*/ } visited[by * w + bx] = 1; @@ -215,9 +262,11 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { } } - as_clean(visited, gscore, fscore); + if(is_alloc){ + as_clean(visited, gscore, fscore); + free(came_from); + } - free(came_from); return 3; } @@ -229,6 +278,8 @@ void update_npcs(Game *game) { } for(i = 0; i < npc_count; i++) { update_npc(&npc_stack[i]); + npc_pathfind(game->player.x, game->player.y, game->map_level, + &npc_stack[i]); } } diff --git a/src/npc.h b/src/npc.h index 8c7f83e..4b0192e 100644 --- a/src/npc.h +++ b/src/npc.h @@ -28,10 +28,13 @@ NPC *npc_create(); * Consider this as a free */ void npc_remove(NPC *npc); -/* Frees then malloc()s a new path to npc - * Useful if you want to safely edit a path */ +/*Sets the adequate variables of npc so that it's path is cleared*/ int npc_clear_path(NPC *npc); +/* Tries to free then malloc()s a new path to npc + * Useful if you want to safely edit a path */ +int npc_alloc_path(NPC *npc); + /* Adds point x,y to the path of npc * Won't work on static NPCs, use npc_clear_path before or make them on the * heap */