diff options
author | DizzyEggg <jajkodizzy@wp.pl> | 2017-09-02 00:21:11 +0200 |
---|---|---|
committer | DizzyEggg <jajkodizzy@wp.pl> | 2017-09-02 00:21:11 +0200 |
commit | 26bf61e06fb4c29e9a297d88dbe42942ba0c96b9 (patch) | |
tree | cba71f429712e34a9f98c119d6f17f3d166a0407 /src/sprite.c | |
parent | bc5acf7394d9e0058d52df1872133cac385694c7 (diff) |
start decompiling sprite.s
Diffstat (limited to 'src/sprite.c')
-rw-r--r-- | src/sprite.c | 236 |
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; + } +} + |