No Description

text_animator.c 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <pokeagb/pokeagb.h>
  2. #include <tileset_animation/font.h>
  3. #include <config.h>
  4. #define CANVAS_X_START (22)
  5. #define CANVAS_Y_START (35)
  6. #define CANVAS_X_SECOND (22)
  7. #define CANVAS_Y_SECOND (36)
  8. #define CANVAS_FIRST ((u8 *)(574 * 0x20 + 0x06000000))
  9. #define CANVAS_SECOND ((u8 *)(592 * 0x20 + 0x06000000))
  10. static const char *map_texts[] = {"--------", "< Carun City", "Route 2 >", "< Route 3", "< Urbania City", "Route 5 >", "< Route 6", NULL};
  11. s16 char_to_tile_index(char chr) {
  12. if (chr >= 'A' && chr <= 'P')
  13. return chr - 'A';
  14. if (chr >= 'Q' && chr <= 'Z')
  15. return (16 * 2) + (chr - 'Q');
  16. if (chr >= '0' && chr <= '9')
  17. return (16 * 8) + (chr - '0');
  18. if (chr >= 'a' && chr <= 'p')
  19. return (16 * 4) + (chr - 'a');
  20. if (chr >= 'q' && chr <= 'z')
  21. return (16 * 6) + (chr - 'q');
  22. if (chr == '<')
  23. return char_to_tile_index('z') + 1;
  24. if (chr == '>')
  25. return char_to_tile_index('z') + 2;
  26. if (chr == ' ')
  27. return char_to_tile_index('9') + 1;
  28. return -1;
  29. }
  30. void draw_text_on_canvas(const char *txt) {
  31. u16 current_tile = 0;
  32. while (*txt) {
  33. s16 tile = char_to_tile_index(*txt);
  34. if (tile != -1) {
  35. void *first = CANVAS_FIRST + (current_tile * 0x20);
  36. void *second = CANVAS_SECOND + (current_tile * 0x20);
  37. memcpy(first, fontTiles + (tile * 0x20), 0x20);
  38. memcpy(second, fontTiles + (16 * 0x20) + (tile * 0x20), 0x20);
  39. }
  40. txt++;
  41. current_tile++;
  42. }
  43. }
  44. u8 get_pixel(u8 x, u8 y, u16 *start) {
  45. u16 block = start[16 * (x / 4) + 2 * y + ((x % 4) / 2)];
  46. if (x % 2 == 0)
  47. return block & 0xFF;
  48. return (block >> 8);
  49. }
  50. void set_pixel(u8 x, u8 y, u16 *start, u16 pixel) {
  51. pixel &= 0xFF;
  52. u16 *addr = &start[16 * (x / 4) + 2 * y + ((x % 4) / 2)];
  53. if (x % 2 == 0)
  54. *addr = (*addr & 0xFF00) | (pixel);
  55. else
  56. *addr = (*((u8 *)addr)) | (pixel << 8);
  57. }
  58. #define ANIMATION_FRAME_SPEED 2
  59. /* TODO: Compile RELEASE Versions of the game with higher optimization flags */
  60. #define TEXT_ANIM_TILE_ROW(c, x, y) (((u32 *)c)[x * 8 + y])
  61. void text_animator(u16 current_frame) {
  62. if ((current_frame % ANIMATION_FRAME_SPEED) == 0) {
  63. for (int y = 0; y < 8; ++y) {
  64. u32 outer_pixel_upper = CANVAS_FIRST[y * 4];
  65. u32 outer_pixel_lower = CANVAS_SECOND[y * 4];
  66. for (int x = 17; x >= 0; --x) {
  67. // tile: AB-CD-EF-GH-|-NX BC-DE-FG-HN
  68. // mem: BA-DC-FE-HG-|-XN ---> CB-ED-GF-NH
  69. // register: HG-FE-DC-BA NH-GF-ED-CB
  70. u32 upper_row = TEXT_ANIM_TILE_ROW(CANVAS_FIRST, x, y);
  71. u32 new_outer_pixel_upper = upper_row;
  72. upper_row = (upper_row >> 4) | (outer_pixel_upper << 28);
  73. TEXT_ANIM_TILE_ROW(CANVAS_FIRST, x, y) = upper_row;
  74. outer_pixel_upper = new_outer_pixel_upper;
  75. u32 lower_row = TEXT_ANIM_TILE_ROW(CANVAS_SECOND, x, y);
  76. u32 new_outer_pixel_lower = lower_row;
  77. lower_row = (lower_row >> 4) | (outer_pixel_lower << 28);
  78. TEXT_ANIM_TILE_ROW(CANVAS_SECOND, x, y) = lower_row;
  79. outer_pixel_lower = new_outer_pixel_lower;
  80. }
  81. }
  82. }
  83. }
  84. void anim_init_text(void) {
  85. blockset_one_current_tile = 0;
  86. blockset_one_max_tile = 0x280;
  87. blockset_one_animator = NULL;
  88. u16 text = var_load(TEXT_ANIMATION_VAR);
  89. if (text != 0) {
  90. draw_text_on_canvas(map_texts[text]);
  91. blockset_one_animator = text_animator;
  92. }
  93. }