From 9978e9eced4da2098ad52eb778d14c55833d1943 Mon Sep 17 00:00:00 2001 From: wgroeneveld Date: Fri, 7 Dec 2018 14:44:56 +0100 Subject: [PATCH] fix sprite animation for all sizes --- .../libgba-sprite-engine/sprites/sprite.h | 3 +- engine/src/sprites/sprite.cpp | 29 +++++++++---------- test/spritetest.cpp | 19 +++++++++--- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/engine/include/libgba-sprite-engine/sprites/sprite.h b/engine/include/libgba-sprite-engine/sprites/sprite.h index 530fbca..c2f6dfe 100644 --- a/engine/include/libgba-sprite-engine/sprites/sprite.h +++ b/engine/include/libgba-sprite-engine/sprites/sprite.h @@ -44,11 +44,11 @@ private: void updateVelocity(); void updateAnimation(); void syncVelocity(); - void syncAnimation(); protected: const void *data; int x, y, dx, dy; + u8 animation_offset; u32 priority, w, h, size_bits, shape_bits; bool stayWithinBounds; u32 imageSize, tileIndex; @@ -58,6 +58,7 @@ protected: std::unique_ptr oam; + void syncAnimation(); virtual void syncOam(); virtual void buildOam(int tileIndex); void setAttributesBasedOnSize(SpriteSize size); diff --git a/engine/src/sprites/sprite.cpp b/engine/src/sprites/sprite.cpp index 8969492..4662d51 100644 --- a/engine/src/sprites/sprite.cpp +++ b/engine/src/sprites/sprite.cpp @@ -52,10 +52,7 @@ void Sprite::syncVelocity() { } void Sprite::syncAnimation() { - int offset = w == 64 ? 2 : 1; // 64xY sprites don't seem to cut currFrame * w - int width = w == 16 ? 8 : w; // 16xY sprites: frame 192 -> 200 (x8) (skip last 2 bpps) - int newTileIndex = this->tileIndex + (currentFrame * width * offset); - + int newTileIndex = this->tileIndex + (currentFrame * (this->animation_offset * 2)); oam->attr2 &= OAM_TILE_OFFSET_CLEAR; oam->attr2 |= (newTileIndex & OAM_TILE_OFFSET_NEW); } @@ -99,18 +96,18 @@ void Sprite::update() { void Sprite::setAttributesBasedOnSize(SpriteSize size) { switch (size) { - case SIZE_8_8: size_bits = 0; shape_bits = 0; w = 8; h = 8; break; - case SIZE_16_16: size_bits = 1; shape_bits = 0; w = 16; h = 16; break; - case SIZE_32_32: size_bits = 2; shape_bits = 0; w = 32; h = 32; break; - case SIZE_64_64: size_bits = 3; shape_bits = 0; w = 64; h = 64; break; - case SIZE_16_8: size_bits = 0; shape_bits = 1; w = 16; h = 8; break; - case SIZE_32_8: size_bits = 1; shape_bits = 1; w = 32; h = 8; break; - case SIZE_32_16: size_bits = 2; shape_bits = 1; w = 32; h = 16; break; - case SIZE_64_32: size_bits = 3; shape_bits = 1; w = 64; h = 32; break; - case SIZE_8_16: size_bits = 0; shape_bits = 2; w = 8; h = 16; break; - case SIZE_8_32: size_bits = 1; shape_bits = 2; w = 8; h = 32; break; - case SIZE_16_32: size_bits = 2; shape_bits = 2; w = 16; h = 32; break; - case SIZE_32_64: size_bits = 3; shape_bits = 2; w = 32; h = 64; break; + case SIZE_8_8: size_bits = 0; shape_bits = 0; w = 8; h = 8; animation_offset = 1; break; + case SIZE_16_16: size_bits = 1; shape_bits = 0; w = 16; h = 16; animation_offset = 4; break; + case SIZE_32_32: size_bits = 2; shape_bits = 0; w = 32; h = 32; animation_offset = 16; break; + case SIZE_64_64: size_bits = 3; shape_bits = 0; w = 64; h = 64; animation_offset = 64; break; + case SIZE_16_8: size_bits = 0; shape_bits = 1; w = 16; h = 8; animation_offset = 2; break; + case SIZE_32_8: size_bits = 1; shape_bits = 1; w = 32; h = 8; animation_offset = 4; break; + case SIZE_32_16: size_bits = 2; shape_bits = 1; w = 32; h = 16; animation_offset = 8; break; + case SIZE_64_32: size_bits = 3; shape_bits = 1; w = 64; h = 32; animation_offset = 32; break; + case SIZE_8_16: size_bits = 0; shape_bits = 2; w = 8; h = 16; animation_offset = 2; break; + case SIZE_8_32: size_bits = 1; shape_bits = 2; w = 8; h = 32; animation_offset = 4; break; + case SIZE_16_32: size_bits = 2; shape_bits = 2; w = 16; h = 32; animation_offset = 8; break; + case SIZE_32_64: size_bits = 3; shape_bits = 2; w = 32; h = 64; animation_offset = 32; break; } } diff --git a/test/spritetest.cpp b/test/spritetest.cpp index 7fcd743..dea7d2d 100644 --- a/test/spritetest.cpp +++ b/test/spritetest.cpp @@ -181,12 +181,12 @@ const u32 kul_data [] = { class SpriteWithStubOam : public Sprite { public: - SpriteWithStubOam() : Sprite(nullptr, imageSize, x, y, SIZE_8_8) { + SpriteWithStubOam(SpriteSize size) : Sprite(nullptr, imageSize, x, y, size) { oam = std::unique_ptr(new OBJ_ATTR()); } - OBJ_ATTR* buildOamForTesting() { - buildOam(0); + OBJ_ATTR* buildOamForTesting(int tileIndex = 0) { + buildOam(tileIndex); return oam.get(); } @@ -201,10 +201,21 @@ protected: } virtual void SetUp() { - s = new SpriteWithStubOam(); + s = new SpriteWithStubOam(SIZE_8_8); } }; +TEST_F(SpriteSuite, Sync_Animation_Updates_OAM_To_Next_Frame) { + s = new SpriteWithStubOam(SIZE_16_32); + s->makeAnimated(2, 0); + auto oam = s->buildOamForTesting(208); // should start at 224 (11100000) after a frame update + s->update(); + + auto attr2 = std::bitset<16>(oam->attr2).to_string(); + + ASSERT_EQ(std::string("0000000011100000"), attr2); +} + TEST_F(SpriteSuite, Animated_Sprite_Increases_Current_Frame_After_Delay) { s->makeAnimated(2, 5);