Без опису

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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 debug.c
  24. * @author Sturmvogel
  25. * @date 15 dec 2016
  26. * @brief Operate with the sots debug engine, very temporary
  27. */
  28. /* === INCLUDE === */
  29. #include <assets/ascii.h>
  30. #include <battle_test.h>
  31. #include <callback.h>
  32. #include <debug.h>
  33. #include <fade.h>
  34. #include <lcd.h>
  35. #include <math.h>
  36. #include <memory.h>
  37. #include <types.h>
  38. /* === STRUCTURES === */
  39. struct assert_memory {
  40. char *file;
  41. int line;
  42. char *expression;
  43. };
  44. /* === STATICS === */
  45. struct assert_memory *assert_global = (struct assert_memory *)0x0203FEC4;
  46. static struct print_engine *print_memory = (struct print_engine *)(0x0203FFF0);
  47. /* === PROTOTYPES === */
  48. /**
  49. * @brief convert int to char
  50. * @param i integer
  51. * @param ref buffer to output to
  52. */
  53. void debug_int_to_char(u32 i, char *ref);
  54. /**
  55. * @get length of integer
  56. * @param i integer
  57. * @return length
  58. */
  59. u32 debug_dec_len(u32 i);
  60. /**
  61. * @brief update debug environment
  62. */
  63. void debug_update();
  64. /**
  65. * @brief reset scrolling (from overworld e.g.)
  66. */
  67. void debug_reset_scrolling();
  68. /**
  69. * @brief start a unit test function
  70. */
  71. void debug_init_unit_test();
  72. /**
  73. * @brief handle for the debug scene
  74. */
  75. void debug_scene();
  76. /**
  77. * @brief convert character to byte
  78. * @param character character
  79. * @return byte from character
  80. */
  81. u8 char_to_byte(char character);
  82. /**
  83. * @brief print a character on the debug environment
  84. * @param line line to print to
  85. * @param row row to print to
  86. * @param character character to print
  87. * @param color color to print in
  88. */
  89. void debug_print_char(u16 line, u16 row, char character, u8 color);
  90. /**
  91. * @brief print a string to the debug environment
  92. * @param line line to print to
  93. * @param row row to start
  94. * @param color color to print in
  95. * @param pBuf string buffer to print (null terminated)
  96. */
  97. void debug_print_string(u16 line, u16 row, u8 color, char *pBuf);
  98. /**
  99. * @brief build power
  100. * @param n integer to power
  101. * @param power exponent
  102. * @return n^power
  103. */
  104. u32 debug_power(u32 n, u32 power);
  105. void debug_init_stage_one();
  106. void debug_init_stage_two();
  107. /**
  108. * @brief set bg color of debug environment
  109. * @param color color to set to
  110. */
  111. void debug_set_bg(u16 color) {
  112. u16 *bgc = (u16 *)0x020375f8;
  113. *bgc = color;
  114. return;
  115. }
  116. /* === STATIC STRUCTURES === */
  117. static struct bg_config debug_bg_config[4] = {
  118. {0, 0, 0x19, 0, 0, 0}, {1, 1, 0x1A, 0, 0, 1}, {2, 2, 0x1B, 0, 0, 2}, {3, 3, 0x1C, 0, 0, 3}};
  119. /* === IMPLEMENTATIONS === */
  120. void as_assert(char *expression, char *file, int line) {
  121. assert_global->file = file;
  122. assert_global->line = line;
  123. assert_global->expression = expression;
  124. set_callback2(debug_assert_scene);
  125. vblank_handler_set(debug_update);
  126. superstate.multi_purpose_state_tracker = 0;
  127. }
  128. void debug_scene() {
  129. if (superstate.multi_purpose_state_tracker == 0) {
  130. debug_init_stage_one();
  131. superstate.multi_purpose_state_tracker++;
  132. } else if (superstate.multi_purpose_state_tracker == 1) {
  133. debug_init_stage_two();
  134. superstate.multi_purpose_state_tracker++;
  135. } else if (superstate.multi_purpose_state_tracker == 2) {
  136. debug_init_unit_test();
  137. superstate.multi_purpose_state_tracker++;
  138. }
  139. return;
  140. }
  141. void debug_some_test() {
  142. set_callback2(debug_scene);
  143. vblank_handler_set(debug_update);
  144. superstate.multi_purpose_state_tracker = 0;
  145. return;
  146. }
  147. void debug_reset_scrolling() {
  148. lcd_io_set_func(0x12, 0x0);
  149. lcd_io_set_func(0x14, 0x0);
  150. lcd_io_set_func(0x16, 0x0);
  151. lcd_io_set_func(0x18, 0x0);
  152. lcd_io_set_func(0x1A, 0x0);
  153. lcd_io_set_func(0x1C, 0x0);
  154. lcd_io_set_func(0x1E, 0x0);
  155. return;
  156. }
  157. void debug_init_unit_test() { test_speed(); }
  158. void debug_print_string(u16 line, u16 row, u8 color, char *pBuf) {
  159. while (*pBuf) {
  160. debug_print_char(line, row++, *pBuf++, color);
  161. }
  162. return;
  163. }
  164. void debug_print(char *str) {
  165. while (*str) {
  166. if (print_memory->row > 29) {
  167. print_memory->line++;
  168. print_memory->row = 0;
  169. }
  170. if (*str == '\n') {
  171. print_memory->line++;
  172. print_memory->row = 0;
  173. }
  174. if (*str == '\xFE') {
  175. str++;
  176. u8 c = *str;
  177. if (c > 2)
  178. c = 0;
  179. print_memory->color = c;
  180. } else {
  181. debug_print_char(print_memory->line, print_memory->row, *str, print_memory->color);
  182. print_memory->row++;
  183. }
  184. str++;
  185. }
  186. return;
  187. }
  188. void debug_printf(char *str, int arg) {
  189. while (*str) {
  190. if (print_memory->row > 29) {
  191. print_memory->line++;
  192. print_memory->row = 0;
  193. }
  194. if (*str == '\n') {
  195. print_memory->line++;
  196. print_memory->row = 0;
  197. }
  198. if (*str == '\xFE') {
  199. str++;
  200. u8 c = *str;
  201. if (c > 2)
  202. c = 0;
  203. print_memory->color = c;
  204. } else if (*str == '%') {
  205. str++;
  206. if (*str == '%') {
  207. debug_print_char(print_memory->line, print_memory->row, *str, print_memory->color);
  208. print_memory->row++;
  209. } else if (*str == 'd') {
  210. u32 len = debug_dec_len(arg);
  211. char temp[debug_dec_len(len + 1)];
  212. temp[len] = 0;
  213. debug_int_to_char(arg, temp);
  214. debug_print(temp);
  215. } else if (*str == 'c') {
  216. char print_char = (char)(arg);
  217. debug_print_char(print_memory->line, print_memory->row, print_char, print_memory->color);
  218. print_memory->row++;
  219. }
  220. } else {
  221. debug_print_char(print_memory->line, print_memory->row, *str, print_memory->color);
  222. print_memory->row++;
  223. }
  224. str++;
  225. }
  226. }
  227. void debug_clean() {
  228. memset((void *)0x0600C800, 0, 0x800);
  229. print_memory->row = 0;
  230. print_memory->line = 0;
  231. print_memory->color = 0;
  232. return;
  233. }
  234. void debug_wait_for_btn(u16 field) {
  235. volatile u16 *control_io = (volatile u16 *)(0x04000130);
  236. while (*control_io & field) {
  237. }
  238. return;
  239. }
  240. void debug_init_stage_one() {
  241. print_memory->row = 0;
  242. print_memory->line = 0;
  243. print_memory->color = 0;
  244. gpu_tile_bg_drop_all_sets(0);
  245. gpu_tile_bg_drop_all_sets(1);
  246. gpu_tile_bg_drop_all_sets(2);
  247. gpu_tile_bg_drop_all_sets(3);
  248. gpu_bg_vram_setup(0, debug_bg_config, 4);
  249. gpu_bg_show(0);
  250. gpu_bg_show(1);
  251. gpu_bg_show(2);
  252. gpu_bg_show(3);
  253. gpu_sync_bg_visibility_and_mode();
  254. debug_reset_scrolling();
  255. obj_delete_all();
  256. memset((void *)0x06000000, 0, 0x17fe0);
  257. memset((void *)0x020375F8, 0, 0x400);
  258. }
  259. void debug_init_stage_two() {
  260. vram_decompress((void *)asciiTiles, (void *)0x06000000);
  261. memcpy((void *)0x020375F8, (void *)asciiPal, 0x60);
  262. debug_set_bg(0x0000);
  263. }
  264. void debug_assert_scene() {
  265. if (superstate.multi_purpose_state_tracker == 0) {
  266. debug_init_stage_one();
  267. superstate.multi_purpose_state_tracker++;
  268. } else if (superstate.multi_purpose_state_tracker == 1) {
  269. debug_init_stage_two();
  270. superstate.multi_purpose_state_tracker++;
  271. } else if (superstate.multi_purpose_state_tracker == 2) {
  272. debug_print("Assertion Failed: ");
  273. debug_print(assert_global->expression);
  274. debug_print("\n\nFile: ");
  275. debug_print(assert_global->file);
  276. debug_printf("\n\nLine: %d", assert_global->line);
  277. superstate.multi_purpose_state_tracker++;
  278. }
  279. /* Loop Endlessly in this stage */
  280. return;
  281. }
  282. void debug_print_char(u16 line, u16 row, char character, u8 color) {
  283. if (color > 2)
  284. color = 0;
  285. u16 position = (32 * line) + row;
  286. union t_map_entry map_entry;
  287. map_entry.entry.tile = char_to_byte(character);
  288. map_entry.entry.pal = color;
  289. u16 *ptr = (u16 *)(0x0600c800 + (position * 2));
  290. *ptr = map_entry.short_map;
  291. return;
  292. }
  293. u8 char_to_byte(char character) {
  294. if (character >= 0x20 && character <= 0x7E)
  295. return character - 0x20;
  296. else
  297. return 3;
  298. }
  299. void debug_update() {
  300. fade_update();
  301. task_exec();
  302. objc_exec();
  303. obj_sync();
  304. gpu_pal_upload();
  305. obj_gpu_sprites_upload();
  306. }
  307. void debug_int_to_char(u32 i, char *ref) {
  308. if (i == 0) {
  309. ref[0] = '0';
  310. return;
  311. }
  312. u32 len = debug_dec_len(i);
  313. while (i > 0) {
  314. ref[len - 1] = '0' + (i % 10);
  315. i /= 10;
  316. len--;
  317. }
  318. return;
  319. }
  320. u32 debug_power(u32 n, u32 power) {
  321. u32 out = 1;
  322. for (u32 i = 0; i < power; ++i) {
  323. out = out * n;
  324. }
  325. return out;
  326. }
  327. u32 debug_dec_len(u32 i) {
  328. u32 len = 1;
  329. while ((i /= 10) > 0) {
  330. len++;
  331. }
  332. return len;
  333. }