1#pragma once 2#include "ap_macro.h" 3#include "ap_math.h" 4#include "ap_snes.h" 5 6// Matches ledge direction 7// 0 U D L R LU LD RU RD 0 8#define DIR_LIST X(U) X(D) X(L) X(R) X(LU) X(LD) X(RU) X(RD) 9enum { DIR_NONE, DIR_U, DIR_D, DIR_L, DIR_R, DIR_LU, DIR_LD, DIR_RU, DIR_RD }; 10static const int8_t dir_dx[10] = {0, 0, 0, -1, +1, -1, -1, +1, +1, 0}; 11static const int8_t dir_dy[10] = {0, -1, +1, 0, 0, -1, +1, -1, +1, 0}; 12static const uint8_t dir_cost[10] = {0, 32, 32, 32, 32, 48, 48, 48, 48, 0}; // cost to move 4x4 blocks 13 14static const uint16_t dir_joypad[10] = { 15 [DIR_U] = SNES_UP_MASK, [DIR_D] = SNES_DOWN_MASK, 16 [DIR_L] = SNES_LEFT_MASK, [DIR_R] = SNES_RIGHT_MASK, 17 [DIR_LU] = SNES_UP_MASK | SNES_LEFT_MASK, [DIR_LD] = SNES_DOWN_MASK | SNES_LEFT_MASK, 18 [DIR_RU] = SNES_UP_MASK | SNES_RIGHT_MASK, [DIR_RD] = SNES_DOWN_MASK | SNES_RIGHT_MASK, 19}; 20 21static const struct xy dir_dxy[10] = { 22 [DIR_U] = XY(0, -1), [DIR_D] = XY(0, +1), 23 [DIR_L] = XY(-1, 0), [DIR_R] = XY(+1, 0), 24 [DIR_LU] = XY(-1, -1), [DIR_LD] = XY(-1, +1), 25 [DIR_RU] = XY(+1, -1), [DIR_RD] = XY(+1, +1), 26}; 27static const uint8_t dir_opp[10] = { 28 [DIR_U] = DIR_D, [DIR_D] = DIR_U, 29 [DIR_L] = DIR_R, [DIR_R] = DIR_L, 30 [DIR_LU] = DIR_RD, [DIR_RD] = DIR_LU, 31 [DIR_RU] = DIR_LD, [DIR_LD] = DIR_RU, 32}; 33static const uint8_t dir_cw[10] = { 34 [DIR_U] = DIR_R, [DIR_D] = DIR_L, 35 [DIR_L] = DIR_U, [DIR_R] = DIR_D, 36}; 37static const uint8_t dir_ccw[10] = { 38 [DIR_U] = DIR_L, [DIR_D] = DIR_R, 39 [DIR_L] = DIR_D, [DIR_R] = DIR_D, 40}; 41 42static const char * const dir_names[10] = { 43 [0] = "0", 44#define X(d) [CONCAT(DIR_, d)] = STRINGIFY(d), 45DIR_LIST 46#undef X 47}; 48 49enum { 50#define X(d) CONCAT(DIRBIT_, d) = (1ul << (CONCAT(DIR_, d) - 1)), 51DIR_LIST 52#undef X 53}; 54 55#define NODE_TYPE_LIST \ 56 X(NONE) \ 57 X(ITEM) \ 58 X(CHEST) \ 59 X(TRANSITION) \ 60 X(SWITCH) \ 61 X(SPRITE) \ 62 X(SCRIPT) \ 63 X(OVERLAY) \ 64 X(KEYBLOCK) \ 65 66struct ap_screen; 67struct ap_node { 68 struct ap_screen * screen; 69 struct ap_node * next; 70 struct ap_node * prev; 71 72 struct xy tl; 73 struct xy br; 74 75 uint8_t adjacent_direction; 76 //struct ap_screen ** adjacent_screen; 77 struct ap_node * adjacent_node; 78 struct xy locked_xy; // door is locked if this is 0xFx not 0x82 79 struct ap_node * lock_node; 80 const struct ap_script * script; 81 struct ap_goal * goal; 82 struct ap_item_loc * item_loc; 83 uint8_t overlay_index; 84 85 enum ap_node_type { 86#define X(type) CONCAT(NODE_, type), 87NODE_TYPE_LIST 88#undef X 89 } type; 90 uint8_t tile_attr; 91 uint8_t sprite_type; 92 uint16_t sprite_subtype; 93 union { 94 uint8_t door_type; 95 uint8_t chest_type; 96 }; 97 bool _reachable; 98 bool _debug_blocked; 99 char name[32]; 100 101 // Global Search State 102 struct ap_node_pgsearch { 103 uint64_t iter; 104 //struct xy xy; 105 struct ap_node * from; 106 uint64_t distance; 107 } pgsearch; 108}; 109 110#define PRINODE "%s%s%s" 111#define PRINODEF(n) ((n) ? (n)->name : "(null)"), ((n) && (n)->screen ? " screen=" : ""), ((n) && (n)->screen ? (n)->screen->name : "") 112 113struct ap_screen { 114 struct xy tl; 115 struct xy br; 116 uint8_t quadmask; 117 uint16_t id; 118 uint8_t dungeon_id; 119 uint16_t dungeon_room; 120 uint16_t dungeon_tags; 121 const struct ap_room_tag * room_tags[2]; 122 struct ap_node node_list[1]; 123 const struct ap_screen_info * info; 124 char name[64]; 125 uint8_t attr_cache[0x80][0x80]; 126 //struct ap_graph graph; 127 128 struct ap_node_distance { 129 struct ap_node *src; 130 struct ap_node *dst; 131 uint64_t distance; 132 } * distances; 133 size_t distances_length; 134 size_t distances_capacity; 135}; 136 137struct ap_script { 138 struct xy start_tl; 139 int start_item; 140 const char * sequence; 141 enum script_type { 142 SCRIPT_SEQUENCE, 143 SCRIPT_KILLALL, 144 SCRIPT_KILLDROPS, 145 } type; 146 char name[32]; 147}; 148 149struct xy 150ap_link_xy(); 151 152struct xy 153ap_sprite_xy(uint8_t i); 154 155uint16_t 156ap_map_attr(struct xy xy); 157 158void 159ap_map_bounds(struct xy * topleft, struct xy * bottomright); 160 161struct xy 162ap_map16_to_xy(struct xy tl, uint16_t map16); 163 164void 165ap_print_map_screen(struct ap_screen * screen); 166 167void 168ap_print_map_screen_pair(void); 169 170void 171ap_print_map_graph(); 172 173void 174ap_print_map_full(void); 175 176void 177ap_print_state(void); 178 179uint32_t 180ap_path_heuristic(struct xy src, struct xy dst_tl, struct xy dst_br); 181 182int 183ap_follow_targets(uint16_t * joypad, enum ap_inventory * equip_out); 184 185void 186ap_joypad_setdir(uint16_t * joypad, uint8_t dir); 187 188struct ap_screen * 189ap_update_map_screen(bool force); 190 191int 192ap_pathfind_node(struct ap_node * node, bool commit, int max_distance); 193 194int 195ap_pathfind_sprite(size_t sprite_idx); 196 197int 198ap_set_script(const struct ap_script * script); 199 200int 201ap_map_record_transition_from(struct ap_node * src_node); 202 203bool 204ap_node_islocked(struct ap_node * node, bool *unlockable_out, const struct ap_room_tag ** unlock_tag_out); 205 206void 207ap_node_islocked_print(struct ap_node * node); 208 209void 210ap_map_import(const char * filename); 211 212void 213ap_map_export(const char * filename); 214 215void 216ap_map_tick(void);