summaryrefslogtreecommitdiff
path: root/src/sprite.c
diff options
context:
space:
mode:
authorDizzyEggg <jajkodizzy@wp.pl>2017-09-02 00:21:11 +0200
committerDizzyEggg <jajkodizzy@wp.pl>2017-09-02 00:21:11 +0200
commit26bf61e06fb4c29e9a297d88dbe42942ba0c96b9 (patch)
treecba71f429712e34a9f98c119d6f17f3d166a0407 /src/sprite.c
parentbc5acf7394d9e0058d52df1872133cac385694c7 (diff)
start decompiling sprite.s
Diffstat (limited to 'src/sprite.c')
-rw-r--r--src/sprite.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/src/sprite.c b/src/sprite.c
index 3b73363ac..245dc2660 100644
--- a/src/sprite.c
+++ b/src/sprite.c
@@ -1,5 +1,6 @@
#include "global.h"
#include "sprite.h"
+#include "main.h"
#define OAM_MATRIX_COUNT 32
@@ -10,6 +11,56 @@ struct SpriteCopyRequest
u16 size;
};
+// this file's functions
+void UpdateOamCoords(void);
+void BuildSpritePriorities(void);
+void SortSprites(void);
+void CopyMatricesToOamBuffer(void);
+void AddSpritesToOamBuffer(void);
+u8 CreateSpriteAt(u8 index, const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority);
+void ClearSpriteCopyRequests(void);
+void ResetOamMatrices(void);
+void ResetSprite(struct Sprite *sprite);
+s16 AllocSpriteTiles(u16 tileCount);
+void RequestSpriteFrameImageCopy(u16 index, u16 tileNum, const struct SpriteFrameImage *images);
+void ResetAllSprites(void);
+void BeginAnim(struct Sprite *sprite);
+void ContinueAnim(struct Sprite *sprite);
+void AnimCmd_frame(struct Sprite *sprite);
+void AnimCmd_end(struct Sprite *sprite);
+void AnimCmd_jump(struct Sprite *sprite);
+void AnimCmd_loop(struct Sprite *sprite);
+void BeginAnimLoop(struct Sprite *sprite);
+void ContinueAnimLoop(struct Sprite *sprite);
+void JumpToTopOfAnimLoop(struct Sprite *sprite);
+void BeginAffineAnim(struct Sprite *sprite);
+void ContinueAffineAnim(struct Sprite *sprite);
+void AffineAnimDelay(u8 matrixNum, struct Sprite *sprite);
+void AffineAnimCmd_loop(u8 matrixNum, struct Sprite *sprite);
+void BeginAffineAnimLoop(u8 matrixNum, struct Sprite *sprite);
+void ContinueAffineAnimLoop(u8 matrixNum, struct Sprite *sprite);
+void JumpToTopOfAffineAnimLoop(u8 matrixNum, struct Sprite *sprite);
+void AffineAnimCmd_jump(u8 matrixNum, struct Sprite *sprite);
+void AffineAnimCmd_end(u8 matrixNum, struct Sprite *sprite);
+void AffineAnimCmd_frame(u8 matrixNum, struct Sprite *sprite);
+void CopyOamMatrix(u8 destMatrixIndex, struct OamMatrix *srcMatrix);
+u8 GetSpriteMatrixNum(struct Sprite *sprite);
+void SetSpriteOamFlipBits(struct Sprite *sprite, u8 hFlip, u8 vFlip);
+void AffineAnimStateRestartAnim(u8 matrixNum);
+void AffineAnimStateStartAnim(u8 matrixNum, u8 animNum);
+void AffineAnimStateReset(u8 matrixNum);
+void ApplyAffineAnimFrameAbsolute(u8 matrixNum, struct AffineAnimFrameCmd *frameCmd);
+void DecrementAnimDelayCounter(struct Sprite *sprite);
+bool8 DecrementAffineAnimDelayCounter(struct Sprite *sprite, u8 matrixNum);
+void ApplyAffineAnimFrameRelativeAndUpdateMatrix(u8 matrixNum, struct AffineAnimFrameCmd *frameCmd);
+s16 ConvertScaleParam(s16 scale);
+void GetAffineAnimFrame(u8 matrixNum, struct Sprite *sprite, struct AffineAnimFrameCmd *frameCmd);
+void ApplyAffineAnimFrame(u8 matrixNum, struct AffineAnimFrameCmd *frameCmd);
+void ResetAffineAnimData(void);
+u8 IndexOfSpriteTileTag(u16 tag);
+void AllocSpriteTileRange(u16 tag, u16 start, u16 count);
+void DoLoadSpritePalette(const u16 *src, u16 paletteOffset);
+
EWRAM_DATA struct Sprite gSprites[MAX_SPRITES + 1] = {0};
EWRAM_DATA u16 gSpritePriorities[MAX_SPRITES] = {0};
EWRAM_DATA u8 gSpriteOrder[MAX_SPRITES] = {0};
@@ -23,3 +74,188 @@ EWRAM_DATA s16 gSpriteCoordOffsetX = 0;
EWRAM_DATA s16 gSpriteCoordOffsetY = 0;
EWRAM_DATA struct OamMatrix gOamMatrices[OAM_MATRIX_COUNT] = {0};
EWRAM_DATA bool8 gAffineAnimsDisabled = 0;
+
+void ResetSpriteData(void)
+{
+ ResetOamRange(0, 128);
+ ResetAllSprites();
+ ClearSpriteCopyRequests();
+ ResetAffineAnimData();
+ FreeSpriteTileRanges();
+ gOamLimit = 64;
+ gReservedSpriteTileCount = 0;
+ AllocSpriteTiles(0);
+ gSpriteCoordOffsetX = 0;
+ gSpriteCoordOffsetY = 0;
+}
+
+void AnimateSprites(void)
+{
+ u8 i;
+ for (i = 0; i < MAX_SPRITES; i++)
+ {
+ struct Sprite *sprite = &gSprites[i];
+
+ if (sprite->inUse)
+ {
+ sprite->callback(sprite);
+
+ if (sprite->inUse)
+ AnimateSprite(sprite);
+ }
+ }
+}
+
+void BuildOamBuffer(void)
+{
+ u8 temp;
+ UpdateOamCoords();
+ BuildSpritePriorities();
+ SortSprites();
+ temp = gMain.oamLoadDisabled;
+ gMain.oamLoadDisabled = TRUE;
+ AddSpritesToOamBuffer();
+ CopyMatricesToOamBuffer();
+ gMain.oamLoadDisabled = temp;
+ gShouldProcessSpriteCopyRequests = TRUE;
+}
+
+void UpdateOamCoords(void)
+{
+ u8 i;
+ for (i = 0; i < MAX_SPRITES; i++)
+ {
+ struct Sprite *sprite = &gSprites[i];
+ if (sprite->inUse && !sprite->invisible)
+ {
+ if (sprite->coordOffsetEnabled)
+ {
+ sprite->oam.x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX;
+ sprite->oam.y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY;
+ }
+ else
+ {
+ sprite->oam.x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX;
+ sprite->oam.y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY;
+ }
+ }
+ }
+}
+
+void BuildSpritePriorities(void)
+{
+ u16 i;
+ for (i = 0; i < MAX_SPRITES; i++)
+ {
+ struct Sprite *sprite = &gSprites[i];
+ u16 priority = sprite->subpriority | (sprite->oam.priority << 8);
+ gSpritePriorities[i] = priority;
+ }
+}
+
+void SortSprites(void)
+{
+ u8 i;
+ for (i = 1; i < MAX_SPRITES; i++)
+ {
+ u8 j = i;
+ struct Sprite *sprite1 = &gSprites[gSpriteOrder[i - 1]];
+ struct Sprite *sprite2 = &gSprites[gSpriteOrder[i]];
+ u16 sprite1Priority = gSpritePriorities[gSpriteOrder[i - 1]];
+ u16 sprite2Priority = gSpritePriorities[gSpriteOrder[i]];
+ s16 sprite1Y = sprite1->oam.y;
+ s16 sprite2Y = sprite2->oam.y;
+
+ if (sprite1Y >= DISPLAY_HEIGHT)
+ sprite1Y = sprite1Y - 256;
+
+ if (sprite2Y >= DISPLAY_HEIGHT)
+ sprite2Y = sprite2Y - 256;
+
+ if (sprite1->oam.affineMode == ST_OAM_AFFINE_DOUBLE
+ && sprite1->oam.size == 3)
+ {
+ u32 shape = sprite1->oam.shape;
+ if (shape == ST_OAM_SQUARE || shape == 2)
+ {
+ if (sprite1Y > 128)
+ sprite1Y = sprite1Y - 256;
+ }
+ }
+
+ if (sprite2->oam.affineMode == ST_OAM_AFFINE_DOUBLE
+ && sprite2->oam.size == 3)
+ {
+ u32 shape = sprite2->oam.shape;
+ if (shape == ST_OAM_SQUARE || shape == ST_OAM_V_RECTANGLE)
+ {
+ if (sprite2Y > 128)
+ sprite2Y = sprite2Y - 256;
+ }
+ }
+
+ while (j > 0
+ && ((sprite1Priority > sprite2Priority)
+ || (sprite1Priority == sprite2Priority && sprite1Y < sprite2Y)))
+ {
+ u8 temp = gSpriteOrder[j];
+ gSpriteOrder[j] = gSpriteOrder[j - 1];
+ gSpriteOrder[j - 1] = temp;
+
+ // UB: If j equals 1, then j-- makes j equal 0.
+ // Then, gSpriteOrder[-1] gets accessed below.
+ // Although this doesn't result in a bug in the ROM,
+ // the behavior is undefined.
+ j--;
+
+ sprite1 = &gSprites[gSpriteOrder[j - 1]];
+ sprite2 = &gSprites[gSpriteOrder[j]];
+ sprite1Priority = gSpritePriorities[gSpriteOrder[j - 1]];
+ sprite2Priority = gSpritePriorities[gSpriteOrder[j]];
+ sprite1Y = sprite1->oam.y;
+ sprite2Y = sprite2->oam.y;
+
+ if (sprite1Y >= DISPLAY_HEIGHT)
+ sprite1Y = sprite1Y - 256;
+
+ if (sprite2Y >= DISPLAY_HEIGHT)
+ sprite2Y = sprite2Y - 256;
+
+ if (sprite1->oam.affineMode == ST_OAM_AFFINE_DOUBLE
+ && sprite1->oam.size == 3)
+ {
+ u32 shape = sprite1->oam.shape;
+ if (shape == ST_OAM_SQUARE || shape == ST_OAM_V_RECTANGLE)
+ {
+ if (sprite1Y > 128)
+ sprite1Y = sprite1Y - 256;
+ }
+ }
+
+ if (sprite2->oam.affineMode == ST_OAM_AFFINE_DOUBLE
+ && sprite2->oam.size == 3)
+ {
+ u32 shape = sprite2->oam.shape;
+ if (shape == ST_OAM_SQUARE || shape == ST_OAM_V_RECTANGLE)
+ {
+ if (sprite2Y > 128)
+ sprite2Y = sprite2Y - 256;
+ }
+ }
+ }
+ }
+}
+
+void CopyMatricesToOamBuffer(void)
+{
+ u8 i;
+ for (i = 0; i < OAM_MATRIX_COUNT; i++)
+ {
+ u32 base = 4 * i;
+ gMain.oamBuffer[base + 0].affineParam = gOamMatrices[i].a;
+ gMain.oamBuffer[base + 1].affineParam = gOamMatrices[i].b;
+ gMain.oamBuffer[base + 2].affineParam = gOamMatrices[i].c;
+ gMain.oamBuffer[base + 3].affineParam = gOamMatrices[i].d;
+ }
+}
+