Browse Source

dynamic npc palettes when returning from menu screens

SBird1337 7 years ago
parent
commit
7ef6128393
4 changed files with 77 additions and 2 deletions
  1. 1
    0
      bpre.sym
  2. 1
    1
      g3headers
  3. 13
    0
      patches/dynamic_overworld_hooks.asm
  4. 62
    1
      src/overworld/dynamic_overworld.c

+ 1
- 0
bpre.sym View File

@@ -84,6 +84,7 @@ battle_script_push = 0x08017544|1;
84 84
 objects = 0x0202063C;
85 85
 
86 86
 stored_palettes = 0x0203FF00;
87
+strange_npc_table = 0x02031DEC;
87 88
 
88 89
 fade_screen = 0x08070589;
89 90
 fade_update = 0x080704D1;

+ 1
- 1
g3headers

@@ -1 +1 @@
1
-Subproject commit f7f112b0d286765a4396669278cb0595a7a69ff5
1
+Subproject commit c4659d3ab4f6062818f1e776746d7be46582f992

+ 13
- 0
patches/dynamic_overworld_hooks.asm View File

@@ -265,4 +265,17 @@ bx r1
265 265
 ldr r1, =obj_delete_all_hook|1
266 266
 bx r1
267 267
 
268
+.pool
269
+
270
+.org 0x0805EE3C
271
+push {r4, lr}
272
+ldr r4, =npc_restore_state|1
273
+bl bxr4
274
+pop {r4}
275
+pop {r0}
276
+bx r0
277
+
278
+bxr4:
279
+bx r4
280
+
268 281
 .pool

+ 62
- 1
src/overworld/dynamic_overworld.c View File

@@ -1,18 +1,28 @@
1 1
 #include <pokeagb/pokeagb.h>
2 2
 
3 3
 #define MAX_PAL_STORE 16
4
+#define STRANGE_NPC_MAX 4
4 5
 
5 6
 struct PalStoreEntry {
6 7
     u8 reference_count;
7 8
     u16 tag;
8 9
 };
9 10
 
11
+struct StrangeNpcStruct {
12
+    u8 field0;
13
+    u8 field1;
14
+    u8 field2;
15
+    u8 field3;
16
+};
17
+
10 18
 extern struct PalStoreEntry stored_palettes[16];
11 19
 
12 20
 extern struct NpcType *npc_get_type(u16 id);
13 21
 
14 22
 extern void dprintf(const char *str, ...);
15 23
 
24
+extern struct StrangeNpcStruct strange_npc_table[4];
25
+
16 26
 s8 npc_dynamic_find_palette(u16 tag) {
17 27
     for (s8 i = 0; i < MAX_PAL_STORE; ++i) {
18 28
         if (stored_palettes[i].reference_count > 0 && stored_palettes[i].tag == tag)
@@ -41,7 +51,8 @@ u8 npc_dynamic_load_palette(u16 tag) {
41 51
     store_entry = npc_dynamic_allocate_palette(tag);
42 52
     if (store_entry == -1) {
43 53
         /* we do not have allocation space left */
44
-        dprintf("npc_dynamic: ATTENTION - TRIED TO ALLOCATE DYNOVER PALETTE WITHOUT SPACE LEFT, INCREASING ZERO REFERENCE\n");
54
+        dprintf("npc_dynamic: ATTENTION - TRIED TO ALLOCATE DYNOVER PALETTE WITHOUT SPACE LEFT, INCREASING ZERO "
55
+                "REFERENCE\n");
45 56
         stored_palettes[0].reference_count++;
46 57
         return 0;
47 58
     }
@@ -67,6 +78,56 @@ void npc_dynamic_remove_entry(u8 id) {
67 78
     }
68 79
 }
69 80
 
81
+void npc_restore_state(u8 id, u16 x, u16 y) {
82
+    for (u8 i = 0; i < STRANGE_NPC_MAX; ++i) {
83
+        if (strange_npc_table[i].field0 != 0) {
84
+            if (strange_npc_table[i].field2 == id)
85
+                return;
86
+        }
87
+    }
88
+
89
+    struct NpcState *npc_to_load = &npc_states[id];
90
+    struct NpcType *type_to_load = npc_get_type(((u16)npc_to_load->type_id) | (((u16)npc_to_load->field1A << 8)));
91
+
92
+    struct Template template_to_load;
93
+    u32 f14;
94
+    npc_to_objtemplate__with_indexed_objfunc(npc_to_load->type_id, npc_to_load->running_behavior, &template_to_load,
95
+                                             &f14);
96
+    template_to_load.pal_tag = 0xFFFF;
97
+    s8 pal_slot = npc_dynamic_load_palette(type_to_load->pal_num);
98
+    u8 obj_id = template_instanciate_forward_search(&template_to_load, 0, 0, 0);
99
+
100
+    if (obj_id == 64)
101
+        return;
102
+
103
+    struct Object *npc_obj = &objects[obj_id];
104
+    npc_fix_position(x + npc_to_load->to.x, y + npc_to_load->to.y, &npc_obj->pos1.x, &npc_obj->pos1.y);
105
+    npc_obj->shift.x = -(type_to_load->pos_neg_center.x / 2);
106
+    npc_obj->shift.y = -(type_to_load->pos_neg_center.y / 2);
107
+    npc_obj->pos1.x += 8;
108
+    npc_obj->pos1.y += (s8)npc_obj->shift.y + 16;
109
+    npc_obj->gfx_table = type_to_load->gfx_table;
110
+    if (npc_to_load->running_behavior == 11) {
111
+        walkrun_init_something(id, obj_id);
112
+        npc_to_load->oamid2 = arrow_init_something();
113
+    }
114
+
115
+    if (f14 != 0) {
116
+        (void) obj_set_f18_to_r0_f42_to_40(npc_obj, f14);
117
+    }
118
+
119
+    npc_obj->final_oam.palette_num = pal_slot;
120
+    npc_obj->bitfield2 |= 2;
121
+    npc_obj->priv[0] = id;
122
+    npc_to_load->oam_id = obj_id;
123
+    if (!(npc_to_load->field1 & 0x10) && (npc_to_load->running_behavior != 11)) {
124
+        obj_anim_image_start(npc_obj, npc_direction_to_obj_anim_image_number(npc_to_load->direction & 0xF));
125
+    }
126
+
127
+    npc_805EFF4(npc_to_load);
128
+    npc_y_height_related(npc_to_load->height >> 4, npc_obj, 1);
129
+}
130
+
70 131
 u8 npc_spawn_with_provided_template(struct RomNpc *npc, struct Template *template, u8 map, u8 bank, s16 x, s16 y) {
71 132
     u8 state = rom_npc_to_npc_state(npc, map, bank);
72 133
     if (state >= 16)