Parcourir la source

Improve animation performance.

ipatix il y a 6 ans
Parent
révision
63d15b1acc
1 fichiers modifiés avec 40 ajouts et 11 suppressions
  1. 40
    11
      src/overworld/tileset_animation/main_animator.c

+ 40
- 11
src/overworld/tileset_animation/main_animator.c Voir le fichier

@@ -1,8 +1,19 @@
1 1
 #include <pokeagb/pokeagb.h>
2
+#include <agb_debug.h>
2 3
 #include <tileset_animation/smoke.h>
3 4
 #include <tileset_animation/water_stone.h>
4 5
 #include <tileset_animation/flowers_mag.h>
5 6
 #include <tileset_animation/flowers_ora.h>
7
+
8
+#define NUM_MAX_ANIMATIONS 16
9
+
10
+struct TilesetAnimationState {
11
+    u16 cur_frame[NUM_MAX_ANIMATIONS];
12
+    u16 cur_tile[NUM_MAX_ANIMATIONS];
13
+};
14
+
15
+static struct TilesetAnimationState *anim_state = (struct TilesetAnimationState *)0x203FAB4;
16
+
6 17
 struct TilesetAnimation {
7 18
     u16 tile_start;
8 19
     u16 frame_length;
@@ -21,16 +32,30 @@ const struct TilesetAnimation hesperia_second_animations[] = {
21 32
 
22 33
 void animate_from_structure(const struct TilesetAnimation *anim, u16 tile_skip, u16 current_frame) {
23 34
     void *vram_address = (void *)(0x06000000 + (tile_skip * 0x20));
24
-    u8 current_animation = 0;
25
-    while (anim[current_animation].image != (void *)0xFFFFFFFF) {
26
-        void *current_vram = vram_address + (0x20 * anim[current_animation].tile_start);
27
-        u16 max_frame = anim[current_animation].frame_length * anim[current_animation].frame_count;
28
-        u16 used_frame = current_frame % max_frame;
29
-        used_frame /= anim[current_animation].frame_length;
30
-        dprintf("using tile %d.\n",used_frame);
31
-        memcpy(current_vram, anim[current_animation].image + (0x20 * anim[current_animation].tile_length * used_frame),
32
-               anim[current_animation].tile_length * 0x20);
33
-        current_animation++;
35
+    u8 cur_anim = 0;
36
+    while (anim[cur_anim].image != (void *)0xFFFFFFFF && cur_anim < NUM_MAX_ANIMATIONS) {
37
+        void *current_vram = vram_address + (0x20 * anim[cur_anim].tile_start);
38
+
39
+        if (anim_state->cur_frame[cur_anim] == 0) {
40
+            memcpy(current_vram, anim[cur_anim].image +
41
+                    (0x20 * anim[cur_anim].tile_length * anim_state->cur_tile[cur_anim]),
42
+                    anim[cur_anim].tile_length * 0x20);
43
+        }
44
+
45
+        anim_state->cur_frame[cur_anim] += 1;
46
+        if (anim_state->cur_frame[cur_anim] >= anim[cur_anim].frame_length) {
47
+            anim_state->cur_frame[cur_anim] = 0;
48
+            anim_state->cur_tile[cur_anim] += 1;
49
+            if (anim_state->cur_tile[cur_anim] >= anim[cur_anim].frame_count) {
50
+                anim_state->cur_tile[cur_anim] = 0;
51
+            }
52
+        }
53
+
54
+        cur_anim++;
55
+    }
56
+    if (cur_anim >= NUM_MAX_ANIMATIONS) {
57
+        dprintf("Warning! Animation State array not big enough to play all animations\n"
58
+                "Please increase the limit in %s\n", __FILE__);
34 59
     }
35 60
 }
36 61
 
@@ -53,4 +78,8 @@ void main_second_animator_init(void) {
53 78
     blockset_two_current_frame = 0;
54 79
     blockset_two_max_frame = 0x3C0;
55 80
     blockset_two_animator = main_second_animator;
56
-}
81
+
82
+    for (int i = 0; i < NUM_MAX_ANIMATIONS; i++) {
83
+        anim_state->cur_frame[i] = 0;
84
+    }
85
+}