SBird1337 преди 6 години
родител
ревизия
3d03e1d61a
променени са 7 файла, в които са добавени 1540 реда и са изтрити 1 реда
  1. 1
    1
      g3headers
  2. 560
    0
      src/pokedex/pokedex.c
  3. 183
    0
      src/pokedex/pokedex_common.c
  4. 71
    0
      src/pokedex/pokedex_common.h
  5. 397
    0
      src/pokedex/pokedex_detail.c
  6. 231
    0
      src/pokedex/pokedex_region.c
  7. 97
    0
      src/pokedex/pokedex_string.s

+ 1
- 1
g3headers

@@ -1 +1 @@
1
-Subproject commit 9f790f1f0ac16ed8f80556e8f74e824836fc1950
1
+Subproject commit f332778115f7c814f63d2192bcd4bce5504ecf00

+ 560
- 0
src/pokedex/pokedex.c Целия файл

@@ -0,0 +1,560 @@
1
+#include <agb_debug.h>
2
+#include <constants/pkmns.h>
3
+#include <pokeagb/pokeagb.h>
4
+#include <pokedex/pdexArrow.h>
5
+#include <pokedex/pdexBall.h>
6
+#include <pokedex/pdexBg.h>
7
+#include <pokedex/pdexScrollBar.h>
8
+#include <pokedex/pdexSelectHalf.h>
9
+
10
+#include "pokedex_common.h"
11
+
12
+#define TB_TITLE 0
13
+#define TB_PKMN 1
14
+#define TB_SEEN 2
15
+#define TB_CAUGHT 3
16
+#define TB_MAIN 4
17
+
18
+#define TB_SEEN_Y (6)
19
+#define TB_CAUGHT_Y 3
20
+
21
+#define DEX_SCROLL_MIN 23
22
+#define DEX_SCROLL_MAX 146
23
+#define SCROLL_SPEED_MAX 6
24
+
25
+void pdex_load(void);
26
+void pdex_vblank_handler(void);
27
+void pdex_loop(u8 tid);
28
+void pdex_cb_handler(void);
29
+
30
+extern const pchar pdex_str_title[];
31
+extern const pchar pdex_str_seen[];
32
+extern const pchar pdex_str_caught[];
33
+extern const pchar pdex_str_empty[];
34
+
35
+static const u8 pdex_y_offset[] = {19, 35, 51, 67, 83, 99, 115, 131};
36
+static const u16 scroll_speed_delays[] = {20, 20, 20, 20, 10, 5, 0};
37
+
38
+struct TextboxTemplate pdex_boxes[] = {
39
+    {.bg_id = 0, .x = 11, .y = 0, .width = 10, .height = 2, .pal_id = 15, .charbase = 1},
40
+    {.bg_id = 0, .x = 2, .y = 2, .width = 10, .height = 2, .pal_id = 15, .charbase = 21},
41
+    {.bg_id = 0, .x = 3, .y = 13, .width = 9, .height = 3, .pal_id = 15, .charbase = 41},
42
+    {.bg_id = 0, .x = 3, .y = 16, .width = 9, .height = 2, .pal_id = 15, .charbase = 59},
43
+
44
+    {.bg_id = 1, .x = 16, .y = 0, .width = 11, .height = 32, .pal_id = 15, .charbase = 77},
45
+
46
+    {.bg_id = 0xFF},
47
+};
48
+
49
+s16 pdex_get_y_offset(s8 n) {
50
+    s8 modOffset = n + pokedex_context->hardware_scroll_amount;
51
+    if (modOffset < -1) {
52
+        modOffset += 16;
53
+    }
54
+
55
+    if (modOffset > 14) {
56
+        modOffset -= 16;
57
+    }
58
+    return (19 + (16 * modOffset));
59
+}
60
+
61
+void pdex_main_box_species_fill(s8 n, u16 species, bool seen, bool caught) {
62
+    seen = true;
63
+    s16 y = pdex_get_y_offset(n);
64
+    rboxid_fill_rectangle(TB_MAIN, 0, 0, y, 11 * 8, 16);
65
+    const pchar *stringToPrint = (seen || caught) ? &pokemon_names[species][0] : &pdex_str_empty[0];
66
+    const pchar stringWhitespace[] = {0x0, 0xFF};
67
+    fmt_int_10(string_buffer, pokedex_context->cursor_position_top + n, 2, 3);
68
+    pstrcat(string_buffer, &stringWhitespace[0]);
69
+    pstrcat(string_buffer, stringToPrint);
70
+    rboxid_print(TB_MAIN, FONT_DEX_STD, 4, y, &pdex_text_color, 0, string_buffer);
71
+}
72
+
73
+void pdex_update_balls(void) {
74
+    for (u8 i = 0; i < 8; ++i) {
75
+        if (pdex_lazy_lookup_entry(i + pokedex_context->cursor_position_top)->caught)
76
+            OBJID_SHOW(pokedex_context->ball_oams[i]);
77
+        else
78
+            OBJID_HIDE(pokedex_context->ball_oams[i]);
79
+    }
80
+}
81
+
82
+void pdex_update_page_full() {
83
+    rboxid_clear_pixels(TB_MAIN, 0);
84
+    for (u16 i = pokedex_context->cursor_position_top; i < pokedex_context->cursor_position_top + 8; ++i) {
85
+        pdex_main_box_species_fill(i - pokedex_context->cursor_position_top, pdex_lazy_lookup_entry(i)->species,
86
+                                   pdex_lazy_lookup_entry(i)->seen, pdex_lazy_lookup_entry(i)->caught);
87
+    }
88
+    pdex_update_balls();
89
+    rboxid_update_tilemap_and_tileset(TB_MAIN);
90
+}
91
+
92
+void pdex_load_sc(void) {
93
+    rboxid_clear_pixels(TB_SEEN, 0);
94
+    rboxid_clear_pixels(TB_CAUGHT, 0);
95
+    u32 seen = pokedex_count(false) + 10;
96
+    u32 caught = pokedex_count(true);
97
+    pchar seenBuffer[4];
98
+    pchar caughtBuffer[4];
99
+    fmt_int_10(seenBuffer, seen, 0, MAX3_COUNT_DIGITS(seen));
100
+    fmt_int_10(caughtBuffer, caught, 0, MAX3_COUNT_DIGITS(caught));
101
+
102
+    u32 twidthSeen = font_get_width_of_string(FONT_DEX_STD, seenBuffer, 0x0000);
103
+    u32 twidthCaught = font_get_width_of_string(FONT_DEX_STD, caughtBuffer, 0x0000);
104
+
105
+    rboxid_print(TB_SEEN, FONT_DEX_STD, 0, TB_SEEN_Y, &pdex_text_color, 0, &pdex_str_seen[0]);
106
+    rboxid_print(TB_CAUGHT, FONT_DEX_STD, 0, TB_CAUGHT_Y, &pdex_text_color, 0, &pdex_str_caught[0]);
107
+
108
+    rboxid_print(TB_SEEN, FONT_DEX_STD, TB_STD_RIGHT(twidthSeen, TB_BOT_LEN_PX), TB_SEEN_Y + 1, &pdex_text_color, 0,
109
+                 seenBuffer);
110
+    rboxid_print(TB_CAUGHT, FONT_DEX_STD, TB_STD_RIGHT(twidthCaught, TB_BOT_LEN_PX), TB_CAUGHT_Y + 1, &pdex_text_color,
111
+                 0, caughtBuffer);
112
+
113
+    rboxid_update_tilemap_and_tileset(TB_SEEN);
114
+    rboxid_update_tilemap_and_tileset(TB_CAUGHT);
115
+}
116
+void pdex_pokemon_oam_update(u16 species, s8 objid) {
117
+    gpu_pal_apply_compressed(pokemon_palette_normal[species].data, 16 * (objects[objid].final_oam.palette_num + 16),
118
+                             32);
119
+    lz77UnCompVram(pokemon_graphics_front[species].data,
120
+                   ((void *)(objects[objid].final_oam.tile_num * 32) + ADDR_VRAM + 0x10000));
121
+}
122
+
123
+s8 pdex_pokemon_oam_load(u16 species, u16 tag) {
124
+    struct SpriteTiles pkmnTiles = {pokemon_graphics_front[species].data, 2048, tag};
125
+    struct SpritePalette pkmnPal = {pokemon_palette_normal[species].data, tag};
126
+    const struct Template pkmnTemplate = {
127
+        .tiles_tag = tag,
128
+        .pal_tag = tag,
129
+        .oam = &pdex_oam_pkmn,
130
+        .animation = &anim_image_empty,
131
+        .graphics = &pkmnTiles,
132
+        .rotscale = &rotscale_empty,
133
+        .callback = oac_nullsub,
134
+    };
135
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pkmnTiles);
136
+
137
+    gpu_pal_decompress_alloc_tag_and_upload(&pkmnPal);
138
+    s8 objid = (s8)template_instanciate_forward_search(&pkmnTemplate, 10, 10, 0);
139
+
140
+    objects[objid].pos1.x = 55;
141
+    objects[objid].pos1.y = 76;
142
+    OBJID_HIDE(objid);
143
+    return objid;
144
+}
145
+
146
+void pdex_pokemon_load(u16 species) {
147
+    /* this is very temporary */
148
+    rboxid_clear_pixels(TB_PKMN, 0);
149
+    u32 twidth = font_get_width_of_string(FONT_DEX_STD, &pokemon_names[species][0], 0x0000);
150
+    rboxid_print(TB_PKMN, FONT_DEX_STD, TB_STD_CENTER(twidth, TB_STD_LEN_PX), 3, &pdex_text_color, 0,
151
+                 &pokemon_names[species][0]);
152
+
153
+    // pokedex_context->pokemon_oam = pdex_pokemon_oam_load(species, pokedex_context->pokemon_oam);
154
+
155
+    rboxid_update_tilemap_and_tileset(TB_PKMN);
156
+}
157
+
158
+struct SpriteTiles pdex_ball_tiles = {pdexBallTiles, 128, DEX_BALL_TAG};
159
+struct SpritePalette pdex_ball_pal = {pdexBallPal, DEX_BALL_TAG};
160
+const struct OamData pdex_ball_oam = {
161
+    .affine_mode = 0,
162
+    .obj_mode = 0,
163
+    .mosaic = false,
164
+    .shape = 0,
165
+    .size = 1,
166
+};
167
+
168
+const struct Template pdex_ball_template = {
169
+    .tiles_tag = DEX_BALL_TAG,
170
+    .pal_tag = DEX_BALL_TAG,
171
+    .oam = &pdex_ball_oam,
172
+    .animation = &anim_image_empty,
173
+    .graphics = &pdex_ball_tiles,
174
+    .rotscale = &rotscale_empty,
175
+    .callback = oac_nullsub,
176
+};
177
+
178
+void pdex_pokeballs_init(void) {
179
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pdex_ball_tiles);
180
+    gpu_pal_obj_alloc_tag_and_apply(&pdex_ball_pal);
181
+    for (u8 i = 0; i < 8; ++i) {
182
+        pokedex_context->ball_oams[i] =
183
+            template_instanciate_forward_search(&pdex_ball_template, 124, 8 + pdex_y_offset[i], 1);
184
+    }
185
+}
186
+
187
+void pdex_oac_cursor_follow(struct Object *obj) { obj->pos1.y = objects[pokedex_context->cursor_main_oam].pos1.y; }
188
+
189
+void pdex_oac_cursor_main(struct Object *obj) {
190
+    obj->pos1.y = 13 + pdex_y_offset[pokedex_context->cursor_position_internal];
191
+}
192
+
193
+struct SpriteTiles pdex_cursor_tiles = {pdexSelectHalfTiles, 1024, DEX_CURSOR_TAG};
194
+struct SpritePalette pdex_cursor_pal = {pdexSelectHalfPal, DEX_CURSOR_TAG};
195
+const struct OamData pdex_cursor_oam = {
196
+    .affine_mode = 0,
197
+    .obj_mode = 0,
198
+    .mosaic = false,
199
+    .shape = 1,
200
+    .size = 3,
201
+};
202
+
203
+const struct Template pdex_ball_main_template = {
204
+    .tiles_tag = DEX_CURSOR_TAG,
205
+    .pal_tag = DEX_CURSOR_TAG,
206
+    .oam = &pdex_cursor_oam,
207
+    .animation = &anim_image_empty,
208
+    .graphics = &pdex_cursor_tiles,
209
+    .rotscale = &rotscale_empty,
210
+    .callback = pdex_oac_cursor_main,
211
+};
212
+
213
+const struct Template pdex_ball_follow_template = {
214
+    .tiles_tag = DEX_CURSOR_TAG,
215
+    .pal_tag = DEX_CURSOR_TAG,
216
+    .oam = &pdex_cursor_oam,
217
+    .animation = &anim_image_empty,
218
+    .graphics = &pdex_cursor_tiles,
219
+    .rotscale = &rotscale_empty,
220
+    .callback = pdex_oac_cursor_follow,
221
+};
222
+
223
+void pdex_cursor_init(void) {
224
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pdex_cursor_tiles);
225
+    gpu_pal_obj_alloc_tag_and_apply(&pdex_cursor_pal);
226
+    pokedex_context->cursor_main_oam = template_instanciate_forward_search(&pdex_ball_main_template, 144, 32, 0);
227
+    pokedex_context->cursor_follow_oam =
228
+        template_instanciate_forward_search(&pdex_ball_follow_template, 144 + 48, 32, 0);
229
+    objects[pokedex_context->cursor_follow_oam].final_oam.h_flip = true;
230
+}
231
+
232
+void pdex_oac_scroll_bar(struct Object *obj) {
233
+    obj->pos1.y = 23 + (((pokedex_context->cursor_position_top + pokedex_context->cursor_position_internal) * 123) /
234
+                        PDEX_LAST_SHOWN);
235
+}
236
+
237
+void pdex_oac_arrow(struct Object *obj) {
238
+    if (obj->priv[0]) {
239
+        // this is the down facing arrow
240
+        if (pokedex_context->cursor_position_top + 8 > PDEX_LAST_SHOWN) {
241
+            obj->final_oam.palette_num = obj->priv[2];
242
+        } else {
243
+            obj->final_oam.palette_num = obj->priv[1];
244
+        }
245
+    } else {
246
+        // this is the up facing arrow
247
+        if (pokedex_context->cursor_position_top == pokedex_context->first_seen) {
248
+            obj->final_oam.palette_num = obj->priv[2];
249
+        } else {
250
+            obj->final_oam.palette_num = obj->priv[1];
251
+        }
252
+    }
253
+}
254
+
255
+struct SpriteTiles pdex_scroll_bar_tiles = {pdexScrollBarTiles, 32, DEX_SCROLL_TAG};
256
+struct SpritePalette pdex_scroll_bar_pal = {pdexScrollBarPal, DEX_SCROLL_TAG};
257
+struct SpriteTiles pdex_arrow_tiles = {pdexArrowTiles, 128, DEX_ARROW_TAG};
258
+struct SpritePalette pdex_arrow_pal = {pdexArrowPal, DEX_ARROW_TAG};
259
+struct SpritePalette pdex_arrow_pal_gray = {pdexArrowPal, DEX_ARROW_TAG_EPAL};
260
+
261
+const struct OamData pdex_scroll_bar_oam = {
262
+    .affine_mode = 0,
263
+    .obj_mode = 0,
264
+    .mosaic = false,
265
+    .shape = 0,
266
+    .size = 0,
267
+};
268
+
269
+const struct OamData pdex_arrow_oam = {
270
+    .affine_mode = 0,
271
+    .obj_mode = 0,
272
+    .mosaic = false,
273
+    .shape = 0,
274
+    .size = 1,
275
+};
276
+
277
+const struct Template pdex_scroll_bar_template = {
278
+    .tiles_tag = DEX_SCROLL_TAG,
279
+    .pal_tag = DEX_SCROLL_TAG,
280
+    .oam = &pdex_scroll_bar_oam,
281
+    .animation = &anim_image_empty,
282
+    .graphics = &pdex_scroll_bar_tiles,
283
+    .rotscale = &rotscale_empty,
284
+    .callback = pdex_oac_scroll_bar,
285
+};
286
+
287
+const struct Template pdex_arrow_template = {
288
+    .tiles_tag = DEX_ARROW_TAG,
289
+    .pal_tag = DEX_ARROW_TAG,
290
+    .oam = &pdex_arrow_oam,
291
+    .animation = &anim_image_empty,
292
+    .graphics = &pdex_arrow_tiles,
293
+    .rotscale = &rotscale_empty,
294
+    .callback = pdex_oac_arrow,
295
+};
296
+
297
+void pdex_load_scroll_ui(void) {
298
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pdex_scroll_bar_tiles);
299
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pdex_arrow_tiles);
300
+    gpu_pal_obj_alloc_tag_and_apply(&pdex_scroll_bar_pal);
301
+    u8 normalPal = gpu_pal_obj_alloc_tag_and_apply(&pdex_arrow_pal);
302
+    u8 grayPal = gpu_pal_obj_alloc_tag_and_apply(&pdex_arrow_pal_gray);
303
+    tint_palette_gray(&palette_bg_unfaded[16 * (16 + grayPal)], 16);
304
+    (void)template_instanciate_forward_search(&pdex_scroll_bar_template, 233, 23, 0);
305
+    u8 upArrow = template_instanciate_forward_search(&pdex_arrow_template, 232, 19, 0);
306
+    u8 downArrow = template_instanciate_forward_search(&pdex_arrow_template, 232, 150, 0);
307
+    objects[downArrow].priv[0] = true;
308
+    objects[downArrow].final_oam.v_flip = true;
309
+    objects[upArrow].priv[1] = normalPal;
310
+    objects[downArrow].priv[1] = normalPal;
311
+    objects[upArrow].priv[2] = grayPal;
312
+    objects[downArrow].priv[2] = grayPal;
313
+}
314
+
315
+void pdex_data_setup(void) { pokedex_context->first_seen = 1; }
316
+
317
+void pdex_hardware_scroll(bool up) {
318
+    if (up) {
319
+        if (pokedex_context->hardware_scroll_amount > -15) {
320
+            bgid_mod_y_offset(1, -(16 << 8), 1);
321
+            pokedex_context->hardware_scroll_amount--;
322
+        } else {
323
+            pokedex_context->hardware_scroll_amount = 0;
324
+            bgid_mod_y_offset(1, 0, 0);
325
+        }
326
+    } else {
327
+
328
+        if (pokedex_context->hardware_scroll_amount < 15) {
329
+            bgid_mod_y_offset(1, 16 << 8, 1);
330
+            pokedex_context->hardware_scroll_amount++;
331
+        } else {
332
+            pokedex_context->hardware_scroll_amount = 0;
333
+            bgid_mod_y_offset(1, 0, 0);
334
+        }
335
+    }
336
+}
337
+
338
+void pdex_fill_previous_slot(void) {
339
+    u16 pIndex = pokedex_context->cursor_position_top - 1;
340
+    pdex_main_box_species_fill(-1, pdex_lazy_lookup_entry(pIndex)->species, pdex_lazy_lookup_entry(pIndex)->seen,
341
+                               pdex_lazy_lookup_entry(pIndex)->caught);
342
+}
343
+
344
+void pdex_fill_next_slot(void) {
345
+    u16 pIndex = pokedex_context->cursor_position_top + 8;
346
+    pdex_main_box_species_fill(8, pdex_lazy_lookup_entry(pIndex)->species, pdex_lazy_lookup_entry(pIndex)->seen,
347
+                               pdex_lazy_lookup_entry(pIndex)->caught);
348
+}
349
+
350
+void pdex_try_advance(u8 reverse) {
351
+    if (reverse) {
352
+        if (pokedex_context->cursor_position_internal > 0) {
353
+            pokedex_context->cursor_position_internal--;
354
+            m4aSongNumStart(600);
355
+        } else if ((pokedex_context->cursor_position_top) > (pokedex_context->first_seen)) {
356
+            pdex_fill_previous_slot();
357
+            pokedex_context->cursor_position_top--;
358
+            pdex_hardware_scroll(true);
359
+            m4aSongNumStart(600);
360
+        } else {
361
+            return;
362
+        }
363
+    } else {
364
+        if (pokedex_context->cursor_position_internal < 7) {
365
+            pokedex_context->cursor_position_internal++;
366
+            m4aSongNumStart(600);
367
+        } else if (pokedex_context->cursor_position_top < (PDEX_LAST_SHOWN - 7)) {
368
+            pdex_fill_next_slot();
369
+            pokedex_context->cursor_position_top++;
370
+            pdex_hardware_scroll(false);
371
+            m4aSongNumStart(600);
372
+        } else {
373
+            return;
374
+        }
375
+    }
376
+
377
+    u16 pkIndexToLoad = pokedex_context->cursor_position_internal + pokedex_context->cursor_position_top;
378
+    u16 speciesToLoad = (pdex_lazy_lookup_entry(pkIndexToLoad)->seen || pdex_lazy_lookup_entry(pkIndexToLoad)->caught)
379
+                            ? pdex_lazy_lookup_entry(pkIndexToLoad)->species
380
+                            : pdex_lazy_lookup_entry(pkIndexToLoad)->species; /* debug, just display the mofo */
381
+
382
+    pdex_pokemon_load(speciesToLoad);
383
+    if (reverse) {
384
+        s8 oam = pokedex_context->pokemon_oam; // current oam id
385
+        OBJID_HIDE(oam);
386
+        pokedex_context->pokemon_oam = pokedex_context->prev_pokemon_oam;
387
+        OBJID_SHOW(pokedex_context->pokemon_oam);
388
+        pokedex_context->prev_pokemon_oam = pokedex_context->next_pokemon_oam;
389
+        pokedex_context->next_pokemon_oam = oam;
390
+
391
+        pdex_pokemon_oam_update(pdex_lazy_lookup_entry(pkIndexToLoad - 1)->species, pokedex_context->prev_pokemon_oam);
392
+    } else {
393
+        s8 oam = pokedex_context->pokemon_oam;
394
+        OBJID_HIDE(oam);
395
+        pokedex_context->pokemon_oam = pokedex_context->next_pokemon_oam;
396
+        OBJID_SHOW(pokedex_context->pokemon_oam);
397
+        pokedex_context->next_pokemon_oam = pokedex_context->prev_pokemon_oam;
398
+        pokedex_context->prev_pokemon_oam = oam;
399
+        pdex_pokemon_oam_update(pdex_lazy_lookup_entry(pkIndexToLoad + 1)->species, pokedex_context->next_pokemon_oam);
400
+    }
401
+    pdex_update_balls();
402
+}
403
+
404
+void pdex_loop(u8 tid) {
405
+    switch (pokedex_context->state) {
406
+    case 0:
407
+        pokedex_context->state++;
408
+        break;
409
+    case 1:
410
+        for (u8 i = 0; i < 4; ++i)
411
+            bgid_send_tilemap(i);
412
+        rboxid_clear_pixels(TB_TITLE, 0);
413
+        rboxid_print(TB_TITLE, FONT_DEX_STD, 0, 0, &pdex_text_color, 0, &pdex_str_title[0]);
414
+        rboxid_update_tilemap_and_tileset(TB_TITLE);
415
+
416
+        pdex_data_setup();
417
+        pdex_cursor_init();
418
+
419
+        pdex_pokeballs_init();
420
+        pdex_load_scroll_ui();
421
+        u16 currentIndex = pokedex_context->cursor_position_top + pokedex_context->cursor_position_internal;
422
+        pdex_pokemon_load(pdex_lazy_lookup_entry(currentIndex)->species);
423
+
424
+        pokedex_context->pokemon_oam =
425
+            pdex_pokemon_oam_load(pdex_lazy_lookup_entry(currentIndex)->species, DEX_PKMN_TAG_ONE);
426
+        OBJID_SHOW(pokedex_context->pokemon_oam);
427
+
428
+        pokedex_context->next_pokemon_oam =
429
+            pdex_pokemon_oam_load(pdex_lazy_lookup_entry(currentIndex + 1)->species, DEX_PKMN_TAG_TWO);
430
+
431
+        if (currentIndex != pokedex_context->first_seen) {
432
+            pokedex_context->prev_pokemon_oam =
433
+                pdex_pokemon_oam_load(pdex_lazy_lookup_entry(currentIndex - 1)->species, DEX_PKMN_TAG_THREE);
434
+        } else {
435
+            pokedex_context->prev_pokemon_oam = pdex_pokemon_oam_load(0, DEX_PKMN_TAG_THREE);
436
+        }
437
+        pdex_load_sc();
438
+        pdex_update_page_full();
439
+
440
+        palette_bg_faded_fill_black();
441
+        pokedex_context->state++;
442
+        break;
443
+    case 2:
444
+        gpu_sync_bg_show(0);
445
+        gpu_sync_bg_show(1);
446
+        gpu_sync_bg_hide(3);
447
+
448
+        gpu_sync_bg_show(2);
449
+        fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 16, 0, 0x0000);
450
+        pokedex_context->state++;
451
+
452
+        break;
453
+    case 3:
454
+        if (!pal_fade_control.active)
455
+            pokedex_context->state++;
456
+        break;
457
+    case 4:
458
+        /* main control */
459
+        if (super.buttons_new & KEY_A) {
460
+            pokedex_context->state = 15;
461
+            m4aSongNumStart(5);
462
+        }
463
+        if (super.buttons_new & KEY_B) {
464
+            pokedex_context->state = 10;
465
+            m4aSongNumStart(601);
466
+        }
467
+        if ((super.buttons_new & KEY_DOWN)) {
468
+            pdex_try_advance(false);
469
+            pokedex_context->scroll_speed = 0;
470
+            pokedex_context->delay_count = 0;
471
+        } else if (super.buttons_held & KEY_DOWN) {
472
+            if (pokedex_context->scroll_speed < SCROLL_SPEED_MAX) {
473
+                if (pokedex_context->delay_count >= scroll_speed_delays[pokedex_context->scroll_speed]) {
474
+                    pdex_try_advance(false);
475
+                    pokedex_context->delay_count = 0;
476
+                    pokedex_context->scroll_speed++;
477
+                } else {
478
+                    pokedex_context->delay_count++;
479
+                }
480
+            } else {
481
+                pdex_try_advance(false);
482
+            }
483
+        }
484
+        if ((super.buttons_new & KEY_UP)) {
485
+            pdex_try_advance(true);
486
+            pokedex_context->scroll_speed = 0;
487
+            pokedex_context->delay_count = 0;
488
+        } else if (super.buttons_held & KEY_UP) {
489
+            if (pokedex_context->scroll_speed < SCROLL_SPEED_MAX) {
490
+                if (pokedex_context->delay_count >= scroll_speed_delays[pokedex_context->scroll_speed]) {
491
+                    pdex_try_advance(true);
492
+                    pokedex_context->delay_count = 0;
493
+                    pokedex_context->scroll_speed++;
494
+                } else {
495
+                    pokedex_context->delay_count++;
496
+                }
497
+            } else {
498
+                pdex_try_advance(true);
499
+            }
500
+        }
501
+        break;
502
+    case 10:
503
+        /* control flow exit */
504
+        fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 0, 16, 0x000);
505
+        pokedex_context->state++;
506
+        break;
507
+    case 11:
508
+        if (!pal_fade_control.active) {
509
+            task_del(tid);
510
+            pdex_vram_free_bgmaps();
511
+            pdex_free_memory();
512
+            void region_select_load(void);
513
+            set_callback2(region_select_load);
514
+        }
515
+        break;
516
+    case 15:
517
+        /* load the detail screen */
518
+        fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 0, 16, 0x0000);
519
+        pokedex_context->state++;
520
+        break;
521
+    case 16:
522
+        if (!pal_fade_control.active) {
523
+            pdex_vram_free_bgmaps();
524
+            task_del(tid);
525
+            void dexdetail_load(void);
526
+            set_callback2(dexdetail_load);
527
+        }
528
+    default:
529
+        break;
530
+    }
531
+}
532
+
533
+void pdex_load_gfx(void) {
534
+    /*TODO: setup text boxes here */
535
+    rbox_init_from_templates(&pdex_boxes[0]);
536
+
537
+    lz77UnCompVram(pdexBgTiles, (void *)0x0600C000);
538
+    LZ77UnCompWram(pdexBgMap, bgid_get_tilemap(2));
539
+    gpu_pal_apply_compressed(pdexBgPal, 0, 32);
540
+    gpu_pal_apply(pdex_text_pal, 15 * 16, 32);
541
+
542
+    /*setup window*/
543
+    lcd_io_set(REG_ID_WIN0H, (128 << 8) | (216));
544
+    lcd_io_set(REG_ID_WIN0V, ((20 << 8) | (148)));
545
+    lcd_io_set(REG_ID_WININ, WIN_BG0 | WIN_BG1 | WIN_BG2 | WIN_BG3 | WIN_OBJ);
546
+    lcd_io_set(REG_ID_WINOUT, WIN_BG0 | WIN_BG2 | WIN_BG3 | WIN_OBJ);
547
+    bgid_mark_for_sync(0);
548
+}
549
+
550
+void pdex_load(void) {
551
+
552
+    pdex_vram_setup();
553
+    pdex_load_gfx();
554
+
555
+    pokedex_context->pokemon_oam = -1;
556
+    pokedex_context->state = 0;
557
+    pokedex_context->hardware_scroll_amount = 0;
558
+    task_add(pdex_loop, 0);
559
+    set_callback2(pdex_cb_handler);
560
+}

