|
| 1 | +#include <stdbool.h> |
| 2 | +#include "dungeon_info.h" |
| 3 | +#include "gfx.h" |
| 4 | +#include "text.h" |
| 5 | +#include "z64.h" |
| 6 | +#include "dpad.h" |
| 7 | +#include "hints.h" |
| 8 | + |
| 9 | +bool update_first_time = false; |
| 10 | +uint8_t current_hint_index = 0; |
| 11 | +uint8_t menu_hint_cooldown = 20; |
| 12 | +uint32_t hint_textbox_ids[40]; |
| 13 | +int8_t hint_textbox_types[40]; |
| 14 | + |
| 15 | +uint32_t *current_hints_array = NULL; |
| 16 | +uint32_t hint_always_ids[10]; |
| 17 | +uint32_t hint_foolish_ids[10]; |
| 18 | +uint32_t hint_goals_ids[10]; |
| 19 | +uint32_t hint_sometimes_ids[10]; |
| 20 | +uint8_t hint_total_found[4]; |
| 21 | + |
| 22 | +menu_category_t menu_hints_categories[] = { |
| 23 | + { 0, "Always"}, |
| 24 | + { 1, "Foolish"}, |
| 25 | + { 2, "Goals"}, |
| 26 | + { 3, "Sometimes"}, |
| 27 | +}; |
| 28 | + |
| 29 | +bool hint_menu_is_drawn() { |
| 30 | + return show_hint_info; |
| 31 | +} |
| 32 | + |
| 33 | +void init_hints_ids() { |
| 34 | + for (uint8_t i = 0; i < 40; i++) { |
| 35 | + hint_textbox_ids[i] = CFG_HINTS_IDS_AND_TYPES[2*i] + 1000; |
| 36 | + hint_textbox_types[i] = CFG_HINTS_IDS_AND_TYPES[2*i + 1]; |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +bool flags_get_hint(int hint_index) { |
| 41 | + return (extended_savectx.hints[hint_index / 8] & (1 << (hint_index % 8))) > 0; |
| 42 | +} |
| 43 | + |
| 44 | +void flags_set_hint(int hint_index) { |
| 45 | + //draw_debug_int(4, hint_index); |
| 46 | + extended_savectx.hints[hint_index / 8] |= 1 << (hint_index % 8); |
| 47 | +} |
| 48 | + |
| 49 | +void update_hints() |
| 50 | +{ |
| 51 | + uint8_t iAlways = 0; |
| 52 | + uint8_t iFoolish = 0; |
| 53 | + uint8_t iGoals = 0; |
| 54 | + uint8_t iSometimes = 0; |
| 55 | + for (uint8_t i = 0; i < 40; i++) { |
| 56 | + if (flags_get_hint(i) && hint_textbox_types[i] < 20) { |
| 57 | + switch (hint_textbox_types[i]) { |
| 58 | + case 2: { |
| 59 | + hint_always_ids[iAlways] = hint_textbox_ids[i]; |
| 60 | + iAlways++; |
| 61 | + break; |
| 62 | + } |
| 63 | + case 3: { |
| 64 | + hint_foolish_ids[iFoolish] = hint_textbox_ids[i]; |
| 65 | + iFoolish++; |
| 66 | + break; |
| 67 | + } |
| 68 | + case 4: { |
| 69 | + hint_goals_ids[iGoals] = hint_textbox_ids[i]; |
| 70 | + iGoals++; |
| 71 | + break; |
| 72 | + } |
| 73 | + case 5: { |
| 74 | + hint_sometimes_ids[iSometimes] = hint_textbox_ids[i]; |
| 75 | + iSometimes++; |
| 76 | + break; |
| 77 | + } |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + hint_total_found[0] = iAlways; |
| 82 | + hint_total_found[1] = iFoolish; |
| 83 | + hint_total_found[2] = iGoals; |
| 84 | + hint_total_found[3] = iSometimes; |
| 85 | +} |
| 86 | + |
| 87 | +void message_id_check(z64_game_t* play, uint16_t textId) |
| 88 | +{ |
| 89 | + // Displaced code |
| 90 | + Message_OpenText(play, textId); |
| 91 | + |
| 92 | + //draw_debug_int(0, textId); |
| 93 | + for (uint8_t i = 0; i < 40; i++) { |
| 94 | + if (hint_textbox_ids[i] == textId && !(flags_get_hint(i))) { |
| 95 | + flags_set_hint(i); |
| 96 | + // Update the duplicate if there is one. |
| 97 | + if (hint_textbox_types[i] > 20 && i > 0) { |
| 98 | + flags_set_hint(i - 1); |
| 99 | + } |
| 100 | + if (i < 39 && hint_textbox_types[i + 1] > 20) { |
| 101 | + flags_set_hint(i + 1); |
| 102 | + } |
| 103 | + update_hints(); |
| 104 | + break; |
| 105 | + } |
| 106 | + } |
| 107 | +} |
| 108 | + |
| 109 | +void draw_hints(z64_disp_buf_t* db) { |
| 110 | + |
| 111 | + db->p = db->buf; |
| 112 | + if ((z64_game.common.input[0].raw.pad.du || z64_game.common.input[0].raw.pad.l) && z64_game.common.input[0].raw.pad.a) { |
| 113 | + if (menu_hint_cooldown == 20) { |
| 114 | + show_hint_info = show_hint_info ? false : true; |
| 115 | + } |
| 116 | + |
| 117 | + if (menu_hint_cooldown > 0) { |
| 118 | + menu_hint_cooldown--; |
| 119 | + } |
| 120 | + } |
| 121 | + if (menu_hint_cooldown < 20) { |
| 122 | + menu_hint_cooldown--; |
| 123 | + if (menu_hint_cooldown == 0) { |
| 124 | + menu_hint_cooldown = 20; |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + gSPDisplayList(db->p++, &setup_db); |
| 129 | + if (show_hint_info) { |
| 130 | + |
| 131 | + if (!update_first_time) { |
| 132 | + update_hints(); |
| 133 | + update_first_time = true; |
| 134 | + } |
| 135 | + |
| 136 | + if (z64_game.common.input[0].pad_pressed.dr) { |
| 137 | + current_hint_cat_index++; |
| 138 | + if (current_hint_cat_index > 3) { |
| 139 | + current_hint_cat_index = 0; |
| 140 | + } |
| 141 | + } |
| 142 | + if (z64_game.common.input[0].pad_pressed.dl) { |
| 143 | + if (current_hint_cat_index == 0) { |
| 144 | + current_hint_cat_index = 3; |
| 145 | + } else { |
| 146 | + current_hint_cat_index--; |
| 147 | + } |
| 148 | + } |
| 149 | + |
| 150 | + switch (current_hint_cat_index) { |
| 151 | + case 0: { |
| 152 | + current_hints_array = hint_always_ids; |
| 153 | + break; |
| 154 | + } |
| 155 | + case 1: { |
| 156 | + current_hints_array = hint_foolish_ids; |
| 157 | + break; |
| 158 | + } |
| 159 | + case 2: { |
| 160 | + current_hints_array = hint_goals_ids; |
| 161 | + break; |
| 162 | + } |
| 163 | + case 3: { |
| 164 | + current_hints_array = hint_sometimes_ids; |
| 165 | + break; |
| 166 | + } |
| 167 | + } |
| 168 | + |
| 169 | + // Set up dimensions |
| 170 | + int font_width = 6; |
| 171 | + int font_height = 11; |
| 172 | + int padding = 2; |
| 173 | + int rows = 7; |
| 174 | + int bg_width = 30 * font_width; |
| 175 | + int bg_height = (rows * font_height) + ((rows + 1) * padding); |
| 176 | + int bg_left = 30; |
| 177 | + int bg_top = 30; |
| 178 | + |
| 179 | + int start_top = bg_top + padding + 1; |
| 180 | + uint16_t left = bg_left + padding; |
| 181 | + |
| 182 | + // Draw background |
| 183 | + gDPSetCombineMode(db->p++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); |
| 184 | + for (int i = 0; i < rows; i++) { |
| 185 | + uint16_t line_top = bg_top + i * (font_height + padding) + padding; |
| 186 | + gDPPipeSync(db->p++); |
| 187 | + if (i % 2) { |
| 188 | + gDPSetPrimColor(db->p++, 0, 0, 0x00, 0x00, 0x00, 0xD0); |
| 189 | + } |
| 190 | + else { |
| 191 | + gDPSetPrimColor(db->p++, 0, 0, 0x00, 0x00, 0x00, 0xDA); |
| 192 | + } |
| 193 | + gSPTextureRectangle(db->p++, |
| 194 | + bg_left<<2, line_top<<2, |
| 195 | + (bg_left + bg_width)<<2, (line_top + font_height + padding)<<2, |
| 196 | + 0, |
| 197 | + 0, 0, |
| 198 | + 1<<10, 1<<10); |
| 199 | + } |
| 200 | + |
| 201 | + gDPPipeSync(db->p++); |
| 202 | + gDPSetCombineMode(db->p++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); |
| 203 | + gDPSetPrimColor(db->p++, 0, 0, 120, 255, 100, 0xFF); |
| 204 | + |
| 205 | + text_print_size(db, "HINTS", left + bg_width / 2 - 3 * font_width, start_top, font_width, font_height); |
| 206 | + gDPSetPrimColor(db->p++, 0, 0, 255, 255, 255, 255); |
| 207 | + colorRGBA8_t white = { 255, 255, 255, 255}; |
| 208 | + for (int i = 0; i < 4; i++) { |
| 209 | + menu_category_t *d = &(menu_hints_categories[i]); |
| 210 | + int top = start_top + ((font_height + padding) * (i + 1)) + 1; |
| 211 | + if (i != current_hint_cat_index) { |
| 212 | + text_print_size(db, d->name, left, top + 5, font_width, font_height); |
| 213 | + text_print_size(db, "Found : ", left + 10 * font_width, top + 5, font_width, font_height); |
| 214 | + draw_int_size(db, hint_total_found[i], left + 20*font_width, top + 5, white, font_width, font_height); |
| 215 | + } |
| 216 | + } |
| 217 | + menu_category_t* d = &(menu_hints_categories[current_hint_cat_index]); |
| 218 | + int top = start_top + ((font_height + padding) * (current_hint_cat_index + 1)) + 1; |
| 219 | + gDPSetPrimColor(db->p++, 0, 0, 0xE0, 0xE0, 0x10, 255); |
| 220 | + colorRGBA8_t yellow = { 0xE0, 0xE0, 0x10, 255}; |
| 221 | + text_print_size(db, d->name, left, top + 5, font_width, font_height); |
| 222 | + text_print_size(db, "Found : ", left + 10 * font_width, top + 5, font_width, font_height); |
| 223 | + draw_int_size(db, hint_total_found[current_hint_cat_index], left + 20 * font_width, top + 5, yellow, font_width, font_height); |
| 224 | + |
| 225 | + if (current_hints_array != NULL && hint_total_found[current_hint_cat_index] > 0) { |
| 226 | + if (z64_ctxt.input[0].pad_pressed.dd) { |
| 227 | + current_hint_index++; |
| 228 | + if (current_hint_index > hint_total_found[current_hint_cat_index] - 1) { |
| 229 | + current_hint_index = 0; |
| 230 | + } |
| 231 | + z64_DisplayTextbox(&z64_game, current_hints_array[current_hint_index], 0); |
| 232 | + } |
| 233 | + } |
| 234 | + } |
| 235 | +} |
0 commit comments