alttp.c158 lines · 5.2 KB · raw
1#include "alttp_public.h"
2#include "ap_item.h"
3#include "ap_macro.h"
4#include "ap_map.h"
5#include "ap_math.h"
6#include "ap_plan.h"
7#include "ap_req.h"
8#include "ap_snes.h"
9
10void
11ap_tick(uint32_t frame, uint16_t * joypad) {
12    assert_bp(frame == 0 || frame == ap_frame + 1);
13    ap_frame = frame;
14
15    *ap_emu->info_string_ptr = ap_info_string;
16    ap_sprites_update();
17    ap_ancillia_update();
18    ap_item_update();
19
20    // Cheating!
21    //*(uint8_t *) (uintptr_t) ap_ram.ignore_sprites = 0xFF;
22    *(uint8_t *) (uintptr_t) ap_ram.health_current = *ap_ram.health_capacity;
23    *(uint8_t *) (uintptr_t) ap_ram.inventory_bombs = 10;
24    *(uint8_t *) (uintptr_t) ap_ram.inventory_quiver = 10;
25    *(uint8_t *) (uintptr_t) ap_ram.inventory_hammer = 1;
26    //*(uint8_t *) (uintptr_t) ap_ram.inventory_gloves = 1;
27    *(uint8_t *) (uintptr_t) &ap_ram.inventory_base[INVENTORY_LAMP] = 1;
28
29    ap_req_update();
30
31    static bool has_imported = false;
32    if (!has_imported) {
33        LOG("importing");
34        ap_map_import("map.19.txt");
35        //ap_map_import("map_state.5.00019532.txt");
36        //ap_map_import("map_state.7.00021016.txt");
37        has_imported = true;
38    } else if (frame == 100 && false) {
39        ap_map_export("map_state_reflect.txt");
40        ap_print_state();
41        ap_print_map_full();
42        //ap_graph_print();
43        LOGB("Current requirements satisfied: %s", ap_req_print(NULL));
44        ap_print_map_screen(NULL);
45        //ap_print_goals();
46        //exit(0);
47    }
48
49    if (ap_manual_mode) {
50        return;
51    }
52
53    if (JOYPAD_EVENT(Y)) {
54        LOG("dumping");
55        ap_print_map_screen(NULL);
56    }
57    if (JOYPAD_TEST(X)) return;
58    /*
59    if (JOYPAD_EVENT(START)) {
60        JOYPAD_CLEAR(START);
61        if (frame > 60) ap_emu->save("home");
62    }
63    */
64    *joypad = 0;
65    //INFO("citem: %#x; %#x %#x %#x", *ap_ram.current_item, *ap_ram.module_index, *ap_ram.submodule_index, *ap_ram.link_state);
66
67// 0x07 In house/dungeon
68// 0x09 In OW
69// 0x0B Overworld Mode (special overworld)
70// 0x0E Dialog or Inventory
71    uint8_t module_index = *ap_ram.module_index;
72    uint8_t submodule_index = *ap_ram.submodule_index;
73    uint8_t sub_submodule_index = *ap_ram.sub_submodule_index;
74    //LOG("Module: %x; Submodule: %x", module_index, submodule_index);
75    //INFO("Module: %#x; Submodule: %#x; %d", module_index, submodule_index, frame);
76    switch (module_index) {
77    case 0x07:
78        if (submodule_index == 0x0E || sub_submodule_index != 0x00) {
79            // Inter-room transition; load in progress if sub_submodule_index != 0
80            INFO("main: %#x; sub: %#x; subsub: %#x %u", module_index, submodule_index, sub_submodule_index, frame);
81            return;
82        }
83    case 0x09:
84    case 0x0B:
85        if (submodule_index == 0x08 || submodule_index == 0x10) {
86            // Stairs; keep following targets (even though we can't change direction);
87            enum ap_inventory equip = *ap_ram.current_item;
88            ap_follow_targets(joypad, &equip);
89        }
90        if (submodule_index != 0x00) {
91            return;
92        }
93        break;
94        //if (frame % 2) JOYPAD_SET(START);
95        // fallthrough
96    case 0x0E:
97        break;
98    default:
99        return;
100    }
101    static int extra_crystal_time = 0;
102    if (*ap_ram.crystal_timer != 0 || extra_crystal_time != 0) {
103        if (*ap_ram.crystal_timer != 0) {
104            extra_crystal_time = 200;
105        } else {
106            extra_crystal_time--;
107        }
108        INFO("Waiting for crystal to drop (%d, %d)", *ap_ram.crystal_timer, extra_crystal_time);
109        *joypad = 0;
110        return;
111    }
112
113    struct xy topleft, bottomright;
114    ap_map_bounds(&topleft, &bottomright);
115    struct xy link = ap_link_xy();
116
117    if (ap_sprites[0].type == 0xC1 && ap_sprites[0].active && XYIN(ap_sprites[0].tl, topleft, bottomright)) {
118        INFO("Waiting for aghanim's cutscene");
119        return;
120    }
121
122    ap_debug = JOYPAD_TEST(START);
123    ap_map_tick();
124    if (*ap_ram.link_state == LINK_STATE_HOLDING_BIG_ROCK) {
125        JOYPAD_MASH(A, 0x01);
126    } else if (*ap_ram.link_state == LINK_STATE_RECVING_ITEM || *ap_ram.link_state == LINK_STATE_RECVING_ITEM2) {
127        JOYPAD_MASH(A, 0x01);
128    } else if (*ap_ram.link_state == LINK_STATE_FALLING_HOLE && *ap_ram.link_falling >= 2) {
129        INFO("Falling into a hole...");
130    } else if (*ap_ram.link_state != LINK_STATE_GROUND
131            && *ap_ram.link_state != LINK_STATE_FALLING_HOLE) {
132        INFO("Link state: %#x", *ap_ram.link_state);
133    } else {
134        if (!JOYPAD_TEST(Y)) {
135            ap_plan_evaluate(joypad);
136        }
137    }
138
139    static uint16_t x = 0;
140    if (x++ == 40000) { // && false) {
141        //ap_print_map_full();
142        //ap_graph_print();
143        LOGB("Current requirements satisfied: %s", ap_req_print(NULL));
144        char filename[128];
145        snprintf(filename, sizeof filename, "map_state.8.%08u.txt", frame);
146        //ap_map_export(filename);
147        x = 0;
148    }
149
150    //INFO("citem: %#x; %#x %#x %#x", *ap_ram.current_item, *ap_ram.module_index, *ap_ram.submodule_index, *ap_ram.link_state);
151    //LOG("Link %d %d %u %u", *ap_ram.link_dx, *ap_ram.link_dy, *ap_ram.link_x, *ap_ram.link_y);
152    //INFO("item: %#x", *ap_ram.recving_item);
153
154    //INFO_HEXDUMP(b);
155    if (frame % 2) {
156        //JOYPAD_SET(A);
157    }
158}