Нема описа

dns_core.c.old 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /****************************************************************************
  2. * Copyright (C) 2015-2016 by the SotS Team *
  3. * *
  4. * This file is part of Sovereign of the Skies. *
  5. * *
  6. * Sovereign of the Skies is free software: you can redistribute it *
  7. * and/or modify it *
  8. * under the terms of the GNU Lesser General Public License as published *
  9. * by the Free Software Foundation, either version 3 of the License, or *
  10. * (at your option) any later version provided you include a copy of the *
  11. * licence and this header. *
  12. * *
  13. * Sovereign of the Skies is distributed in the hope that it will be *
  14. * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU Lesser General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU Lesser General Public *
  19. * License along with Sovereign of the Skies. *
  20. * If not, see <http://www.gnu.org/licenses/>. *
  21. ****************************************************************************/
  22. /**
  23. * @file dns_core.c
  24. * @author Sturmvogel
  25. * @date 15 dec 2016
  26. * @brief interact with the dns system
  27. *
  28. */
  29. /* === INCLUDE === */
  30. #include <dns_core.h>
  31. #include <memory.h>
  32. #include <lcd.h>
  33. #include <callback.h>
  34. /* === PROTOTYPES === */
  35. /**
  36. * @brief hacked overworld callback to update palettes
  37. */
  38. void dns_cb_overworld_hacked();
  39. /**
  40. * @brief get current time of day type
  41. * @return enum containing respective day type
  42. */
  43. enum dns_rtc_time_type dns_get_time_of_day();
  44. /**
  45. * @brief load virtual pal of npc
  46. * @param dst destination to load to
  47. * @param tag tag to load
  48. * @param slot slot to load
  49. * @param shade shade immediatly if true
  50. */
  51. void dns_npc_load_virtual_pal(struct color* dst, u16 tag, u8 slot, u8 shade);
  52. /**
  53. * @brief allocate a virtual pal and load it
  54. * @return pointer to allocated color array
  55. */
  56. struct color* dns_alloc_virtual_pal_and_load();
  57. /**
  58. * @brief update palettes
  59. */
  60. void dns_update_palettes();
  61. /**
  62. * @brief load pal of overworld animation i.e. grass
  63. * @param oe_script_pointer pointer to oe_script controlling the animation
  64. */
  65. void dns_overworld_anim_load_pal(void** oe_script_pointer);
  66. /**
  67. * @brief load blockset to virtual space
  68. * @param blockset pointer to blockset to load
  69. * @param start start range
  70. * @param len end range
  71. * @param destination virtual destination to load to
  72. */
  73. void dns_blockset_load_virtual_palette_and_shade(struct blockset* blockset, u16 start, u16 len, struct color* destination);
  74. /**
  75. * @brief load blockset into palram and shade it
  76. * @param blockset pointer to blockset to load
  77. * @param start start range
  78. * @param len end range
  79. */
  80. void dns_blockset_load_palette_to_gpu_and_shade(struct blockset* blockset, u16 start, u16 len);
  81. /**
  82. * @brief load second pal of mapheader given
  83. * @param data_header pointer to mapdata header
  84. */
  85. void dns_mapdata_load_palette_two(struct mapdata_header* data_header);
  86. /**
  87. * @brief load second pal of mapheader given
  88. * @param data_header pointer to mapdata header
  89. */
  90. void dns_mapdata_load_palette_one(struct mapdata_header* data_header);
  91. /**
  92. * @brief apply light effects to given color array
  93. * @param blockset pointer to blockset
  94. * @param secondary is the blockset a secondary blockset
  95. * @param buffer color buffer to apply lighting to
  96. */
  97. void dns_apply_lighting(void* blockset, u8 secondary, struct color* buffer);
  98. /**
  99. * @brief apply shaders to color buffer
  100. * @param pal pal to apply shader to
  101. * @param fade_copy copy to unfaded immediatly if true
  102. * @param buffer color buffer
  103. */
  104. void dns_apply_shaders(u8 pal, u8 fade_copy, struct color* buffer);
  105. /**
  106. * @brief copy slot to faded buffer
  107. * @param slot palette slot
  108. */
  109. void dns_copy_unfaded(u8 slot);
  110. /**
  111. * @brief should the map allow shading?
  112. * @param current_type maptype to check for
  113. * @return
  114. */
  115. u8 dns_should_shade(enum map_type current_type);
  116. /**
  117. * @brief get color shade struct from time of day
  118. * @param current_time current time of day
  119. * @return color_shade struct with respective information
  120. */
  121. struct color_shade dns_get_shade_from_time(enum dns_rtc_time_type current_time);
  122. /**
  123. * @brief blend color a over color b
  124. * @param a first color
  125. * @param b second color
  126. * @param alpha alpha value
  127. * @return blended color
  128. */
  129. struct color dns_alpha_blend(struct color a, struct color b, u8 alpha);
  130. /**
  131. * @brief patch hack for npc and pal slot
  132. * @param tag tag to apply hack to
  133. * @param pal_slot pal slot to apply hack to
  134. */
  135. void dns_pal_patch_for_npc(u16 tag, u8 pal_slot);
  136. /* === STATICS === */
  137. static struct pal_replace lightmap[] = {
  138. {(void*) 0x082D4AAC, 9, 10, {
  139. 31, 31, 0
  140. }}
  141. ,
  142. {(void*) 0x082D4AAC, 9, 9, {
  143. 31, 31, 0
  144. }}
  145. ,
  146. {(void*) 0x082D4AAC, 9, 8, {
  147. 31, 31, 0
  148. }}
  149. };
  150. static struct color_shade color_shade_day = {
  151. {0, 0, 0}, 255
  152. };
  153. static struct color_shade color_shade_night = {
  154. {0, 6, 16}, 120
  155. };
  156. static struct color_shade color_shade_evening = {
  157. {12, 7, 17}, 120
  158. };
  159. static struct color_shade color_shade_morning = {
  160. {6, 16, 6}, 150
  161. };
  162. /* === IMPLEMENTATIONS === */
  163. void dns_cb_overworld_hacked() {
  164. script_something();
  165. task_exec();
  166. objc_exec();
  167. camera_update();
  168. foo_115798();
  169. foo_5ae28();
  170. obj_sync();
  171. fade_update();
  172. foo_6ffbc();
  173. tilemaps_sync();
  174. volatile u8* test_pointer = (u8*) (0x0203FAB0);
  175. if (*test_pointer == 1 && (fade_controller.mix_color & 0x8000) == 0) {
  176. dns_update_palettes();
  177. *test_pointer = 0;
  178. }
  179. }
  180. enum dns_rtc_time_type dns_get_time_of_day() {
  181. volatile u8* time_pointer = (u8*) (0x0203FAB1);
  182. return *time_pointer;
  183. }
  184. void dns_npc_load_virtual_pal(struct color* dst, u16 tag, u8 slot, u8 shade) {
  185. u16 npc_map_entry = npc_pal_idx_for_given_tag(tag);
  186. memcpy(dst + (16 + slot)*16, npc_palettes[npc_map_entry].palette, 32);
  187. if (shade) {
  188. tint_palette(slot);
  189. dns_apply_shaders(slot + 16, 0, dst);
  190. }
  191. }
  192. struct color* dns_alloc_virtual_pal_and_load() {
  193. struct color* destination = malloc(0x400);
  194. dns_blockset_load_virtual_palette_and_shade(current_mapheader.data_header->blockset_one, 0x0, 0xE0, destination);
  195. dns_blockset_load_virtual_palette_and_shade(current_mapheader.data_header->blockset_two, 0x70, 0xC0, destination);
  196. dns_npc_load_virtual_pal(destination, 0x1120, 0, false);
  197. load_palette_3(0x0, 0xD0);
  198. for (int i = 0; i < 16; ++i) {
  199. if (dynamic_palettes[i].tag >= 0x1100) {
  200. dns_npc_load_virtual_pal(destination, dynamic_palettes[i].tag, i, true);
  201. } else if (dynamic_palettes[i].tag == 0x1004) {
  202. //oe_0001
  203. struct color* oe_pal_1 = (struct color*) (0x08398FA8);
  204. memcpy(destination + (16 + i) * 16, oe_pal_1, 32);
  205. dns_apply_shaders(16 + i, 0, destination);
  206. } else if (dynamic_palettes[i].tag == 0x1005) {
  207. //oe_0002
  208. struct color* oe_pal_2 = (struct color*) (0x08398FC8);
  209. memcpy(destination + (16 + i) * 16, oe_pal_2, 32);
  210. dns_apply_shaders(16 + 1, 0, destination);
  211. }
  212. }
  213. return destination;
  214. }
  215. void dns_update_palettes() {
  216. struct color* destination = dns_alloc_virtual_pal_and_load();
  217. gpu_pal_apply(destination, 0x0, 0x1A0);
  218. gpu_pal_apply(destination + 0x100, 0x100, 0x200);
  219. free(destination);
  220. }
  221. void dns_overworld_anim_load_pal(void** oe_script_pointer) {
  222. struct npc_palette* pal_to_apply = oe_read_word(oe_script_pointer);
  223. u16 current_idx = gpu_pal_tags_index_of(pal_to_apply->tag);
  224. struct color* temp_color = malloc(32);
  225. memcpy(temp_color, pal_to_apply->palette, 32);
  226. dns_apply_shaders(0, 0, temp_color);
  227. struct obj_resource temp_resource = {temp_color, pal_to_apply->tag, pal_to_apply->fill};
  228. obj_gpu_pal_alloc_tag_and_apply(&temp_resource);
  229. free(temp_color);
  230. if (current_idx != 0xFF) {
  231. current_idx = gpu_pal_tags_index_of(pal_to_apply->tag);
  232. tint_palette(current_idx);
  233. }
  234. current_idx = gpu_pal_tags_index_of(pal_to_apply->tag);
  235. some_weather_func(current_idx);
  236. *oe_script_pointer += 4;
  237. return;
  238. }
  239. void dns_blockset_load_virtual_palette_and_shade(struct blockset* blockset, u16 start, u16 len, struct color* destination) {
  240. if (blockset == 0)
  241. return;
  242. if (blockset->is_secondary) {
  243. if (blockset->is_secondary == 1) {
  244. memcpy(destination + start, blockset->palette + (start * 2), len);
  245. for (u8 i = 7; i < 7 + 6; ++i)
  246. dns_apply_shaders(i, 0, destination);
  247. dns_apply_lighting(blockset, 0, destination);
  248. //gpu_pal_apply((color_memory), start, len);
  249. //load_palette_3(start, len >> 1);
  250. } else {
  251. struct color* pal_buffer = (struct color*) (0x02037ACC);
  252. lz77u_wram(blockset->palette, pal_buffer);
  253. memcpy(destination + start, pal_buffer + (start * 2), len);
  254. for (u8 i = 7; i < 7 + 6; ++i)
  255. dns_apply_shaders(i, 0, destination);
  256. dns_apply_lighting(blockset, 0, destination);
  257. //gpu_pal_apply(pal_buffer, start, len);
  258. //load_palette_3(start, len >> 1);
  259. }
  260. } else {
  261. //struct color* color_memory = malloc(224);
  262. memcpy(destination, blockset->palette, len);
  263. for (u8 i = 0; i < 7; ++i)
  264. dns_apply_shaders(i, 0, destination);
  265. dns_apply_lighting(blockset, 0, destination);
  266. //gpu_pal_apply(color_memory, start, len);
  267. //load_palette_3(start, len >> 1);
  268. //free(color_memory);
  269. }
  270. return;
  271. }
  272. void dns_blockset_load_palette_to_gpu_and_shade(struct blockset* blockset, u16 start, u16 len) {
  273. if (blockset == 0)
  274. return;
  275. if (blockset->is_secondary) {
  276. if (blockset->is_secondary == 1) {
  277. struct color* color_memory = malloc(224);
  278. memcpy(color_memory, blockset->palette + 0xE0, 224);
  279. for (u8 i = 0; i < 7; ++i)
  280. dns_apply_shaders(i, 0, color_memory);
  281. dns_apply_lighting(blockset, 1, color_memory);
  282. gpu_pal_apply((color_memory), start, len);
  283. load_palette_3(start, len >> 1);
  284. free(color_memory);
  285. } else {
  286. struct color* pal_buffer = (struct color*) (0x02037ACC);
  287. lz77u_wram(blockset->palette, pal_buffer);
  288. for (u8 i = 7; i < 7 + 6; ++i)
  289. dns_apply_shaders(i, 0, pal_buffer);
  290. dns_apply_lighting(blockset, 0, pal_buffer);
  291. gpu_pal_apply(pal_buffer, start, len);
  292. load_palette_3(start, len >> 1);
  293. }
  294. } else {
  295. struct color* color_memory = malloc(224);
  296. memcpy(color_memory, blockset->palette, 224);
  297. for (u8 i = 0; i < 7; ++i)
  298. dns_apply_shaders(i, 0, color_memory);
  299. dns_apply_lighting(blockset, 0, color_memory);
  300. gpu_pal_apply(color_memory, start, len);
  301. load_palette_3(start, len >> 1);
  302. free(color_memory);
  303. }
  304. return;
  305. }
  306. void dns_mapdata_load_palette_two(struct mapdata_header* data_header) {
  307. //struct color* destination = malloc(0x200);
  308. //blockset_load_virtual_palette_and_shade(data_header->blockset_two, 0x70, 0xC0, destination);
  309. //gpu_pal_apply(destination, 0x70, 0xC0);
  310. //load_palette_3(0x70, 0xC0 >> 1);
  311. dns_blockset_load_palette_to_gpu_and_shade(data_header->blockset_two, 0x70, 0xC0);
  312. return;
  313. }
  314. void dns_mapdata_load_palette_one(struct mapdata_header* data_header) {
  315. //struct color* destination = malloc(0x200);
  316. //blockset_load_virtual_palette_and_shade(data_header->blockset_one, 0x0, 0xE0, destination);
  317. //gpu_pal_apply(destination, 0x0, 0xE0);
  318. //load_palette_3(0x0, 0xE0 >> 1);
  319. dns_blockset_load_palette_to_gpu_and_shade(data_header->blockset_one, 0x0, 0xE0);
  320. return;
  321. }
  322. void dns_apply_lighting(void* blockset, u8 secondary, struct color* buffer) {
  323. if (dns_get_time_of_day() != NIGHT)
  324. return;
  325. for (unsigned int i = 0; i < (sizeof (lightmap) / sizeof (lightmap[0])); ++i) {
  326. if (blockset == lightmap[i].blockset) {
  327. buffer[(lightmap[i].pal - (secondary ? 7 : 0)) * 16 + lightmap[i].index] = lightmap[i].color;
  328. }
  329. }
  330. return;
  331. }
  332. void dns_apply_shaders(u8 pal, u8 fade_copy, struct color* buffer) {
  333. if (tint_filter != 0)
  334. return;
  335. if (!dns_should_shade(current_mapheader.maptype))
  336. return;
  337. for (int i = pal * 16; i < (pal * 16) + 16; ++i) {
  338. struct color_shade current_shade = dns_get_shade_from_time(dns_get_time_of_day());
  339. buffer[i] = dns_alpha_blend(buffer[i], current_shade.color, current_shade.alpha);
  340. }
  341. if (fade_copy)
  342. dns_copy_unfaded(pal);
  343. }
  344. void dns_copy_unfaded(u8 slot) {
  345. for (int i = slot * 16; i < (slot * 16) + 16; ++i) {
  346. palette_faded_buffer[i] = palette_unfaded_buffer[i];
  347. }
  348. }
  349. u8 dns_should_shade(enum map_type current_type) {
  350. switch (current_type) {
  351. case VILLAGE:
  352. case CITY:
  353. case ROUTE:
  354. return 1;
  355. default:
  356. return 0;
  357. }
  358. return 0;
  359. }
  360. struct color_shade dns_get_shade_from_time(enum dns_rtc_time_type current_time) {
  361. switch (current_time) {
  362. case NIGHT:
  363. return color_shade_night;
  364. case EVENING:
  365. return color_shade_evening;
  366. case MORNING:
  367. return color_shade_morning;
  368. case DAY:
  369. default:
  370. return color_shade_day;
  371. }
  372. }
  373. struct color dns_alpha_blend(struct color a, struct color b, u8 alpha) {
  374. if (alpha == 255)
  375. return a;
  376. if (alpha == 0)
  377. return b;
  378. struct color output;
  379. u8 inverted_alpha = 255 - alpha;
  380. output.r = ((a.r * alpha + b.r * inverted_alpha) / 255);
  381. output.b = ((a.b * alpha + b.b * inverted_alpha) / 255);
  382. output.g = ((a.g * alpha + b.g * inverted_alpha) / 255);
  383. return output;
  384. }
  385. void dns_pal_patch_for_npc(u16 tag, u8 pal_slot) {
  386. u16 npc_map_entry = npc_pal_idx_for_given_tag(tag);
  387. gpu_pal_apply(npc_palettes[npc_map_entry].palette, (pal_slot + 16) * 16, 32);
  388. tint_palette(pal_slot);
  389. dns_apply_shaders(pal_slot + 16, 1, palette_unfaded_buffer);
  390. }
  391. /*use fade in animation, load palettes according to current fade state*/