ap_map.h216 lines · 5.0 KB · raw
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);