diff --git a/assets/converters.py b/assets/converters.py index 2d267f9..b6201d9 100644 --- a/assets/converters.py +++ b/assets/converters.py @@ -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["needAction"]) npc_struct += fxconv.string(i["name"]) - npc_struct += fxconv.u32(len(i["path"]) > 2) - npc_struct += fxconv.u32(len(i["path"])//2) - npc_struct += fxconv.u32(0) + npc_struct += fxconv.u8(len(i["path"]) > 2) + npc_struct += fxconv.u8(0) + npc_struct += fxconv.u8(len(i["path"])//2) + npc_struct += fxconv.u8(0) xpath = 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.u8(0) # TODO: Group 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) # Load signs map_struct += fxconv.u32(len(signs)) diff --git a/src/game.c b/src/game.c index 9741be7..482e46c 100644 --- a/src/game.c +++ b/src/game.c @@ -201,18 +201,22 @@ void game_get_inputs(Game *game) { mynpc->x = player->x; mynpc->y = player->x; mynpc->hasPath = 0; + mynpc->owns_path = false; mynpc->face = 1; mynpc->paused = 0; mynpc->has_dialog = 0; mynpc->xpath = NULL; mynpc->ypath = NULL; } + while(keydown(KEY_F1)) { + clearevents(); + } } if(keydown(KEY_F2)) { npc_remove_pos(0); - /*while(keydown(KEY_F2)) { + while(keydown(KEY_F2)) { clearevents(); - }*/ + } } /* Display Debug Information on screen */ diff --git a/src/game.h b/src/game.h index b9b45da..f15864d 100644 --- a/src/game.h +++ b/src/game.h @@ -97,9 +97,10 @@ typedef struct { char *name; /* data for NPC's trajectories */ - uint32_t hasPath; - uint32_t path_length; - uint32_t currentPoint; + uint8_t hasPath; + uint8_t owns_path; + uint8_t path_length; + uint8_t currentPoint; int16_t *xpath; int16_t *ypath; diff --git a/src/npc.c b/src/npc.c index 44bfb32..41ce657 100644 --- a/src/npc.c +++ b/src/npc.c @@ -6,6 +6,7 @@ #include "map.h" #include +#include #include /*debug*/ #include #include @@ -32,10 +33,10 @@ void npc_remove(NPC *npc) { if(pos >= NPC_STACK_SIZE) return; - if(npc->xpath) + if(npc->owns_path) { free(npc->xpath); - if(npc->ypath) free(npc->ypath); + } if(pos == NPC_STACK_SIZE) { if(npc_count) @@ -46,7 +47,7 @@ void npc_remove(NPC *npc) { if(move_size + pos > NPC_STACK_SIZE) move_size = NPC_STACK_SIZE - pos; - memmove(npc, (void *)(npc + sizeof(NPC)), move_size); + memmove(npc, &npc_stack[++pos], move_size); if(npc_count) npc_count--; } @@ -59,12 +60,17 @@ int npc_clear_path(NPC *npc) { npc->currentPoint = 0; npc->hasPath = 0; npc->path_length = 0; - free(npc->xpath); - free(npc->ypath); + + if(npc->owns_path) { + free(npc->xpath); + free(npc->ypath); + } + npc->xpath = malloc(4); npc->ypath = malloc(4); if(npc->xpath == NULL || npc->ypath == NULL) return 1; + npc->owns_path = true; return 0; } @@ -135,6 +141,8 @@ as_recons_fail: 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) { @@ -159,24 +167,47 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { npc_clear_path(npc); - uint8_t *visited = malloc(w * h); - for(i = 0; i < w * h; i++) - visited[i] = 1; - visited[spos] = 0; + uint8_t *visited; + int16_t *came_from; + uint8_t *gscore; + uint8_t *fscore; - int16_t *came_from = malloc(w * h * 2); - for(i = 0; i < w * h; i++) - came_from[i] = -1; + if(isSH3() || w * h * 5 > 1024 * 15) { + visited = malloc(w * h); + came_from = malloc(w * h * 2); + gscore = malloc(w * h * 2); + fscore = malloc(w * h * 2); + if(!visited || !came_from || !gscore || !fscore) { + as_clean(visited, gscore, fscore); + free(came_from); + 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 { + visited = (void *)xyram; + gscore = (void *)(xyram + w * h); + fscore = (void *)(xyram + w * h * 2); + 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; + } - 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); + visited[spos] = 0; + gscore[spos] = 0; uint8_t bscore; int32_t bx = x; @@ -199,8 +230,9 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { } 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); + return 1 /*as_reconstruct_path(came_from, w, h, spos, + dest_y * w + dest_x, npc)*/ + ; } visited[by * w + bx] = 1; @@ -244,6 +276,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 74e5a57..3d02e01 100644 --- a/src/npc.h +++ b/src/npc.h @@ -28,8 +28,9 @@ NPC *npc_create(); * Consider this as a free */ void npc_remove(NPC *npc); -/* Pops the NPC at pos from the NPC stack - * Consider this as a free*/ +/* Pops the NPC at pos from the NPC stack. You would most likely want to use + * npc_remove instead + * Consider this as a free */ void npc_remove_pos(uint32_t pos); /* Frees then malloc()s a new path to npc @@ -46,8 +47,8 @@ int npc_append_path(uint16_t x, uint16_t y, NPC *npc); * Returns non-zero on failure */ 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 - * map! */ +/* Draws every NPC. This function should be called after drawing the + * background */ void npc_draw(Game *game); /* Updates the static NPCs and the NPC stack */