Explorar el Código

idk sry, may or may not have coded half of this while on ballmers peak

SBird1337 hace 6 años
padre
commit
f6acbd5db3

+ 1
- 0
.gitignore Ver fichero

@@ -12,3 +12,4 @@ nbproject/private/tools/
12 12
 build/*
13 13
 generated_image/*
14 14
 .vscode/*
15
+todo/

+ 1
- 1
g3headers

@@ -1 +1 @@
1
-Subproject commit 8d64b390cbaf2e1fc9a09fbf0edb339847954332
1
+Subproject commit 9d639a8abcba11d78a999fec9f777fb473179e06

+ 1
- 0
main.asm Ver fichero

@@ -62,6 +62,7 @@
62 62
 
63 63
 .include "patches/game_engine/quick_hacks.asm"
64 64
 .include "patches/game_engine/localization.asm"
65
+.include "patches/game_engine/start_menu.asm"
65 66
 
66 67
 //.include "battle_engine/patches/battle_hooks.s"
67 68
 

+ 5
- 0
patches/game_engine/start_menu.asm Ver fichero

@@ -0,0 +1,5 @@
1
+.org 0x0806F404
2
+.word sm_pdex_init+1
3
+
4
+.org (0x083A7344+4)
5
+.word sm_pdex_init+1

+ 4
- 0
patches/overworlds/trainer.asm Ver fichero

@@ -8,3 +8,7 @@ ldr r2, =tb_on_spot+1
8 8
 bx r2
9 9
 .pool
10 10
 
11
+.org 0x080BC3A0
12
+ldr r1, =battle_intro_launch+1
13
+bx r1
14
+.pool

+ 1
- 1
sots-private

@@ -1 +1 @@
1
-Subproject commit b5a966c9e5a05bfe9c3fde5f702e927acb973815
1
+Subproject commit 9b11de697e06bb46f12c58e5ca31817cd65e0317

+ 11
- 11
src/battle_engine/battle_abilities.c Ver fichero

@@ -30,23 +30,23 @@
30 30
 /* === INCLUDE === */
31 31
 #include <battle_abilities.h>
32 32
 #include <battle_custom_structs.h>
33
-#include <battle_structs.h>
33
+//#include <battle_structs.h>
34
+#include <pokeagb/pokeagb.h>
34 35
 
35 36
 /* === IMPLEMENTATIONS === */
