Aucune description

text_animator.c 3.5KB

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