+ 183
- 0
src/pokedex/pokedex_common.c Целия файл

@@ -0,0 +1,183 @@
1
+#include "pokedex_common.h"
2
+#include <constants/pkmns.h>
3
+#include <pokeagb/pokeagb.h>
4
+
5
+const u16 pdex_text_pal[] = {rgb5(255, 0, 255), rgb5(255, 255, 255), rgb5(0, 0, 0),     rgb5(255, 0, 255),
6
+                             rgb5(255, 0, 255), rgb5(255, 0, 255),   rgb5(255, 0, 255), rgb5(255, 0, 255),
7
+                             rgb5(255, 0, 255), rgb5(255, 0, 255),   rgb5(255, 0, 255), rgb5(255, 0, 255),
8
+                             rgb5(255, 0, 255), rgb5(255, 0, 255),   rgb5(255, 0, 255), rgb5(255, 0, 255)};
9
+
10
+const struct BgConfig pdex_bg_config[4] = {
11
+    {
12
+        .padding = 0,
13
+        .b_padding = 0,
14
+        .priority = 0,
15
+        .palette = 0,
16
+        .size = 0,
17
+        .map_base = 29,
18
+        .character_base = 0,
19
+        .bgid = 0,
20
+    },
21
+    {
22
+        .padding = 0,
23
+        .b_padding = 0,
24
+        .priority = 1,
25
+        .palette = 0,
26
+        .size = 0,
27
+        .map_base = 28,
28
+        .character_base = 0,
29
+        .bgid = 1,
30
+    },
31
+    {
32
+        .padding = 0,
33
+        .b_padding = 0,
34
+        .priority = 2,
35
+        .palette = 0,
36
+        .size = 0,
37
+        .map_base = 30,
38
+        .character_base = 3,
39
+        .bgid = 2,
40
+    },
41
+    {
42
+        .padding = 0,
43
+        .b_padding = 0,
44
+        .priority = 3,
45
+        .palette = 0,
46
+        .size = 1,
47
+        .map_base = 31,
48
+        .character_base = 3,
49
+        .bgid = 3,
50
+    },
51
+};
52
+
53
+struct DexForm pdex_forms[FORM_COUNT] = 
54
+{
55
+    {.index = 19, .forms = {{814, PKMN_ALOLA_RATTFRATZ, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
56
+    {.index = 20, .forms = {{815, PKMN_ALOLA_RATIKARL, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
57
+    {.index = 26, .forms = {{816, PKMN_ALOLA_RAICHU, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
58
+    {.index = 27, .forms = {{817, PKMN_ALOLA_SANDAN, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
59
+    {.index = 28, .forms = {{818, PKMN_ALOLA_SANDAMER, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
60
+    {.index = 37, .forms = {{819, PKMN_ALOLA_VULPIX, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
61
+    {.index = 38, .forms = {{820, PKMN_ALOLA_VULNONA, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
62
+    {.index = 50, .forms = {{821, PKMN_ALOLA_DIGDA, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
63
+    {.index = 51, .forms = {{822, PKMN_ALOLA_DIGDRI, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
64
+    {.index = 52, .forms = {{823, PKMN_ALOLA_MAUZI, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
65
+    {.index = 53, .forms = {{824, PKMN_ALOLA_SNOBILIKAT, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
66
+    {.index = 74, .forms = {{825, PKMN_ALOLA_KLEINSTEIN, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
67
+    {.index = 75, .forms = {{826, PKMN_ALOLA_GEOROK, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
68
+    {.index = 76, .forms = {{827, PKMN_ALOLA_GEOWAZ, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
69
+    {.index = 88, .forms = {{828, PKMN_ALOLA_SLEIMA, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
70
+    {.index = 89, .forms = {{829, PKMN_ALOLA_SLEIMOK, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
71
+    {.index = 103, .forms = {{830, PKMN_ALOLA_KOKOWEI, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
72
+    {.index = 105, .forms = {{831, PKMN_ALOLA_KNOGGA, ALOLA}, {0xFFFF, 0xFFFF, FORM_END}}},
73
+    {.index = 0xFFFF, .forms = {{0xFFFF, 0xFFFF, FORM_END}}},
74
+};
75
+
76
+const struct OamData pdex_oam_pkmn = {
77
+    .affine_mode = 0,
78
+    .obj_mode = 0,
79
+    .mosaic = false,
80
+    .shape = 0,
81
+    .size = 3,
82
+};
83
+
84
+struct TextColor pdex_text_color = {0, 1, 2};
85
+
86
+void pdex_vblank_handler(void) {
87
+    gpu_sprites_upload();
88
+    copy_queue_process();
89
+    gpu_pal_upload();
90
+}
91
+
92
+u8 pstr_lines(const pchar *str) {
93
+    u8 lines = 1;
94
+    while (*str != 0xFF) {
95
+        if (*str == 0xFE)
96
+            lines++;
97
+        str++;
98
+    }
99
+    return lines;
100
+}
101
+
102
+void pdex_cb_handler(void) {
103
+    if (pal_fade_control.active)
104
+        process_palfade();
105
+    else {
106
+        task_exec();
107
+        objc_exec();
108
+        obj_sync_superstate();
109
+        tilemaps_sync();
110
+        remoboxes_upload_tilesets();
111
+    }
112
+}
113
+
114
+void pdex_vram_free_bgmaps(void) {
115
+    for (u8 i = 0; i < 3; ++i) {
116
+        void *tmap = bgid_get_tilemap(i);
117
+        if (tmap != NULL) {
118
+            free(tmap);
119
+            bgid_nullify_tilemap(i);
120
+        }
121
+    }
122
+}
123
+
124
+struct PdexLookup *pdex_fill_lookup(u16 dexIndex) {
125
+    u16 species = pokedex_index_to_species(dexIndex);
126
+    pokedex_context->lookup[dexIndex].species = species;
127
+    pokedex_context->lookup[dexIndex].seen = dex_flag_pokedex_index(dexIndex, DEX_FLAG_CHECK_SEEN);
128
+    pokedex_context->lookup[dexIndex].caught = dex_flag_pokedex_index(dexIndex, DEX_FLAG_CHECK_CAUGHT);
129
+    return &pokedex_context->lookup[dexIndex];
130
+}
131
+
132
+struct PdexLookup *pdex_lazy_lookup_entry(u16 dexIndex) {
133
+    if (pokedex_context->lookup[dexIndex].species != -1) {
134
+        return &pokedex_context->lookup[dexIndex];
135
+    } else {
136
+        return pdex_fill_lookup(dexIndex);
137
+    }
138
+}
139
+
140
+void pdex_free_memory(void) {
141
+    if (pokedex_context->lookup != NULL)
142
+        free(pokedex_context->lookup);
143
+    free(pokedex_context);
144
+}
145
+
146
+void pdex_alloc_memory(void) {
147
+    pokedex_context = malloc_and_clear(sizeof(struct PdexCtx));
148
+    pokedex_context->lookup = malloc_and_clear((PDEX_LAST_ENTRY + 1) * sizeof(struct PdexLookup));
149
+    memset(pokedex_context->lookup, 0xFF, (PDEX_LAST_ENTRY + 1) * sizeof(struct PdexLookup));
150
+}
151
+
152
+void pdex_vram_allocate_bgmaps(void) {
153
+    bgid_set_tilemap(0, malloc(0x800));
154
+    bgid_set_tilemap(1, malloc(0x800));
155
+    bgid_set_tilemap(2, malloc(0x800));
156
+}
157
+
158
+void pdex_vram_setup(void) {
159
+    vblank_handler_set(NULL);
160
+    pal_fade_control_and_dead_struct_reset();
161
+    gpu_tile_bg_drop_all_sets(true);
162
+    obj_and_aux_reset_all();
163
+    gpu_tile_obj_tags_reset();
164
+    gpu_pal_allocator_reset();
165
+    rboxes_free();
166
+    tasks_init();
167
+    bg_vram_setup(0, &pdex_bg_config[0], 4);
168
+    u32 set = 0;
169
+    CpuFastSet((void *)&set, (void *)0x06000000, CPUModeFS(0x10000, CPUFSSET));
170
+
171
+    bgid_mod_x_offset(0, 0, 0);
172
+    bgid_mod_y_offset(0, 0, 0);
173
+    bgid_mod_x_offset(1, 0, 0);
174
+    bgid_mod_y_offset(1, 0, 0);
175
+    bgid_mod_x_offset(2, 0, 0);
176
+    bgid_mod_y_offset(2, 0, 0);
177
+    bgid_mod_x_offset(3, 0, 0);
178
+    bgid_mod_y_offset(3, 0, 0);
179
+
180
+    vblank_handler_set(pdex_vblank_handler);
181
+    interrupts_enable(INTERRUPT_VBLANK);
182
+    pdex_vram_allocate_bgmaps();
183
+}

+ 71
- 0
src/pokedex/pokedex_common.h Целия файл

@@ -0,0 +1,71 @@
1
+#ifndef PDEX_C_H_
2
+#define PDEX_C_H_
3
+
4
+#include <pokeagb/pokeagb.h>
5
+
6
+#define PDEX_ALOLA_COUNT (18)
7
+#define PDEX_LAST_ENTRY (813 + PDEX_ALOLA_COUNT)
8
+#define PDEX_LAST_SHOWN (813)
9
+
10
+#define CPUFSCPY 0
11
+#define CPUFSSET 1
12
+#define CPUModeFS(size, mode) ((size >> 2) | (mode << 24))
13
+#define MAX3_COUNT_DIGITS(n) (n >= 100 ? 3 : (n >= 10 ? 2 : 1))
14
+
15
+#define OBJID_HIDE(objid) objects[objid].final_oam.affine_mode = 2
16
+#define OBJID_SHOW(objid) objects[objid].final_oam.affine_mode = 0
17
+
18
+#define PDEX_FADEIN_SPD 1
19
+
20
+#define FONT_DEX_STD 1
21
+
22
+#define TB_STD_LEN 10
23
+#define TB_STD_LEN_PX (TB_STD_LEN * 8)
24
+#define TB_BOT_LEN 9
25
+#define TB_BOT_LEN_PX (TB_BOT_LEN * 8)
26
+
27
+#define TB_STD_CENTER(t,w) (((w - t) >> 1) + 2)
28
+#define TB_STD_RIGHT(t,w) ((w - t))
29
+
30
+#define DEX_PKMN_TAG_ONE 0x1300
31
+#define DEX_PKMN_TAG_TWO 0x1310
32
+#define DEX_PKMN_TAG_THREE 0x1311
33
+#define DEX_BALL_TAG 0x1301
34
+#define DEX_CURSOR_TAG 0x1302
35
+#define DEX_ARROW_TAG 0x1303
36
+#define DEX_ARROW_TAG_EPAL 0x1304
37
+#define DEX_SCROLL_TAG 0x1305
38
+#define DEX_REGION_SELECT 0x1306
39
+#define DEX_DETAIL_TYPE1 0x130E
40
+#define DEX_DETAIL_TYPE2 0x130F
41
+#define DEX_DETAIL_TYPEPAL 0x130E
42
+
43
+#define DEX_REGION_PAL(i) (0x1307 + i)
44
+#define DEX_REGION_ICON(i) (0x1307 + i)
45
+#define MAX_FORMS 7
46
+#define FORM_COUNT 20
47
+
48
+struct DexForm
49
+{
50
+    u16 index;
51
+    struct DexFormEntry forms[MAX_FORMS];
52
+};
53
+
54
+void pdex_cb_handler(void);
55
+void pdex_vblank_handler(void);
56
+void pdex_vram_setup(void);
57
+void pdex_vram_free_bgmaps(void);
58
+void pdex_free_memory(void);
59
+void pdex_alloc_memory(void);
60
+struct PdexLookup *pdex_lazy_lookup_entry(u16 dexIndex);
61
+void pdex_load(void);
62
+
63
+const u16 pdex_text_pal[16];
64
+const struct BgConfig pdex_bg_config[4];
65
+struct TextColor pdex_text_color;
66
+const struct OamData pdex_oam_pkmn;
67
+struct DexForm pdex_forms[FORM_COUNT];
68
+
69
+u8 pstr_lines(const pchar* str);
70
+
71
+#endif

+ 397
- 0
src/pokedex/pokedex_detail.c Целия файл

@@ -0,0 +1,397 @@
1
+#include <agb_debug.h>
2
+#include <pokeagb/pokeagb.h>
3
+#include <pokedex/pdexArrowRotated.h>
4
+#include <pokedex/pdexDetailBg.h>
5
+
6
+#include "pokedex_common.h"
7
+
8
+#define TB_PKNAME 0
9
+#define TB_PKSIZE 1
10
+#define TB_DESC 2
11
+
12
+#define TB_PKNAME_W 30
13
+#define TB_SW_W 12
14
+
15
+extern pchar pdex_entry_debug[];
16
+extern pchar pdex_str_size[];
17
+extern pchar pdex_str_weight[];
18
+extern pchar pdex_str_size_unit[];
19
+extern pchar pdex_str_weight_unit[];
20
+extern pchar pdex_str_comma[];
21
+
22
+struct TextboxTemplate dexdetail_boxes[] = {
23
+    {.bg_id = 0, .x = 0, .y = 0, .width = TB_PKNAME_W, .height = 4, .pal_id = 15, .charbase = 1},
24
+    {.bg_id = 0, .x = 17, .y = 5, .width = TB_SW_W, .height = 4, .pal_id = 15, .charbase = 121},
25
+    {.bg_id = 1, .x = 1, .y = 0, .width = 28, .height = 20, .pal_id = 15, .charbase = 161},
26
+
27
+    {.bg_id = 0xFF},
28
+};
29
+
30
+u8 dexdetail_type_to_oam_type[18] = {0, 9, 8, 12, 6, 5, 11, 10, 14, 17, 1, 2, 3, 4, 13, 7, 16, 15};
31
+
32
+#define O_TYPE(t) (dexdetail_type_to_oam_type[t])
33
+
34
+struct OamData dexdetail_type_oam = {
35
+    .affine_mode = 0,
36
+    .obj_mode = 0,
37
+    .mosaic = false,
38
+    .shape = 1,
39
+    .size = 2,
40
+};
41
+
42
+void dexdetail_update_type_oam(u8 type, struct Object *obj) {
43
+    memcpy((void *)((0x06010000) + (obj->final_oam.tile_num * 0x20)),
44
+           pokemon_type_chart_gfx + (128 * O_TYPE(type)) + (512 * (O_TYPE(type) >> 2)), 128);
45
+    memcpy((void *)((0x06010000) + 128 + (obj->final_oam.tile_num * 0x20)),
46
+           pokemon_type_chart_gfx + 512 + (128 * O_TYPE(type)) + (512 * (O_TYPE(type) >> 2)), 128);
47
+}
48
+
49
+s8 dexdetail_load_type_oam(u8 type, u16 tag) {
50
+    struct SpriteTiles typeTiles = {(&pokemon_type_chart_gfx[0]) + 256 * O_TYPE(type), 256, tag};
51
+    gpu_tile_obj_alloc_tag_and_upload(&typeTiles);
52
+    const struct Template typeTemplate = {
53
+        .tiles_tag = tag,
54
+        .pal_tag = DEX_DETAIL_TYPEPAL,
55
+        .oam = &dexdetail_type_oam,
56
+        .animation = &anim_image_empty,
57
+        .graphics = &typeTiles,
58
+        .rotscale = &rotscale_empty,
59
+        .callback = oac_nullsub,
60
+    };
61
+    s8 id = (s8)template_instanciate_forward_search(&typeTemplate, 100, 100, 0);
62
+    dexdetail_update_type_oam(type, &objects[id]);
63
+    return id;
64
+}
65
+
66
+extern pchar pdex_str_form_alola[];
67
+
68
+void dexdetail_load_pokemon(u16 dexindex, enum DexFormType formType) {
69
+    u16 species = pdex_lazy_lookup_entry(dexindex)->species;
70
+    rboxid_clear_pixels(TB_PKNAME, 0);
71
+    rboxid_clear_pixels(TB_PKSIZE, 0);
72
+    rboxid_clear_pixels(TB_DESC, 0);
73
+    pstrcpy(string_buffer, &pokemon_names[species][0]);
74
+    switch (formType) {
75
+    case ALOLA:
76
+        pstrcat(string_buffer, pdex_str_form_alola);
77
+        break;
78
+    default:
79
+        break;
80
+    }
81
+    u16 twidth = font_get_width_of_string(FONT_DEX_STD, string_buffer, 0x0000);
82
+    rboxid_print(TB_PKNAME, FONT_DEX_STD, TB_STD_CENTER(twidth, 8 * TB_PKNAME_W), 0, &pdex_text_color, 0,
83
+                 string_buffer);
84
+
85
+    pchar *strType = &pokedex_data[dexindex].category_name[0];
86
+    u16 typeTwidth = font_get_width_of_string(FONT_DEX_STD, strType, 0x0000);
87
+    rboxid_print(TB_PKNAME, FONT_DEX_STD, TB_STD_CENTER(typeTwidth, 88) + 110, 14, &pdex_text_color, 0, strType);
88
+    rboxid_print(TB_PKSIZE, FONT_DEX_STD, 4, 1, &pdex_text_color, 0, pdex_str_size);
89
+    rboxid_print(TB_PKSIZE, FONT_DEX_STD, 4, 14, &pdex_text_color, 0, pdex_str_weight);
90
+
91
+    u16 weightNumber = pokedex_data[dexindex].weight / 10;
92
+    u16 weightDecimal = pokedex_data[dexindex].weight % 10;
93
+    pchar buffer[20];
94
+    fmt_int_10(string_buffer, weightNumber, 0, 3);
95
+    fmt_int_10(&buffer[0], weightDecimal, 0, 1);
96
+    pstrcat(string_buffer, pdex_str_comma);
97
+    pstrcat(string_buffer, buffer);
98
+    pstrcat(string_buffer, pdex_str_weight_unit);
99
+    u16 weightTwidth = font_get_width_of_string(FONT_DEX_STD, string_buffer, 0x0000);
100
+
101
+    rboxid_print(TB_PKSIZE, FONT_DEX_STD, TB_STD_RIGHT(weightTwidth, TB_SW_W * 8) - 6, 14, &pdex_text_color, 0,
102
+                 string_buffer);
103
+
104
+    u16 sizeNumber = pokedex_data[dexindex].height / 10;
105
+    u16 sizeDecimal = pokedex_data[dexindex].height % 10;
106
+    fmt_int_10(string_buffer, sizeNumber, 0, 3);
107
+    fmt_int_10(&buffer[0], sizeDecimal, 0, 1);
108
+    pstrcat(string_buffer, pdex_str_comma);
109
+    pstrcat(string_buffer, buffer);
110
+    pstrcat(string_buffer, pdex_str_size_unit);
111
+
112
+    rboxid_print(TB_PKSIZE, FONT_DEX_STD, TB_STD_RIGHT(weightTwidth, TB_SW_W * 8) - 6, 1, &pdex_text_color, 0,
113
+                 string_buffer);
114
+
115
+    rboxid_print(TB_DESC, FONT_DEX_STD, 3, 2, &pdex_text_color, 0, pokedex_data[dexindex].description1);
116
+
117
+    /* setup scrolling parameters */
118
+    u8 descLines = pstr_lines(&pokedex_data[dexindex].description1[0]);
119
+    if (descLines > 4)
120
+        pokedex_context->detail_scroll_max = descLines - 4;
121
+    else
122
+        pokedex_context->detail_scroll_max = 0;
123
+
124
+    /* load the species sprite */
125
+    if (pokedex_context->detail_pokemon_oam != -1) {
126
+        lz77UnCompVram(
127
+            pokemon_graphics_front[species].data,
128
+            ((void *)(objects[pokedex_context->detail_pokemon_oam].final_oam.tile_num * 32) + ADDR_VRAM + 0x10000));
129
+        gpu_pal_apply_compressed(pokemon_palette_normal[species].data,
130
+                                 16 * (objects[pokedex_context->detail_pokemon_oam].final_oam.palette_num + 16), 32);
131
+    } else {
132
+        struct SpriteTiles pkmnTiles = {pokemon_graphics_front[species].data, 2048, DEX_PKMN_TAG_ONE};
133
+        struct SpritePalette pkmnPal = {pokemon_palette_normal[species].data, DEX_PKMN_TAG_ONE};
134
+        const struct Template pkmnTemplate = {
135
+            .tiles_tag = DEX_PKMN_TAG_ONE,
136
+            .pal_tag = DEX_PKMN_TAG_ONE,
137
+            .oam = &pdex_oam_pkmn,
138
+            .animation = &anim_image_empty,
139
+            .graphics = &pkmnTiles,
140
+            .rotscale = &rotscale_empty,
141
+            .callback = oac_nullsub,
142
+        };
143
+        gpu_tile_obj_decompress_alloc_tag_and_upload(&pkmnTiles);
144
+
145
+        gpu_pal_decompress_alloc_tag_and_upload(&pkmnPal);
146
+        pokedex_context->detail_pokemon_oam = (s8)template_instanciate_forward_search(&pkmnTemplate, 10, 10, 0);
147
+
148
+        objects[pokedex_context->detail_pokemon_oam].pos1.x = 55;
149
+        objects[pokedex_context->detail_pokemon_oam].pos1.y = 55;
150
+    }
151
+
152
+    // draw the first type icon
153
+    if (pokedex_context->detail_type_oam[0] != -1) {
154
+        dexdetail_update_type_oam(pokemon_base_stats[species].type[0], &objects[pokedex_context->detail_type_oam[0]]);
155
+    } else {
156
+        pokedex_context->detail_type_oam[0] =
157
+            dexdetail_load_type_oam(pokemon_base_stats[species].type[0], DEX_DETAIL_TYPE1);
158
+        objects[pokedex_context->detail_type_oam[0]].pos1.x = 156;
159
+        objects[pokedex_context->detail_type_oam[0]].pos1.y = 80;
160
+    }
161
+    // draw the second type icon eventually
162
+    if (pokemon_base_stats[species].type[0] != pokemon_base_stats[species].type[1]) {
163
+        if (pokedex_context->detail_type_oam[1] != -1) {
164
+            dexdetail_update_type_oam(pokemon_base_stats[species].type[1],
165
+                                      &objects[pokedex_context->detail_type_oam[1]]);
166
+        } else {
167
+            pokedex_context->detail_type_oam[1] =
168
+                dexdetail_load_type_oam(pokemon_base_stats[species].type[1], DEX_DETAIL_TYPE2);
169
+            objects[pokedex_context->detail_type_oam[1]].pos1.x = 210;
170
+            objects[pokedex_context->detail_type_oam[1]].pos1.y = 80;
171
+        }
172
+        OBJID_SHOW(pokedex_context->detail_type_oam[1]);
173
+    } else {
174
+        OBJID_HIDE(pokedex_context->detail_type_oam[1]);
175
+    }
176
+    rboxid_update_tilemap_and_tileset(TB_DESC);
177
+    rboxid_update_tilemap_and_tileset(TB_PKNAME);
178
+    rboxid_update_tilemap_and_tileset(TB_PKSIZE);
179
+}
180
+
181
+void dexdetail_update_form(u16 form) {
182
+    REG_DISPCNT &= ~((1 << 8) | (1 << 9));
183
+    if (form == 0) {
184
+        dexdetail_load_pokemon(pokedex_context->cursor_position_top + pokedex_context->cursor_position_internal,
185
+                               NORMAL);
186
+    } else {
187
+        form--;
188
+        if (pokedex_context->detail_forms[form].index > PDEX_LAST_SHOWN) {
189
+            dexdetail_load_pokemon(pokedex_context->detail_forms[form].index, pokedex_context->detail_forms[form].type);
190
+        } else {
191
+            // update the oam only
192
+            u16 species = pokedex_context->detail_forms[form].species;
193
+            lz77UnCompVram(
194
+                pokemon_graphics_front[species].data,
195
+                ((void *)(objects[pokedex_context->detail_pokemon_oam].final_oam.tile_num * 32) + ADDR_VRAM + 0x10000));
196
+            gpu_pal_apply_compressed(pokemon_palette_normal[species].data,
197
+                                     16 * (objects[pokedex_context->detail_pokemon_oam].final_oam.palette_num + 16),
198
+                                     32);
199
+        }
200
+    }
201
+    REG_DISPCNT |= ((1 << 8) | (1 << 9));
202
+}
203
+
204
+struct DexFormEntry *dexdetail_get_forms(u16 index) {
205
+    u16 current = 0;
206
+    while (pdex_forms[current].index != 0xFFFF) {
207
+        if (pdex_forms[current].index == index)
208
+            return &pdex_forms[current].forms[0];
209
+        current++;
210
+    }
211
+    return NULL;
212
+}
213
+
214
+void dexdetail_oac_arrow(struct Object *obj) {
215
+    if (pokedex_context->detail_forms != NULL) {
216
+        if (obj->priv[0]) {
217
+            // this is the left arrow
218
+            if (pokedex_context->detail_form_position != 0) {
219
+                obj->final_oam.palette_num = obj->priv[1];
220
+            } else {
221
+                obj->final_oam.palette_num = obj->priv[2];
222
+            }
223
+        } else {
224
+            // this is the right arrow
225
+            if (pokedex_context->detail_forms[pokedex_context->detail_form_position].type != FORM_END) {
226
+                obj->final_oam.palette_num = obj->priv[1];
227
+            } else {
228
+                obj->final_oam.palette_num = obj->priv[2];
229
+            }
230
+        }
231
+    }
232
+}
233
+
234
+struct SpriteTiles pdex_arrow_rot_tiles = {pdexArrowRotatedTiles, 256, DEX_ARROW_TAG};
235
+struct SpritePalette pdex_arrow_rot_pal = {pdexArrowRotatedPal, DEX_ARROW_TAG};
236
+struct SpritePalette pdex_arrow_rot_pal_gray = {pdexArrowRotatedPal, DEX_ARROW_TAG_EPAL};
237
+
238
+const struct OamData pdex_arrow_rot_oam = {
239
+    .affine_mode = 0,
240
+    .obj_mode = 0,
241
+    .mosaic = false,
242
+    .shape = 0,
243
+    .size = 1,
244
+};
245
+
246
+const struct Template pdex_arrow_rot_template = {
247
+    .tiles_tag = DEX_ARROW_TAG,
248
+    .pal_tag = DEX_ARROW_TAG,
249
+    .oam = &pdex_arrow_rot_oam,
250
+    .animation = &anim_image_empty,
251
+    .graphics = &pdex_arrow_rot_tiles,
252
+    .rotscale = &rotscale_empty,
253
+    .callback = dexdetail_oac_arrow,
254
+};
255
+
256
+void dexdetail_load_form_arrows(void) {
257
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pdex_arrow_rot_tiles);
258
+    u8 normalPal = gpu_pal_obj_alloc_tag_and_apply(&pdex_arrow_rot_pal);
259
+    u8 grayPal = gpu_pal_obj_alloc_tag_and_apply(&pdex_arrow_rot_pal_gray);
260
+    tint_palette_gray(&palette_bg_unfaded[16 * (16 + grayPal)], 16);
261
+    u8 leftArrow = template_instanciate_forward_search(&pdex_arrow_rot_template, 10, 55, 0);
262
+    u8 rightArrow = template_instanciate_forward_search(&pdex_arrow_rot_template, 100, 55, 0);
263
+    objects[leftArrow].priv[0] = true;
264
+    objects[leftArrow].final_oam.h_flip = true;
265
+    objects[leftArrow].priv[1] = normalPal;
266
+    objects[leftArrow].priv[2] = grayPal;
267
+    objects[rightArrow].priv[0] = false;
268
+    objects[rightArrow].priv[1] = normalPal;
269
+    objects[rightArrow].priv[2] = grayPal;
270
+    pokedex_context->detail_arrows_oam[0] = leftArrow;
271
+    pokedex_context->detail_arrows_oam[1] = rightArrow;
272
+}
273
+
274
+void dexdetail_scroll_update(void) {
275
+    bgid_mod_y_offset(1, -24576 + (pokedex_context->detail_scroll_amount * 256 * 14), 0);
276
+}
277
+
278
+void dexdetail_loop(u8 tid) {
279
+    u16 currentIndex = pokedex_context->cursor_position_top + pokedex_context->cursor_position_internal;
280
+    switch (pokedex_context->state) {
281
+    case 0:
282
+        bgid_send_tilemap(2);
283
+        dexdetail_load_form_arrows();
284
+        dexdetail_load_pokemon(currentIndex, NORMAL);
285
+        pokedex_context->detail_form_position = 0;
286
+        struct DexFormEntry *forms = dexdetail_get_forms(currentIndex);
287
+        if (forms != NULL) {
288
+            OBJID_SHOW(pokedex_context->detail_arrows_oam[0]);
289
+            OBJID_SHOW(pokedex_context->detail_arrows_oam[1]);
290
+        } else {
291
+            OBJID_HIDE(pokedex_context->detail_arrows_oam[0]);
292
+            OBJID_HIDE(pokedex_context->detail_arrows_oam[1]);
293
+        }
294
+
295
+        pokedex_context->detail_forms = forms;
296
+        palette_bg_faded_fill_black();
297
+        pokedex_context->state++;
298
+        break;
299
+    case 1:
300
+        gpu_sync_bg_show(0);
301
+        gpu_sync_bg_show(1);
302
+        gpu_sync_bg_hide(3);
303
+
304
+        gpu_sync_bg_show(2);
305
+        fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 16, 0, 0x0000);
306
+        pokedex_context->state++;
307
+        break;
308
+    case 2:
309
+        if (!pal_fade_control.active) {
310
+            pokecry_play(pdex_lazy_lookup_entry(currentIndex)->species, 0);
311
+            pokedex_context->state++;
312
+        }
313
+        break;
314
+    case 3:
315
+        switch (super.buttons_new) {
316
+        case KEY_B:
317
+            pokedex_context->state = 12;
318
+            u16 dexindex = pokedex_context->cursor_position_top + pokedex_context->cursor_position_internal;
319
+            if (dexindex <= PDEX_LAST_SHOWN - 7) {
320
+                pokedex_context->cursor_position_top = dexindex;
321
+                pokedex_context->cursor_position_internal = 0;
322
+            } else {
323
+                pokedex_context->cursor_position_top = PDEX_LAST_SHOWN - 7;
324
+                pokedex_context->cursor_position_internal = (dexindex - pokedex_context->cursor_position_top);
325
+            }
326
+            m4aSongNumStart(601);
327
+            fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 0, 16, 0x0000);
328
+            break;
329
+        case KEY_LEFT:
330
+            if (pokedex_context->detail_form_position != 0) {
331
+                pokedex_context->detail_form_position--;
332
+                dexdetail_update_form(pokedex_context->detail_form_position);
333
+            }
334
+            break;
335
+        case KEY_RIGHT:
336
+            if (pokedex_context->detail_forms[pokedex_context->detail_form_position].type != FORM_END) {
337
+                pokedex_context->detail_form_position++;
338
+                dexdetail_update_form(pokedex_context->detail_form_position);
339
+            }
340
+            break;
341
+        case KEY_START:
342
+            pokecry_play(pdex_lazy_lookup_entry(currentIndex)->species, 0);
343
+            break;
344
+        case KEY_UP:
345
+            if (pokedex_context->detail_scroll_amount > 0) {
346
+                pokedex_context->detail_scroll_amount--;
347
+                dexdetail_scroll_update();
348
+            }
349
+            break;
350
+        case KEY_DOWN:
351
+            if (pokedex_context->detail_scroll_amount < pokedex_context->detail_scroll_max) {
352
+                pokedex_context->detail_scroll_amount++;
353
+                dexdetail_scroll_update();
354
+            }
355
+            break;
356
+        }
357
+        break;
358
+    case 12:
359
+        if (!pal_fade_control.active) {
360
+            task_del(tid);
361
+            pdex_vram_free_bgmaps();
362
+            set_callback2(pdex_load);
363
+        }
364
+        break;
365
+    default:
366
+        break;
367
+    }
368
+}
369
+
370
+struct SpritePalette dexdetail_type_pal = {&pokemon_type_chart_pal[0], DEX_DETAIL_TYPEPAL};
371
+
372
+void dexdetail_load_gfx(void) {
373
+    rbox_init_from_templates(&dexdetail_boxes[0]);
374
+    lz77UnCompVram(pdexDetailBgTiles, (void *)0x0600C000);
375
+    LZ77UnCompWram(pdexDetailBgMap, bgid_get_tilemap(2));
376
+    gpu_pal_apply_compressed(pdexDetailBgPal, 0, 32);
377
+    gpu_pal_apply(pdex_text_pal, 15 * 16, 32);
378
+    gpu_pal_obj_alloc_tag_and_apply(&dexdetail_type_pal);
379
+
380
+    lcd_io_set(REG_ID_WIN0H, (8 << 8) | (232));
381
+    lcd_io_set(REG_ID_WIN0V, ((100 << 8) | (160)));
382
+    lcd_io_set(REG_ID_WININ, WIN_BG0 | WIN_BG1 | WIN_BG2 | WIN_BG3 | WIN_OBJ);
383
+    lcd_io_set(REG_ID_WINOUT, WIN_BG0 | WIN_BG2 | WIN_BG3 | WIN_OBJ);
384
+    bgid_mod_y_offset(1, -24576, 1);
385
+    bgid_mark_for_sync(0);
386
+}
387
+
388
+void dexdetail_load(void) {
389
+    pdex_vram_setup();
390
+    dexdetail_load_gfx();
391
+    pokedex_context->state = 0;
392
+    pokedex_context->detail_pokemon_oam = -1;
393
+    pokedex_context->detail_type_oam[0] = -1;
394
+    pokedex_context->detail_type_oam[1] = -1;
395
+    task_add(dexdetail_loop, 0);
396
+    set_callback2(pdex_cb_handler);
397
+}

+ 231
- 0
src/pokedex/pokedex_region.c Целия файл

@@ -0,0 +1,231 @@
1
+#include <agb_debug.h>
2
+#include <constants/pkmns.h>
3
+#include <pokeagb/pokeagb.h>
4
+#include <pokeagb/core/m4a.h>
5
+#include <pokedex/pdexSelectBg.h>
6
+#include <pokedex/pdexSelectRegion.h>
7
+
8
+#include "pokedex_common.h"
9
+
10
+void region_select_load(void);
11
+extern const pchar *pdex_str_regions[];
12
+extern const pchar *pdex_str_empty;
13
+
14
+const u16 region_to_dex[] = {1, 152, 252, 393, 501, 656, 728};
15
+
16
+struct TextboxTemplate region_select_boxes[] = {
17
+    {.bg_id = 0, .x = 4, .y = 7, .width = 6, .height = 3, .pal_id = 15, .charbase = 1},
18
+    {.bg_id = 0, .x = 13, .y = 7, .width = 6, .height = 3, .pal_id = 15, .charbase = 19},
19
+    {.bg_id = 0, .x = 22, .y = 7, .width = 6, .height = 3, .pal_id = 15, .charbase = 38},
20
+
21
+    {.bg_id = 0, .x = 2, .y = 17, .width = 6, .height = 2, .pal_id = 15, .charbase = 57},
22
+    {.bg_id = 0, .x = 9, .y = 17, .width = 6, .height = 2, .pal_id = 15, .charbase = 69},
23
+    {.bg_id = 0, .x = 17, .y = 17, .width = 6, .height = 2, .pal_id = 15, .charbase = 81},
24
+    {.bg_id = 0, .x = 24, .y = 17, .width = 6, .height = 2, .pal_id = 15, .charbase = 93},
25
+
26
+    {.bg_id = 0xFF},
27
+};
28
+
29
+u8 region_text_x_offset[] = {2, 4, 2, 1, 5, 1, 4};
30
+u8 region_text_y_offset[] = {7, 7, 7, 2, 2, 2, 2};
31
+u8 region_select_x_offset[] = {54, 128, 198, 38, 97, 156, 215};
32
+u8 region_select_y_offset[] = {40, 40, 40, 115, 115, 115, 115};
33
+
34
+u16 region_icons[] = {PKMN_BISASAM,   PKMN_SCHIGGY, PKMN_GLUMANDA, PKMN_ENDIVIE, PKMN_KARNIMANI, PKMN_FEURIGEL,
35
+                      PKMN_GECKARBOR, PKMN_HYDROPI, PKMN_FLEMMLI,  PKMN_CHELAST, PKMN_PLINFA,    PKMN_PANFLAM,
36
+                      PKMN_SERPIFEU,  PKMN_OTTARO,  PKMN_FLOINK,   PKMN_IGAMARO, PKMN_FROXY,     PKMN_FYNX,
37
+                      PKMN_BAUZ,      PKMN_ROBBALL, PKMN_FLAMIAU};
38
+
39
+u16 region_icons_x_offset[] = {37, 49, 58, 110, 122, 133, 182, 193, 206, 22, 33,
40
+                               43, 80, 93, 103, 139, 150, 161, 196, 207, 219};
41
+
42
+u16 region_icons_y_offset[] = {39,  17,  39, 39,  19,  39, 39,  19,  39, 117, 94,
43
+                               116, 116, 95, 115, 116, 95, 116, 120, 99, 120};
44
+
45
+bool sm_pdex_init(void) {
46
+    if (pal_fade_control.active)
47
+        return false;
48
+    audioDampenMaybe();
49
+    sav1_secure_increment(0x29); // this is something the original dex routine does, probably for statistics
50
+    /* maybe clean up safari stuff here if necessary */
51
+    overworld_free_bgmaps();
52
+
53
+    malloc_init((void *)0x2000000, 0x1C000);
54
+    set_callback2(region_select_load);
55
+    return true;
56
+}
57
+
58
+void region_select_load_gfx() {
59
+    rbox_init_from_templates(&region_select_boxes[0]);
60
+    lz77UnCompVram(pdexSelectBgTiles, (void *)0x0600C000);
61
+    LZ77UnCompWram(pdexSelectBgMap, bgid_get_tilemap(2));
62
+    gpu_pal_apply_compressed(pdexSelectBgPal, 0, 32);
63
+    gpu_pal_apply(pdex_text_pal, 15 * 16, 32);
64
+    bgid_mark_for_sync(0);
65
+}
66
+
67
+void region_oac_select(struct Object *obj) {
68
+    obj->pos1.x = region_select_x_offset[pokedex_context->region_selected];
69
+    obj->pos1.y = region_select_y_offset[pokedex_context->region_selected];
70
+}
71
+
72
+struct SpriteTiles region_select_tiles = {pdexSelectRegionTiles, 2048, DEX_REGION_SELECT};
73
+struct SpritePalette region_select_pal = {pdexSelectRegionPal, DEX_REGION_SELECT};
74
+
75
+const struct OamData region_select_oam = {
76
+    .affine_mode = 0,
77
+    .obj_mode = 0,
78
+    .mosaic = false,
79
+    .shape = 0,
80
+    .size = 3,
81
+};
82
+
83
+struct Template region_select_template = {
84
+    .tiles_tag = DEX_REGION_SELECT,
85
+    .pal_tag = DEX_REGION_SELECT,
86
+    .oam = &region_select_oam,
87
+    .animation = &anim_image_empty,
88
+    .graphics = &region_select_tiles,
89
+    .rotscale = &rotscale_empty,
90
+    .callback = region_oac_select,
91
+};
92
+
93
+void region_load_icon_palettes(void) {
94
+    for (u8 i = 0; i < 3; ++i) {
95
+        struct SpritePalette current = {pokeicon_pals[i], DEX_REGION_PAL(i)};
96
+        gpu_pal_obj_alloc_tag_and_apply(&current);
97
+    }
98
+}
99
+
100
+const struct OamData region_icon_oam = {
101
+    .affine_mode = 0,
102
+    .obj_mode = 0,
103
+    .mosaic = false,
104
+    .shape = 0,
105
+    .size = 2,
106
+};
107
+
108
+void region_load_icon(u8 i) {
109
+    struct SpriteTiles current = {pokeicon_table[region_icons[i]], 512, DEX_REGION_ICON(i)};
110
+    gpu_tile_obj_alloc_tag_and_upload(&current);
111
+    struct Template region_icon_template = {
112
+        .tiles_tag = DEX_REGION_ICON(i),
113
+        .pal_tag = DEX_REGION_PAL(pokeicon_pal_indices[region_icons[i]]),
114
+        .oam = &region_icon_oam,
115
+        .animation = &anim_image_empty,
116
+        .graphics = &current,
117
+        .rotscale = &rotscale_empty,
118
+        .callback = oac_nullsub,
119
+    };
120
+    template_instanciate_forward_search(&region_icon_template, region_icons_x_offset[i], region_icons_y_offset[i], 0);
121
+}
122
+
123
+void region_load_border() {
124
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&region_select_tiles);
125
+    gpu_pal_obj_alloc_tag_and_apply(&region_select_pal);
126
+    (void)template_instanciate_forward_search(&region_select_template, 100, 100, 0);
127
+}
128
+
129
+void region_loop(u8 tid) {
130
+    (void)tid;
131
+    switch (pokedex_context->state) {
132
+    case 0:
133
+        bgid_send_tilemap(2);
134
+
135
+        for (u8 i = 0; i < 7; ++i) {
136
+            rboxid_clear_pixels(i, 0);
137
+            rboxid_print(i, FONT_DEX_STD, region_text_x_offset[i], region_text_y_offset[i], &pdex_text_color, 0,
138
+                         pdex_str_regions[i + 1]);
139
+            rboxid_update_tilemap_and_tileset(i);
140
+        }
141
+
142
+        region_load_border();
143
+        region_load_icon_palettes();
144
+        for (u8 i = 0; i < 21; ++i)
145
+            region_load_icon(i);
146
+
147
+        palette_bg_faded_fill_black();
148
+        pokedex_context->state++;
149
+        break;
150
+    case 1:
151
+        gpu_sync_bg_show(0);
152
+        gpu_sync_bg_hide(1);
153
+        gpu_sync_bg_hide(3);
154
+
155
+        gpu_sync_bg_show(2);
156
+        fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 16, 0, 0x0000);
157
+        pokedex_context->state++;
158
+        break;
159
+    case 2:
160
+        if (!pal_fade_control.active)
161
+            pokedex_context->state++;
162
+        break;
163
+    case 3:
164
+        switch (super.buttons_new) {
165
+        case KEY_RIGHT:
166
+            if (pokedex_context->region_selected < 6) {
167
+                pokedex_context->region_selected++;
168
+                m4aSongNumStart(101);
169
+            }
170
+            break;
171
+        case KEY_DOWN:
172
+            if (pokedex_context->region_selected < 3) {
173
+                pokedex_context->region_selected += 3;
174
+                m4aSongNumStart(101);
175
+            }
176
+            break;
177
+        case KEY_LEFT:
178
+            if (pokedex_context->region_selected > 0) {
179
+                pokedex_context->region_selected--;
180
+                m4aSongNumStart(101);
181
+            }
182
+            break;
183
+        case KEY_UP:
184
+            if ((pokedex_context->region_selected > 2) && (pokedex_context->region_selected < 6)) {
185
+                pokedex_context->region_selected -= 3;
186
+                m4aSongNumStart(101);
187
+            }
188
+            break;
189
+        case KEY_A:
190
+            fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 0, 16, 0x0000);
191
+            pokedex_context->state = 10;
192
+            m4aSongNumStart(5);
193
+            break;
194
+        case KEY_B:
195
+            fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 0, 16, 0x0000);
196
+            pokedex_context->state = 11;
197
+            m4aSongNumStart(601);
198
+        default:
199
+            break;
200
+        }
201
+        break;
202
+    case 10:
203
+        if (!pal_fade_control.active) {
204
+            task_del(tid);
205
+            pdex_vram_free_bgmaps();
206
+            pokedex_context->cursor_position_top = region_to_dex[pokedex_context->region_selected];
207
+            set_callback2(pdex_load);
208
+        }
209
+        break;
210
+    case 11:
211
+        if (!pal_fade_control.active) {
212
+            task_del(tid);
213
+            pdex_free_memory();
214
+            set_callback2(c2_overworld_switch_start_menu);
215
+            set_callback1(c1_overworld);
216
+        }
217
+        break;
218
+    default:
219
+
220
+        break;
221
+    }
222
+}
223
+
224
+void region_select_load(void) {
225
+    pdex_vram_setup();
226
+    pdex_alloc_memory();
227
+
228
+    region_select_load_gfx();
229
+    task_add(region_loop, 0);
230
+    set_callback2(pdex_cb_handler);
231
+}

+ 97
- 0
src/pokedex/pokedex_string.s Целия файл

@@ -0,0 +1,97 @@
1
+.align 2
2
+.thumb
3
+.text
4
+.global pdex_str_title
5
+pdex_str_title:
6
+    .string LAN_DE "Amitec Pokédex"
7
+    .string LAN_EN "Amitec Pokédex"
8
+
9
+.global pdex_str_seen
10
+pdex_str_seen:
11
+    .string LAN_DE "Ges.:"
12
+    .string LAN_EN "Seen:"
13
+
14
+.global pdex_str_caught
15
+pdex_str_caught:
16
+    .string LAN_DE "Gef.:"
17
+    .string LAN_EN "Caught:"
18
+
19
+.global pdex_str_size
20
+pdex_str_size:
21
+    .string LAN_DE "Größe:"
22
+    .string LAN_EN "Size:"
23
+
24
+.global pdex_str_weight
25
+pdex_str_weight:
26
+    .string LAN_DE "Gewicht:"
27
+    .string LAN_EN "Weight:"
28
+
29
+.global pdex_str_size_unit
30
+pdex_str_size_unit:
31
+    .string LAN_DE "m"
32
+    .string LAN_EN "m"
33
+
34
+.global pdex_str_weight_unit
35
+pdex_str_weight_unit:
36
+    .string LAN_DE "kg"
37
+    .string LAN_EN "kg"
38
+
39
+.global pdex_str_comma
40
+pdex_str_comma:
41
+    .string LAN_DE ","
42
+    .string LAN_EN ","
43
+
44
+.global pdex_str_empty
45
+pdex_str_empty:
46
+    .string LAN_DE "----------"
47
+    .string LAN_EN "----------"
48
+
49
+.global pdex_str_form_alola
50
+pdex_str_form_alola:
51
+    .string LAN_DE " (Alola)"
52
+    .string LAN_DE " (Alola)"
53
+
54
+.align 2
55
+.global pdex_str_regions
56
+pdex_str_regions:
57
+.word pdex_str_empty
58
+.word pdex_str_kanto
59
+.word pdex_str_jotho
60
+.word pdex_str_hoeen
61
+.word pdex_str_sinnoh
62
+.word pdex_str_unova
63
+.word pdex_str_kalos
64
+.word pdex_str_alola
65
+
66
+pdex_str_kanto:
67
+    .string LAN_DE "Kanto"
68
+    .string LAN_EN "Kanto"
69
+
70
+pdex_str_jotho:
71
+    .string LAN_DE "Johto"
72
+    .string LAN_EN "Johto"
73
+
74
+pdex_str_hoeen:
75
+    .string LAN_DE "Hoenn"
76
+    .string LAN_EN "Hoenn"
77
+
78
+pdex_str_sinnoh:
79
+    .string LAN_DE "Sinnoh"
80
+    .string LAN_EN "Sinnoh"
81
+
82
+pdex_str_unova:
83
+    .string LAN_DE "Einall"
84
+    .string LAN_EN " Unova"
85
+
86
+pdex_str_kalos:
87
+    .string LAN_DE "Kalos"
88
+    .string LAN_EN "Kalos"
89
+
90
+pdex_str_alola:
91
+    .string LAN_DE "Alola"
92
+    .string LAN_EN "Alola"
93
+
94
+.global pdex_entry_debug
95
+pdex_entry_debug:
96
+    .string LAN_DE "Glurak fliegt durch die Lüfte, um starke\nGegner aufzuspüren. Sein heißer Feuer-\natem bringt alles zum Schmelzen.\nAber es richtet seinen Feueratem nie auf\nschwächere Gegner."
97
+    .string LAN_EN "Glurak fliegt durch die Lüfte, um starke Gegner aufzuspüren.\nSein heißer Feueratem bringt alles zum Schmelzen.\nAber es richtet seinen Feueratem nie auf schwächere Gegner."