36
-u8 ability_has_effect(u8 bank, u8 mold_breaker, u8 gastro)
37
-{
38
-    if(gastro && custom_battle_elements.ptr->bank_affecting[bank].gastro_acided)
37
+u8 ability_has_effect(u8 bank, u8 mold_breaker, u8 gastro) {
38
+    (void)mold_breaker;
39
+
40
+    if (gastro && custom_battle_elements.ptr->bank_affecting[bank].gastro_acided)
39 41
         return false;
40 42
     return true;
41
-    //TODO: MOLD BREAKER
43
+    // TODO: MOLD BREAKER
42 44
 }
43 45
 
44
-u8 ability_weather_effects()
45
-{
46
-    //TODO: AIR LOCK AND CLOUD NINE
46
+u8 ability_weather_effects() {
47
+    // TODO: AIR LOCK AND CLOUD NINE
47 48
     return true;
48 49
 }
49
-u8 ability_has_ability(u8 bank, u8 ability)
50
-{
51
-    return (ability_has_effect(bank,0,1) && battle_participants[bank].ability_id == ability);
50
+u8 ability_has_ability(u8 bank, u8 ability) {
51
+    return (ability_has_effect(bank, 0, 1) && battle_data[bank].ability_id == ability);
52 52
 }

+ 6
- 7
src/battle_engine/battle_end_of_turn.c Ver fichero

@@ -29,8 +29,7 @@
29 29
 
30 30
 /* === INCLUDE === */
31 31
 
32
-#include <battle_structs.h>
33
-#include <constants/ptypes.h>
32
+#include <pokeagb/pokeagb.h>
34 33
 
35 34
 /* === PROTOTYPES === */
36 35
 
@@ -41,11 +40,11 @@ void battle_end_of_turn();
41 40
 
42 41
 /* === IMPLEMENTATIONS === */
43 42
 void battle_end_of_turn() {
44
-    for (int i = 0; i < 4; ++i) {
45
-        if (battle_participants[i].type1 == TYPE_EGG)
46
-            battle_participants[i].type1 = TYPE_FLYING;
47
-        if (battle_participants[i].type2 == TYPE_EGG)
48
-            battle_participants[i].type2 = TYPE_FLYING;
43
+    for (u32 i = 0; i < 4; ++i) {
44
+        if (battle_data[i].type1 == TYPE_NONE)
45
+            battle_data[i].type1 = TYPE_FLYING;
46
+        if (battle_data[i].type2 == TYPE_NONE)
47
+            battle_data[i].type2 = TYPE_FLYING;
49 48
     }
50 49
     return;
51 50
 }

+ 3
- 3
src/battle_engine/battle_help.c Ver fichero

@@ -33,12 +33,12 @@
33 33
 #include <battle_custom_structs.h>
34 34
 #include <battle_help.h>
35 35
 #include <battle_locations.h>
36
-#include <game_engine.h>
37 36
 #include <constants/abilities.h>
38
-#include <pkmn_attributes.h> /*TODO: POKEAGB */
39
-#include <pkmn_item_effects.h>
40 37
 #include <constants/items.h>
41 38
 #include <constants/ptypes.h>
39
+#include <game_engine.h>
40
+#include <pkmn_attributes.h> /*TODO: POKEAGB */
41
+#include <pkmn_item_effects.h>
42 42
 
43 43
 /* === STATICS === */
44 44
 

+ 57
- 54
src/battle_engine/battle_initiative.c Ver fichero

@@ -29,18 +29,18 @@
29 29
 
30 30
 /* === INCLUDE === */
31 31
 
32
-#include <battle_initiative.h>
33
-#include <pkmn_item_effects.h>
34
-#include <pokemon.h>
35
-#include <battle_help.h>
36
-#include <constants/abilities.h>
37
-#include <math.h>
38
-#include <battle_common.h>
39 32
 #include <battle_abilities.h>
40
-#include <battle_structs.h>
41
-#include <battle_locations.h>
33
+#include <battle_common.h>
42 34
 #include <battle_custom_structs.h>
43 35
 #include <battle_fractions.h>
36
+#include <battle_help.h>
37
+#include <battle_initiative.h>
38
+#include <battle_locations.h>
39
+#include <battle_structs.h>
40
+#include <constants/abilities.h>
41
+#include <math.h>
42
+#include <pkmn_item_effects.h>
43
+#include <pokemon.h>
44 44
 
45 45
 /* === EXTERN STRUCTS === */
46 46
 
@@ -51,41 +51,44 @@ struct move_info move_table[1024];
51 51
 u16 get_speed(u8 bank) {
52 52
     u32 speed = battle_participants[bank].spd << 16;
53 53
     switch (battle_item_get_effect(bank, 1)) {
54
-        case ITEM_EFFECT_IRONBALL:
55
-            speed >>= 1;
56
-            break;
57
-        case ITEM_EFFECT_CHOICESCARF:
58
-            speed = (speed * 150) / 100;
59
-            break;
60
-        case ITEM_EFFECT_QUICKPOWDER:
61
-            if (battle_participants[bank].poke_species == POKE_DITTO && !battle_participants[bank].status2.transformed)
62
-                speed <<= 1;
63
-            break;
54
+    case ITEM_EFFECT_IRONBALL:
55
+        speed >>= 1;
56
+        break;
57
+    case ITEM_EFFECT_CHOICESCARF:
58
+        speed = (speed * 150) / 100;
59
+        break;
60
+    case ITEM_EFFECT_QUICKPOWDER:
61
+        if (battle_participants[bank].poke_species == POKE_DITTO && !battle_participants[bank].status2.transformed)
62
+            speed <<= 1;
63
+        break;
64 64
     }
65 65
     if (ability_has_effect(bank, 0, 1)) {
66 66
         u8 weather_effects = ability_weather_effects();
67 67
         switch (battle_participants[bank].ability_id) {
68
-            case ABILITY_CHLOROPHYLL:
69
-                if (weather_effects && (battle_weather.flags.harsh_sun || battle_weather.flags.permament_sun || battle_weather.flags.sun))
70
-                    speed *= 2;
71
-                break;
72
-            case ABILITY_SWIFT_SWIM:
73
-                if (weather_effects && (battle_weather.flags.rain || battle_weather.flags.downpour || battle_weather.flags.permament_rain || battle_weather.flags.heavy_rain))
74
-                    speed *= 2;
75
-                break;
76
-            case ABILITY_SAND_RUSH:
77
-                if (weather_effects && (battle_weather.flags.sandstorm || battle_weather.flags.permament_sandstorm))
78
-                    speed *= 2;
79
-                break;
80
-            case ABILITY_QUICK_FEET:
81
-                if (battle_participants[bank].status.flags.burn || battle_participants[bank].status.flags.poison || battle_participants[bank].status.flags.toxic_poison)
82
-                    speed = speed + ((speed * 50) / 100);
83
-                else if (battle_participants[bank].status.flags.paralysis) {
84
-                    /* cancel para */
85
-                    speed *= 4;
86
-                    speed = speed + ((speed * 50) / 100);
87
-                }
88
-                break;
68
+        case ABILITY_CHLOROPHYLL:
69
+            if (weather_effects &&
70
+                (battle_weather.flags.harsh_sun || battle_weather.flags.permament_sun || battle_weather.flags.sun))
71
+                speed *= 2;
72
+            break;
73
+        case ABILITY_SWIFT_SWIM:
74
+            if (weather_effects && (battle_weather.flags.rain || battle_weather.flags.downpour ||
75
+                                    battle_weather.flags.permament_rain || battle_weather.flags.heavy_rain))
76
+                speed *= 2;
77
+            break;
78
+        case ABILITY_SAND_RUSH:
79
+            if (weather_effects && (battle_weather.flags.sandstorm || battle_weather.flags.permament_sandstorm))
80
+                speed *= 2;
81
+            break;
82
+        case ABILITY_QUICK_FEET:
83
+            if (battle_participants[bank].status.flags.burn || battle_participants[bank].status.flags.poison ||
84
+                battle_participants[bank].status.flags.toxic_poison)
85
+                speed = speed + ((speed * 50) / 100);
86
+            else if (battle_participants[bank].status.flags.paralysis) {
87
+                /* cancel para */
88
+                speed *= 4;
89
+                speed = speed + ((speed * 50) / 100);
90
+            }
91
+            break;
89 92
         }
90 93
     }
91 94
     if (battle_participants[bank].status.flags.paralysis)
@@ -94,24 +97,25 @@ u16 get_speed(u8 bank) {
94 97
         speed *= 2;
95 98
     if (battle_status_3[bank].unburden)
96 99
         speed *= 2;
97
-    //TODO: /* SWAMP EFFECT */
98
-    speed = (speed * stat_buffs[battle_participants[bank].spd_buff].dividend) / (stat_buffs[battle_participants[bank].spd_buff].divisor);
99
-    return (u16) (speed >> 16);
100
+    // TODO: /* SWAMP EFFECT */
101
+    speed = (speed * stat_buffs[battle_participants[bank].spd_buff].dividend) /
102
+            (stat_buffs[battle_participants[bank].spd_buff].divisor);
103
+    return (u16)(speed >> 16);
100 104
 }
101 105
 
102 106
 u8 speed_alt_from_item(u8 bank, u8 item_effect) {
103 107
     switch (item_effect) {
104
-        case ITEM_EFFECT_QUICKCLAW:
105
-            if ((battle_turn_random % 100) > item_get_quality(battle_participants[bank].held_item)) {
106
-                return 1;
107
-            }
108
-            break;
109
-        case ITEM_EFFECT_CUSTAPBERRY:
110
-            //TODO: implement HP CONDITION
108
+    case ITEM_EFFECT_QUICKCLAW:
109
+        if ((battle_turn_random % 100) > item_get_quality(battle_participants[bank].held_item)) {
111 110
             return 1;
112
-            break;
113
-        case ITEM_EFFECT_LAGGINGTAIL:
114
-            return -1;
111
+        }
112
+        break;
113
+    case ITEM_EFFECT_CUSTAPBERRY:
114
+        // TODO: implement HP CONDITION
115
+        return 1;
116
+        break;
117
+    case ITEM_EFFECT_LAGGINGTAIL:
118
+        return -1;
115 119
     }
116 120
     return 0;
117 121
 }
@@ -175,4 +179,3 @@ enum init_enum get_first_to_strike(u8 bank_one, u8 bank_two, u8 ignore_prio) {
175 179
     }
176 180
     return result;
177 181
 }
178
-

+ 9
- 11
src/battle_engine/battle_test.c Ver fichero

@@ -27,14 +27,14 @@
27 27
  * @brief Unit tests for battles, very temporary and undocumented
28 28
  */
29 29
 
30
-#include <types.h>
31
-#include <battle_test.h>
32
-#include <debug.h>
33
-#include <battle_initiative.h>
34
-#include <constants/abilities.h>
35
-#include <battle_structs.h>
36 30
 #include <battle_common.h>
37 31
 #include <battle_custom_structs.h>
32
+#include <battle_initiative.h>
33
+#include <battle_structs.h>
34
+#include <battle_test.h>
35
+#include <constants/abilities.h>
36
+#include <debug.h>
37
+#include <types.h>
38 38
 
39 39
 #define TEST_AMOUNT 10000
40 40
 
@@ -69,7 +69,7 @@ void test_speed() {
69 69
     debug_printf("bank_one.spd: %d\n", battle_participants[0].spd);
70 70
     debug_printf("bank_two.spd: %d\n", battle_participants[1].spd);
71 71
 
72
-    //trick room
72
+    // trick room
73 73
     custom_battle_elements.ptr->field_affecting.trick_room = 1;
74 74
     debug_print("activating trick room...\n");
75 75
     debug_print("testing (await ONE):");
@@ -104,7 +104,7 @@ void test_speed() {
104 104
     }
105 105
     custom_battle_elements.ptr->field_affecting.trick_room = 0;
106 106
     debug_print("stall test (-tr): ");
107
-    
107
+
108 108
     result = get_first_to_strike(0, 1, 0);
109 109
     if (result == ONE)
110 110
         debug_print("\xFE\x1 pass\n\xFE\x0");
@@ -238,7 +238,6 @@ void test_speed() {
238 238
     battle_weather.flags.sun = 0;
239 239
     battle_weather.flags.sandstorm = 0;
240 240
 
241
-
242 241
     debug_print("quick feet: ");
243 242
     battle_participants[0].ability_id = ABILITY_QUICK_FEET;
244 243
     battle_participants[1].ability_id = ABILITY_QUICK_FEET;
@@ -271,7 +270,7 @@ void test_speed() {
271 270
     battle_participants[1].ability_id = 0;
272 271
     debug_wait_for_btn(8);
273 272
     debug_clean();
274
-    //stress
273
+    // stress
275 274
     battle_participants[0].spd = 20;
276 275
     battle_participants[1].spd = 20;
277 276
     debug_printf("bank_one.spd: %d\n", battle_participants[0].spd);
@@ -297,7 +296,6 @@ void test_speed() {
297 296
     debug_wait_for_btn(1);
298 297
     debug_clean();
299 298
 
300
-
301 299
     if (pass)
302 300
         debug_set_bg(0x3E0);
303 301
     else

+ 20
- 25
src/battle_engine/custom_structs_malloc.c Ver fichero

@@ -27,16 +27,15 @@
27 27
  * @brief Patch hacks for handling custom battle structures
28 28
  */
29 29
 
30
-
31 30
 /* === INCLUDE === */
32 31
 
32
+#include <battle_common.h>
33 33
 #include <battle_custom_structs.h>
34
+#include <battle_locations.h>
34 35
 #include <config/core.h>
36
+#include <constants/moves.h>
35 37
 #include <game_engine.h>
36 38
 #include <memory.h>
37
-#include <constants/moves.h>
38
-#include <battle_common.h>
39
-#include <battle_locations.h>
40 39
 
41 40
 /* === PROTOTYPES === */
42 41
 
@@ -57,40 +56,35 @@ void battle_switch_in();
57 56
 
58 57
 /* === IMPLEMENTATIONS === */
59 58
 
60
-void malloc_battle_structs()
61
-{
62
-    custom_battle_elements.ptr=(struct custom_battle_struct*)malloc(sizeof(struct custom_battle_struct));
59
+void malloc_battle_structs() {
60
+    custom_battle_elements.ptr = (struct custom_battle_struct *)malloc(sizeof(struct custom_battle_struct));
63 61
 }
64 62
 
65
-void free_battle_structs()
66
-{
63
+void free_battle_structs() {
67 64
     free(custom_battle_elements.ptr);
68
-    custom_battle_elements.ptr=0;
65
+    custom_battle_elements.ptr = 0;
69 66
     flag_clear(FLAG_DEOXYS_AURA);
70 67
     flag_clear(FLAG_SKIP_BATTLE_MUSIC);
71 68
 }
72 69
 
73
-//hijack switch in command, clean up battle structs and carry over baton pass
74
-void battle_switch_in()
75
-{
76
-    struct bank_affecting* current_bank_affecting = &custom_battle_elements.ptr->bank_affecting[battle_active_bank];
77
-    //copy of the old structure to carry over baton pass effects
70
+// hijack switch in command, clean up battle structs and carry over baton pass
71
+void battle_switch_in() {
72
+    struct bank_affecting *current_bank_affecting = &custom_battle_elements.ptr->bank_affecting[battle_active_bank];
73
+    // copy of the old structure to carry over baton pass effects
78 74
     struct bank_affecting prev_bank_affecting = custom_battle_elements.ptr->bank_affecting[battle_active_bank];
79 75
     memset(current_bank_affecting, 0, sizeof(struct bank_affecting));
80
-    //handle type 3 if needed
76
+    // handle type 3 if needed
81 77
     current_bank_affecting->just_switched_in = 1;
82 78
     current_bank_affecting->wish_hp = prev_bank_affecting.wish_hp;
83
-    if(battle_executed_move == MOVE_BATON_PASS)
84
-    {
79
+    if (battle_executed_move == MOVE_BATON_PASS) {
85 80
         current_bank_affecting->aqua_ring = prev_bank_affecting.aqua_ring;
86 81
         current_bank_affecting->embargo = prev_bank_affecting.embargo;
87 82
         current_bank_affecting->powertrick = prev_bank_affecting.powertrick;
88 83
         current_bank_affecting->gastro_acided = prev_bank_affecting.gastro_acided;
89 84
         current_bank_affecting->heal_block = prev_bank_affecting.heal_block;
90
-        
91
-        if(prev_bank_affecting.powertrick)
92
-        {
93
-            //carry over switched stats of power trick
85
+
86
+        if (prev_bank_affecting.powertrick) {
87
+            // carry over switched stats of power trick
94 88
             u16 *atk = &battle_participants[battle_active_bank].atk;
95 89
             u16 *def = &battle_participants[battle_active_bank].def;
96 90
             u16 switch_var = *atk;
@@ -98,12 +92,13 @@ void battle_switch_in()
98 92
             *def = switch_var;
99 93
         }
100 94
     }
101
-    
102
-    struct side_affecting* active_side = &custom_battle_elements.ptr->side_affecting[get_side_from_bank(battle_active_bank)];
95
+
96
+    struct side_affecting *active_side =
97
+        &custom_battle_elements.ptr->side_affecting[get_side_from_bank(battle_active_bank)];
103 98
     active_side->stealth_rock_done = 0;
104 99
     active_side->sticky_web_done = 0;
105 100
     active_side->toxic_spikes_done = 0;
106 101
     active_side->lunardance_done = 0;
107
-    
102
+
108 103
     return;
109 104
 }

+ 16
- 0
src/overworld/trainerbattle_init.c Ver fichero

@@ -0,0 +1,16 @@
1
+#include <pokeagb/pokeagb.h>
2
+
3
+void battle_intro_launch(u8 environment) {
4
+    TaskCallback introTask;
5
+    if (battle_type_flags & BATTLE_FLAG_LINK) {
6
+        introTask = (TaskCallback)(0x080BCC4C | 1);
7
+    } else if (battle_type_flags & 0x1000 && build_edition_identifier != 2) {
8
+        introTask = (TaskCallback)(0x080BC6C8 | 1);
9
+    } else {
10
+        introTask = task00_battle_intro_by_env[environment];
11
+    }
12
+    struct Task *livingTask = &tasks[task_add(introTask, 0)];
13
+    for (u8 i = 0; i <= 6; ++i)
14
+        livingTask->priv[i] = 0;
15
+    livingTask->priv[1] = environment;
16
+}

+ 397
- 0
src/pokedex/pokedex.c Ver fichero

@@ -0,0 +1,397 @@
1
+#include <agb_debug.h>
2
+#include <pokeagb/pokeagb.h>
3
+#include <pokedex/pdexBall.h>
4
+#include <pokedex/pdexBg.h>
5
+#include <pokedex/pdexSelectHalf.h>
6
+
7
+#define PDEX_FADEIN_SPD 1
8
+#define TB_TITLE 0
9
+#define TB_PKMN 1
10
+#define TB_SEEN 2
11
+#define TB_CAUGHT 3
12
+#define TB_MAIN 4
13
+
14
+#define FONT_DEX_STD 1
15
+#define TB_STD_LEN 10
16
+#define TB_STD_LEN_PX (TB_STD_LEN * 8)
17
+#define TB_BOT_LEN 9
18
+#define TB_BOT_LEN_PX (TB_BOT_LEN * 8)
19
+#define TB_STD_CENTER(t) (((TB_STD_LEN_PX - t) >> 1) + 2)
20
+#define TB_STD_RIGHT(t) ((TB_BOT_LEN_PX - t))
21
+
22
+#define OBJID_HIDE(objid) objects[objid].final_oam.affine_mode = 2
23
+#define OBJID_SHOW(objid) objects[objid].final_oam.affine_mode = 0
24
+
25
+#define TB_SEEN_Y (6)
26
+#define TB_CAUGHT_Y 3
27
+
28
+#define DEX_PKMN_TAG 0x1300
29
+#define DEX_BALL_TAG 0x1301
30
+#define DEX_CURSOR_TAG 0x1302
31
+
32
+#define MAX3_COUNT_DIGITS(n) (n >= 100 ? 3 : (n >= 10 ? 2 : 1))
33
+
34
+#define CPUFSCPY 0
35
+#define CPUFSSET 1
36
+#define CPUModeFS(size, mode) ((size >> 2) | (mode << 24))
37
+
38
+void pdex_load(void);
39
+void pdex_vblank_handler(void);
40
+void pdex_loop(u8 tid);
41
+void pdex_cb_handler(void);
42
+
43
+extern const pchar pdex_str_title[];
44
+extern const pchar pdex_str_seen[];
45
+extern const pchar pdex_str_caught[];
46
+extern const pchar pdex_str_empty[];
47
+
48
+static const u8 pdex_y_offset[] = {3,          16 + 2,     2 * 16 + 1, 3 * 16,    4 * 16 - 1,
49
+                                   5 * 16 - 2, 6 * 16 - 3, 7 * 16 - 4, 8 * 16 - 5};
50
+
51
+const u16 pdex_text_pal[] = {rgb5(255, 0, 255), rgb5(255, 255, 255), rgb5(0, 0, 0),     rgb5(255, 0, 255),
52
+                             rgb5(255, 0, 255), rgb5(255, 0, 255),   rgb5(255, 0, 255), rgb5(255, 0, 255),
53
+                             rgb5(255, 0, 255), rgb5(255, 0, 255),   rgb5(255, 0, 255), rgb5(255, 0, 255),
54
+                             rgb5(255, 0, 255), rgb5(255, 0, 255),   rgb5(255, 0, 255), rgb5(255, 0, 255)};
55
+
56
+struct TextColor pdex_text_color = {0, 1, 2};
57
+
58
+struct TextboxTemplate pdex_boxes[] = {
59
+    {.bg_id = 0, .x = 11, .y = 0, .width = 10, .height = 2, .pal_id = 15, .charbase = 1},
60
+    {.bg_id = 0, .x = 2, .y = 2, .width = 10, .height = 2, .pal_id = 15, .charbase = 21},
61
+    {.bg_id = 0, .x = 3, .y = 14, .width = 9, .height = 3, .pal_id = 15, .charbase = 41},
62
+    {.bg_id = 0, .x = 3, .y = 17, .width = 9, .height = 2, .pal_id = 15, .charbase = 59},
63
+
64
+    {.bg_id = 0, .x = 16, .y = 2, .width = 11, .height = 17, .pal_id = 15, .charbase = 77},
65
+
66
+    {.bg_id = 0xFF},
67
+};
68
+
69
+const struct BgConfig pdex_bg_config[4] = {
70
+    {
71
+        .padding = 0,
72
+        .b_padding = 0,
73
+        .priority = 0,
74
+        .palette = 0,
75
+        .size = 0,
76
+        .map_base = 29,
77
+        .character_base = 0,
78
+        .bgid = 0,
79
+    },
80
+    {
81
+        .padding = 0,
82
+        .b_padding = 0,
83
+        .priority = 1,
84
+        .palette = 0,
85
+        .size = 0,
86
+        .map_base = 28,
87
+        .character_base = 0,
88
+        .bgid = 1,
89
+    },
90
+    {
91
+        .padding = 0,
92
+        .b_padding = 0,
93
+        .priority = 2,
94
+        .palette = 0,
95
+        .size = 0,
96
+        .map_base = 30,
97
+        .character_base = 3,
98
+        .bgid = 2,
99
+    },
100
+    {
101
+        .padding = 0,
102
+        .b_padding = 0,
103
+        .priority = 3,
104
+        .palette = 0,
105
+        .size = 1,
106
+        .map_base = 31,
107
+        .character_base = 3,
108
+        .bgid = 3,
109
+    },
110
+};
111
+
112
+void pdex_main_box_species_fill(u8 n, u16 species, bool seen, bool caught) {
113
+    rboxid_fill_rectangle(TB_MAIN, 0, 0, pdex_y_offset[n], 11 * 8, 12);
114
+    const pchar *stringToPrint = (seen || caught) ? &pokemon_names[species][0] : &pdex_str_empty[0];
115
+    const pchar stringWhitespace[] = {0x0, 0xFF};
116
+    fmt_int_10(string_buffer, species, 2, 3);
117
+    pstrcat(string_buffer, &stringWhitespace[0]);
118
+    pstrcat(string_buffer, stringToPrint);
119
+    rboxid_print(TB_MAIN, FONT_DEX_STD, 4, pdex_y_offset[n], &pdex_text_color, 0, string_buffer);
120
+    // show the pokéball if necessary
121
+}
122
+
123
+void pdex_init_dex_boxes(void) {
124
+    /* fill with dummy data */
125
+    rboxid_clear_pixels(TB_MAIN, 0);
126
+    for (u8 i = 0; i < 9; ++i) {
127
+        pdex_main_box_species_fill(i, i + 1, false, false);
128
+    }
129
+    // rboxid_fill_rectangle(TB_MAIN, 1, 0,0, 10*8, 18*8);
130
+    rboxid_update_tilemap_and_tileset(TB_MAIN);
131
+}
132
+
133
+void pdex_load_sc(void) {
134
+    rboxid_clear_pixels(TB_SEEN, 0);
135
+    rboxid_clear_pixels(TB_CAUGHT, 0);
136
+    u32 seen = pokedex_count(false) + 10;
137
+    u32 caught = pokedex_count(true);
138
+    pchar seenBuffer[4];
139
+    pchar caughtBuffer[4];
140
+    fmt_int_10(seenBuffer, seen, 0, MAX3_COUNT_DIGITS(seen));
141
+    fmt_int_10(caughtBuffer, caught, 0, MAX3_COUNT_DIGITS(caught));
142
+
143
+    u32 twidthSeen = font_get_width_of_string(FONT_DEX_STD, seenBuffer, 0x0000);
144
+    u32 twidthCaught = font_get_width_of_string(FONT_DEX_STD, caughtBuffer, 0x0000);
145
+
146
+    rboxid_print(TB_SEEN, FONT_DEX_STD, 0, TB_SEEN_Y, &pdex_text_color, 0, &pdex_str_seen[0]);
147
+    rboxid_print(TB_CAUGHT, FONT_DEX_STD, 0, TB_CAUGHT_Y, &pdex_text_color, 0, &pdex_str_caught[0]);
148
+
149
+    rboxid_print(TB_SEEN, FONT_DEX_STD, TB_STD_RIGHT(twidthSeen), TB_SEEN_Y + 1, &pdex_text_color, 0, seenBuffer);
150
+    rboxid_print(TB_CAUGHT, FONT_DEX_STD, TB_STD_RIGHT(twidthCaught), TB_CAUGHT_Y + 1, &pdex_text_color, 0,
151
+                 caughtBuffer);
152
+
153
+    rboxid_update_tilemap_and_tileset(TB_SEEN);
154
+    rboxid_update_tilemap_and_tileset(TB_CAUGHT);
155
+}
156
+
157
+const struct OamData pdex_oam_pkmn = {
158
+    .affine_mode = 0,
159
+    .obj_mode = 0,
160
+    .mosaic = false,
161
+    .shape = 0,
162
+    .size = 3,
163
+};
164
+
165
+void pdex_pokemon_load(u16 species) {
166
+    /* this is very temporary */
167
+    rboxid_clear_pixels(TB_PKMN, 0);
168
+    u32 twidth = font_get_width_of_string(FONT_DEX_STD, &pokemon_names[species][0], 0x0000);
169
+    rboxid_print(TB_PKMN, FONT_DEX_STD, TB_STD_CENTER(twidth), 3, &pdex_text_color, 0, &pokemon_names[species][0]);
170
+    if (pokedex_context->pokemon_oam != -1) {
171
+        obj_delete_and_free(&objects[pokedex_context->pokemon_oam]);
172
+    }
173
+    struct SpriteTiles pkmnTiles = {pokemon_graphics_front[species].data, 2048, DEX_PKMN_TAG};
174
+    struct SpritePalette pkmnPal = {pokemon_palette_normal[species].data, DEX_PKMN_TAG};
175
+    const struct Template pkmnTemplate = {
176
+        .tiles_tag = DEX_PKMN_TAG,
177
+        .pal_tag = DEX_PKMN_TAG,
178
+        .oam = &pdex_oam_pkmn,
179
+        .animation = &anim_image_empty,
180
+        .graphics = &pkmnTiles,
181
+        .rotscale = &rotscale_empty,
182
+        .callback = oac_nullsub,
183
+    };
184
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pkmnTiles);
185
+
186
+    gpu_pal_decompress_alloc_tag_and_upload(&pkmnPal);
187
+    pokedex_context->pokemon_oam = (s8)template_instanciate_forward_search(&pkmnTemplate, 10, 10, 0);
188
+
189
+    objects[pokedex_context->pokemon_oam].pos1.x = 55;
190
+    objects[pokedex_context->pokemon_oam].pos1.y = 80;
191
+
192
+    rboxid_update_tilemap_and_tileset(TB_PKMN);
193
+}
194
+
195
+struct SpriteTiles pdex_ball_tiles = {pdexBallTiles, 128, DEX_BALL_TAG};
196
+struct SpritePalette pdex_ball_pal = {pdexBallPal, DEX_BALL_TAG};
197
+const struct OamData pdex_ball_oam = {
198
+    .affine_mode = 0,
199
+    .obj_mode = 0,
200
+    .mosaic = false,
201
+    .shape = 0,
202
+    .size = 1,
203
+};
204
+
205
+const struct Template pdex_ball_template = {
206
+    .tiles_tag = DEX_BALL_TAG,
207
+    .pal_tag = DEX_BALL_TAG,
208
+    .oam = &pdex_ball_oam,
209
+    .animation = &anim_image_empty,
210
+    .graphics = &pdex_ball_tiles,
211
+    .rotscale = &rotscale_empty,
212
+    .callback = oac_nullsub,
213
+};
214
+
215
+void pdex_pokeballs_init(void) {
216
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pdex_ball_tiles);
217
+    gpu_pal_obj_alloc_tag_and_apply(&pdex_ball_pal);
218
+    for (u8 i = 0; i < 9; ++i) {
219
+        pokedex_context->ball_oams[i] =
220
+            template_instanciate_forward_search(&pdex_ball_template, 124, 24 + pdex_y_offset[i], 0);
221
+        OBJID_HIDE(pokedex_context->ball_oams[i]);
222
+    }
223
+}
224
+
225
+void pdex_oac_cursor_follow(struct Object *obj) { obj->pos1.y = objects[pokedex_context->cursor_main_oam].pos1.y; }
226
+
227
+void pdex_oac_cursor_main(struct Object *obj) {
228
+    obj->pos1.y = 29 + pdex_y_offset[pokedex_context->cursor_position_internal];
229
+}
230
+
231
+struct SpriteTiles pdex_cursor_tiles = {pdexSelectHalfTiles, 1024, DEX_CURSOR_TAG};
232
+struct SpritePalette pdex_cursor_pal = {pdexSelectHalfPal, DEX_CURSOR_TAG};
233
+const struct OamData pdex_cursor_oam = {
234
+    .affine_mode = 0,
235
+    .obj_mode = 0,
236
+    .mosaic = false,
237
+    .shape = 1,
238
+    .size = 3,
239
+};
240
+
241
+const struct Template pdex_ball_main_template = {
242
+    .tiles_tag = DEX_CURSOR_TAG,
243
+    .pal_tag = DEX_CURSOR_TAG,
244
+    .oam = &pdex_cursor_oam,
245
+    .animation = &anim_image_empty,
246
+    .graphics = &pdex_cursor_tiles,
247
+    .rotscale = &rotscale_empty,
248
+    .callback = pdex_oac_cursor_main,
249
+};
250
+
251
+const struct Template pdex_ball_follow_template = {
252
+    .tiles_tag = DEX_CURSOR_TAG,
253
+    .pal_tag = DEX_CURSOR_TAG,
254
+    .oam = &pdex_cursor_oam,
255
+    .animation = &anim_image_empty,
256
+    .graphics = &pdex_cursor_tiles,
257
+    .rotscale = &rotscale_empty,
258
+    .callback = pdex_oac_cursor_follow,
259
+};
260
+
261
+void pdex_cursor_init(void) {
262
+    gpu_tile_obj_decompress_alloc_tag_and_upload(&pdex_cursor_tiles);
263
+    gpu_pal_obj_alloc_tag_and_apply(&pdex_cursor_pal);
264
+    pokedex_context->cursor_main_oam = template_instanciate_forward_search(&pdex_ball_main_template, 144, 32, 0);
265
+    pokedex_context->cursor_follow_oam =
266
+        template_instanciate_forward_search(&pdex_ball_follow_template, 144 + 48, 32, 0);
267
+    objects[pokedex_context->cursor_follow_oam].final_oam.h_flip = true;
268
+}
269
+
270
+void pdex_loop(u8 tid) {
271
+    (void)tid;
272
+    switch (pokedex_context->state) {
273
+    case 0:
274
+        pokedex_context->state++;
275
+        break;
276
+    case 1:
277
+        for (u8 i = 0; i < 4; ++i)
278
+            bgid_send_tilemap(i);
279
+        rboxid_clear_pixels(TB_TITLE, 0);
280
+        rboxid_print(TB_TITLE, FONT_DEX_STD, 0, 0, &pdex_text_color, 0, &pdex_str_title[0]);
281
+        rboxid_update_tilemap_and_tileset(TB_TITLE);
282
+
283
+        pdex_pokemon_load(0);
284
+        pdex_load_sc();
285
+        pdex_init_dex_boxes();
286
+        pdex_pokeballs_init();
287
+        pdex_cursor_init();
288
+        palette_bg_faded_fill_black();
289
+        pokedex_context->state++;
290
+        break;
291
+    case 2:
292
+        gpu_sync_bg_show(0);
293
+        gpu_sync_bg_hide(1);
294
+        gpu_sync_bg_hide(3);
295
+
296
+        gpu_sync_bg_show(2);
297
+        if (pokedex_context->delay_count >= 5) {
298
+            fade_screen(0xFFFFFFFF, PDEX_FADEIN_SPD, 16, 0, 0x0000);
299
+            pokedex_context->state++;
300
+            pokedex_context->delay_count = 0;
301
+        } else {
302
+            pokedex_context->delay_count++;
303
+        }
304
+
305
+        break;
306
+    case 3:
307
+        if ((super.buttons_new & KEY_DOWN)) {
308
+            if (pokedex_context->cursor_position_internal < 8) {
309
+                pokedex_context->cursor_position_internal++;
310
+            }
311
+        } else if ((super.buttons_new & KEY_UP)) {
312
+            if (pokedex_context->cursor_position_internal > 0)
313
+                pokedex_context->cursor_position_internal--;
314
+        }
315
+        break;
316
+    default:
317
+        break;
318
+    }
319
+}
320
+
321
+bool sm_pdex_init(void) {
322
+    if (pal_fade_control.active)
323
+        return false;
324
+    audioDampenMaybe();
325
+    sav1_secure_increment(0x29); // this is something the original dex routine does, probably for statistics
326
+    /* maybe clean up safari stuff here if necessary */
327
+    overworld_free_bgmaps();
328
+    set_callback2(pdex_load);
329
+    return true;
330
+}
331
+
332
+void pdex_vram_setup(void) {
333
+    vblank_handler_set(NULL);
334
+    pal_fade_control_and_dead_struct_reset();
335
+    obj_and_aux_reset_all();
336
+    gpu_tile_obj_tags_reset();
337
+    rboxes_free();
338
+    tasks_init();
339
+    gpu_tile_bg_drop_all_sets(true);
340
+
341
+    bg_vram_setup(0, &pdex_bg_config[0], 4);
342
+
343
+    u8 *bgMap = malloc(0x800);
344
+    u8 *strMap = malloc(0x800);
345
+    bgid_set_tilemap(2, bgMap);
346
+    bgid_set_tilemap(0, strMap);
347
+    bgid_mark_for_sync(0);
348
+
349
+    /*TODO: setup text boxes here */
350
+    rbox_init_from_templates(&pdex_boxes[0]);
351
+    u32 set = 0;
352
+    CpuFastSet((void *)&set, (void *)0x06000000, CPUModeFS(0x10000, CPUFSSET));
353
+
354
+    lz77UnCompVram(pdexBgTiles, (void *)0x0600C000);
355
+    LZ77UnCompWram(pdexBgMap, bgMap);
356
+    gpu_pal_apply_compressed(pdexBgPal, 0, 32);
357
+    gpu_pal_apply(pdex_text_pal, 15 * 16, 32);
358
+
359
+    vblank_handler_set(pdex_vblank_handler);
360
+    interrupts_enable(INTERRUPT_VBLANK);
361
+    bgid_mod_x_offset(0, 0, 0);
362
+    bgid_mod_y_offset(0, 0, 0);
363
+    bgid_mod_x_offset(1, 0, 0);
364
+    bgid_mod_y_offset(1, 0, 0);
365
+    bgid_mod_x_offset(2, 0, 0);
366
+    bgid_mod_y_offset(2, 0, 0);
367
+    bgid_mod_x_offset(3, 0, 0);
368
+    bgid_mod_y_offset(3, 0, 0);
369
+}
370
+
371
+void pdex_load(void) {
372
+    pdex_vram_setup();
373
+    pokedex_context = malloc(sizeof(struct PdexCtx));
374
+    pokedex_context->state = 0;
375
+    pokedex_context->pokemon_oam = -1;
376
+    pokedex_context->delay_count = 0;
377
+    task_add(pdex_loop, 0);
378
+    set_callback2(pdex_cb_handler);
379
+}
380
+
381
+void pdex_vblank_handler(void) {
382
+    gpu_sprites_upload();
383
+    copy_queue_process();
384
+    gpu_pal_upload();
385
+}
386
+
387
+void pdex_cb_handler(void) {
388
+    if (pal_fade_control.active)
389
+        process_palfade();
390
+    else {
391
+        task_exec();
392
+        objc_exec();
393
+        obj_sync_superstate();
394
+        tilemaps_sync();
395
+        remoboxes_upload_tilesets();
396
+    }
397
+}

+ 22
- 0
src/pokedex/pokedex_string.s Ver fichero

@@ -0,0 +1,22 @@
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_empty
20
+pdex_str_empty:
21
+    .string LAN_DE "----------"
22
+    .string LAN_EN "----------"

+ 1
- 1
src/specials/trainer_battle.c Ver fichero

@@ -60,7 +60,7 @@ char *str_invalid_text_ref;
60 60
  * @param ptr pointer to load byte from
61 61
  * @return byte loaded
62 62
  */
63
-u8 load_byte(void *ptr) {
63
+inline u8 load_byte(void *ptr) {
64 64
     u8 *to_load = (u8 *)ptr;
65 65
     return (u8)(*to_load);
66 66
 }