No Description

dynamic_overworld.c 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include <pokeagb/pokeagb.h>
  2. #define MAX_PAL_STORE 16
  3. #define STRANGE_NPC_MAX 4
  4. struct PalStoreEntry {
  5. u8 reference_count;
  6. u16 tag;
  7. };
  8. struct StrangeNpcStruct {
  9. u8 field0;
  10. u8 field1;
  11. u8 field2;
  12. u8 field3;
  13. };
  14. extern struct PalStoreEntry stored_palettes[16];
  15. extern struct NpcType *npc_get_type(u16 id);
  16. extern void dprintf(const char *str, ...);
  17. extern struct StrangeNpcStruct strange_npc_table[4];
  18. s8 npc_dynamic_find_palette(u16 tag) {
  19. for (s8 i = 0; i < MAX_PAL_STORE; ++i) {
  20. if (stored_palettes[i].reference_count > 0 && stored_palettes[i].tag == tag)
  21. return i;
  22. }
  23. return -1;
  24. }
  25. s8 npc_dynamic_allocate_palette(u16 tag) {
  26. for (s8 i = 0; i < MAX_PAL_STORE; ++i) {
  27. if (stored_palettes[i].reference_count == 0) {
  28. stored_palettes[i].tag = tag;
  29. stored_palettes[i].reference_count++;
  30. return i;
  31. }
  32. }
  33. return -1;
  34. }
  35. u8 npc_dynamic_load_palette(u16 tag) {
  36. s8 store_entry = npc_dynamic_find_palette(tag);
  37. if (store_entry != -1) {
  38. stored_palettes[store_entry].reference_count++;
  39. return store_entry;
  40. }
  41. store_entry = npc_dynamic_allocate_palette(tag);
  42. if (store_entry == -1) {
  43. /* we do not have allocation space left */
  44. dprintf("npc_dynamic: ATTENTION - TRIED TO ALLOCATE DYNOVER PALETTE WITHOUT SPACE LEFT, INCREASING ZERO "
  45. "REFERENCE\n");
  46. stored_palettes[0].reference_count++;
  47. return 0;
  48. }
  49. pal_patch_for_npc(tag, (u8)store_entry);
  50. return (u8)store_entry;
  51. }
  52. void ov_emot_load(struct Object *obj, u16 a2, u8 a3) {
  53. (void)npc_dynamic_load_palette(0x1100);
  54. obj->final_oam.priority = 2;
  55. obj->bitfield2 |= 2;
  56. obj->priv[0] = oe_state.effect_pos.x;
  57. obj->priv[1] = oe_state.effect_pos.y;
  58. obj->priv[2] = oe_state.priority;
  59. obj->priv[3] = -5;
  60. obj->priv[7] = a2;
  61. obj_anim_image_start(obj, a3);
  62. }
  63. void npc_dynamic_reset() {
  64. for (u8 i = 0; i < MAX_PAL_STORE; ++i) {
  65. stored_palettes[i].reference_count = 0;
  66. stored_palettes[i].tag = 0;
  67. }
  68. }
  69. void npc_dynamic_remove_entry(u8 id, u16 tag) {
  70. if (stored_palettes[id].tag == tag) {
  71. if (stored_palettes[id].reference_count > 0) {
  72. stored_palettes[id].reference_count--;
  73. dprintf("npc_dynamic: removed entry #%d\n", id);
  74. if (stored_palettes[id].reference_count == 0)
  75. stored_palettes[id].tag = 0;
  76. }
  77. }
  78. }
  79. void npc_restore_state(u8 id, u16 x, u16 y) {
  80. for (u8 i = 0; i < STRANGE_NPC_MAX; ++i) {
  81. if (strange_npc_table[i].field0 != 0) {
  82. if (strange_npc_table[i].field2 == id)
  83. return;
  84. }
  85. }
  86. struct NpcState *npc_to_load = &npc_states[id];
  87. u16 type_id = ((u16)npc_to_load->type_id) | (((u16)npc_to_load->field1A << 8));
  88. struct NpcType *type_to_load = npc_get_type(type_id);
  89. struct Template template_to_load;
  90. u32 f14;
  91. npc_to_objtemplate__with_indexed_objfunc(type_id, npc_to_load->running_behavior, &template_to_load,
  92. &f14);
  93. template_to_load.pal_tag = 0xFFFF;
  94. s8 pal_slot = npc_dynamic_load_palette(type_to_load->pal_num);
  95. /*template_to_load.pal_tag = type_to_load->pal_num;
  96. gpu_pal_obj_alloc_tag_and_apply(&npc_palettes[npc_pal_idx_for_given_tag(type_to_load->pal_num)]);
  97. u8 pal_slot = gpu_pal_tags_index_of(type_to_load->pal_num);*/
  98. u8 obj_id = template_instanciate_forward_search(&template_to_load, 0, 0, 0);
  99. if (obj_id == 64)
  100. return;
  101. struct Object *npc_obj = &objects[obj_id];
  102. npc_fix_position(x + npc_to_load->to.x, y + npc_to_load->to.y, &npc_obj->pos1.x, &npc_obj->pos1.y);
  103. npc_obj->shift.x = -(type_to_load->pos_neg_center.x / 2);
  104. npc_obj->shift.y = -(type_to_load->pos_neg_center.y / 2);
  105. npc_obj->pos1.x += 8;
  106. npc_obj->pos1.y += (s8)npc_obj->shift.y + 16;
  107. npc_obj->gfx_table = type_to_load->gfx_table;
  108. if (npc_to_load->running_behavior == 11) {
  109. walkrun_init_something(id, obj_id);
  110. npc_to_load->oamid2 = arrow_init_something();
  111. }
  112. if (f14 != 0) {
  113. (void)obj_set_f18_to_r0_f42_to_40(npc_obj, f14);
  114. }
  115. npc_obj->final_oam.palette_num = pal_slot;
  116. npc_obj->bitfield2 |= 2;
  117. npc_obj->priv[0] = id;
  118. npc_to_load->oam_id = obj_id;
  119. if (!(npc_to_load->field1 & 0x10) && (npc_to_load->running_behavior != 11)) {
  120. obj_anim_image_start(npc_obj, npc_direction_to_obj_anim_image_number(npc_to_load->direction & 0xF));
  121. }
  122. npc_805EFF4(npc_to_load);
  123. npc_y_height_related(npc_to_load->height >> 4, npc_obj, 1);
  124. }
  125. u8 npc_spawn_with_provided_template(struct RomNpc *npc, struct Template *template, u8 map, u8 bank, s16 x, s16 y) {
  126. u8 state = rom_npc_to_npc_state(npc, map, bank);
  127. if (state >= 16)
  128. return 16;
  129. struct NpcState *created_state = &npc_states[state];
  130. struct NpcType *type = npc_get_type(created_state->type_id | (npc->field3 << 8));
  131. s8 pal_slot = npc_dynamic_load_palette(type->pal_num);
  132. // gpu_pal_obj_alloc_tag_and_apply(&npc_palettes[npc_pal_idx_for_given_tag(type->pal_num)]);
  133. // u8 pal_slot = gpu_pal_tags_index_of(type->pal_num);
  134. if (created_state->running_behavior == 76)
  135. created_state->field1 |= 0x20;
  136. template->pal_tag = 0xFFFF;
  137. // template->pal_tag = type->pal_num;
  138. u8 obj_id = template_instanciate_forward_search(template, 0, 0, 0);
  139. if (obj_id == 64) {
  140. created_state->bitfield &= 0xFE;
  141. return 16;
  142. }
  143. struct Object *npc_object = &objects[obj_id];
  144. npc_fix_position(x + created_state->to.x, y + created_state->to.y, &npc_object->pos1.x, &npc_object->pos1.y);
  145. npc_object->shift.x = -(type->pos_neg_center.x / 2);
  146. npc_object->shift.y = -(type->pos_neg_center.y / 2);
  147. npc_object->pos1.x += 8;
  148. npc_object->pos1.y += (s8)npc_object->shift.y + 16;
  149. /* Set our allocated index */
  150. npc_object->final_oam.palette_num = pal_slot;
  151. npc_object->bitfield2 |= 2;
  152. npc_object->priv[0] = state;
  153. created_state->oam_id = obj_id;
  154. u8 unknown = (created_state->field1 & 0xEF) | (16 * (type->pal_slot_unk << 25 >> 31));
  155. created_state->field1 = unknown;
  156. if (!(unknown & 0x10)) {
  157. obj_anim_image_start(npc_object, npc_direction_to_obj_anim_image_number(created_state->direction & 0xF));
  158. }
  159. npc_y_height_related(created_state->height >> 4, npc_object, 1);
  160. npc_obj_offscreen_culling_and_flag_update(created_state, npc_object);
  161. return state;
  162. }
  163. void oec01_load_pal_impl(u32 *oe_script) {
  164. struct SpritePalette *pal = (struct SpritePalette *)oe_read_word(oe_script);
  165. s8 allocated = npc_dynamic_find_palette(pal->tag);
  166. if (allocated == -1)
  167. allocated = npc_dynamic_allocate_palette(pal->tag);
  168. if (allocated > 0) {
  169. gpu_pal_apply(pal->data, 256 + (16 * allocated), 32);
  170. tint_palette_switch(allocated);
  171. palette_obj_807AA8C(allocated);
  172. } else {
  173. dprintf("ERROR: RAN OUT OF PALETTES FOR DYNAMIC SYSTEM\n");
  174. }
  175. *oe_script += 4;
  176. }
  177. void oec02_load_pal_impl(u32 *oe_script) {
  178. struct SpritePalette *pal = (struct SpritePalette *)oe_read_word(oe_script);
  179. s8 allocated = npc_dynamic_find_palette(pal->tag);
  180. if (allocated == -1)
  181. allocated = npc_dynamic_allocate_palette(pal->tag);
  182. if (allocated > 0) {
  183. gpu_pal_apply(pal->data, 256 + (16 * allocated), 32);
  184. tint_palette_switch(allocated);
  185. } else {
  186. dprintf("ERROR: RAN OUT OF PALETTES FOR DYNAMIC SYSTEM\n");
  187. }
  188. *oe_script += 4;
  189. }