mirror of https://github.com/pret/pokeemerald.git
272 lines
6.5 KiB
C
272 lines
6.5 KiB
C
|
#ifndef GUARD_SPRITE_H
|
||
|
#define GUARD_SPRITE_H
|
||
|
|
||
|
#define MAX_SPRITES 64
|
||
|
|
||
|
struct SpriteSheet
|
||
|
{
|
||
|
const u8 *data; // Raw uncompressed pixel data
|
||
|
u16 size;
|
||
|
u16 tag;
|
||
|
};
|
||
|
|
||
|
struct CompressedSpriteSheet
|
||
|
{
|
||
|
const u8 *data; // LZ77 compressed pixel data
|
||
|
u16 size; // Uncompressed size of pixel data
|
||
|
u16 tag;
|
||
|
};
|
||
|
|
||
|
struct SpriteFrameImage
|
||
|
{
|
||
|
const u8 *data;
|
||
|
u16 size;
|
||
|
};
|
||
|
|
||
|
#define obj_frame_tiles(ptr) {.data = (u8 *)ptr, .size = sizeof ptr}
|
||
|
|
||
|
struct SpritePalette
|
||
|
{
|
||
|
const u16 *data; // Raw uncompressed palette data
|
||
|
u16 tag;
|
||
|
};
|
||
|
|
||
|
struct CompressedSpritePalette
|
||
|
{
|
||
|
const u8 *data; // LZ77 compressed palette data
|
||
|
u16 tag;
|
||
|
};
|
||
|
|
||
|
struct AnimFrameCmd
|
||
|
{
|
||
|
// If the sprite has an array of images, this is the array index.
|
||
|
// If the sprite has a sheet, this is the tile offset.
|
||
|
u32 imageValue:16;
|
||
|
|
||
|
u32 duration:6;
|
||
|
u32 hFlip:1;
|
||
|
u32 vFlip:1;
|
||
|
};
|
||
|
|
||
|
struct AnimLoopCmd
|
||
|
{
|
||
|
u32 type:16;
|
||
|
u32 count:6;
|
||
|
};
|
||
|
|
||
|
struct AnimJumpCmd
|
||
|
{
|
||
|
u32 type:16;
|
||
|
u32 target:6;
|
||
|
};
|
||
|
|
||
|
// The first halfword of this union specifies the type of command.
|
||
|
// If it -2, then it is a jump command. If it is -1, then it is the end of the script.
|
||
|
// Otherwise, it is the imageValue for a frame command.
|
||
|
union AnimCmd
|
||
|
{
|
||
|
s16 type;
|
||
|
struct AnimFrameCmd frame;
|
||
|
struct AnimLoopCmd loop;
|
||
|
struct AnimJumpCmd jump;
|
||
|
};
|
||
|
|
||
|
#define ANIMCMD_FRAME(...) \
|
||
|
{.frame = {__VA_ARGS__}}
|
||
|
#define ANIMCMD_LOOP(_count) \
|
||
|
{.loop = {.type = -3, .count = _count}}
|
||
|
#define ANIMCMD_JUMP(_target) \
|
||
|
{.jump = {.type = -2, .target = _target}}
|
||
|
#define ANIMCMD_END \
|
||
|
{.type = -1}
|
||
|
|
||
|
struct AffineAnimFrameCmd
|
||
|
{
|
||
|
s16 xScale;
|
||
|
s16 yScale;
|
||
|
u8 rotation;
|
||
|
u8 duration;
|
||
|
};
|
||
|
|
||
|
struct AffineAnimLoopCmd
|
||
|
{
|
||
|
s16 type;
|
||
|
s16 count;
|
||
|
};
|
||
|
|
||
|
struct AffineAnimJumpCmd
|
||
|
{
|
||
|
s16 type;
|
||
|
u16 target;
|
||
|
};
|
||
|
|
||
|
union AffineAnimCmd
|
||
|
{
|
||
|
s16 type;
|
||
|
struct AffineAnimFrameCmd frame;
|
||
|
struct AffineAnimLoopCmd loop;
|
||
|
struct AffineAnimJumpCmd jump;
|
||
|
};
|
||
|
|
||
|
#define AFFINEANIMCMDTYPE_LOOP 0x7FFD
|
||
|
#define AFFINEANIMCMDTYPE_JUMP 0x7FFE
|
||
|
#define AFFINEANIMCMDTYPE_END 0x7FFF
|
||
|
|
||
|
#define AFFINEANIMCMD_FRAME(_xScale, _yScale, _rotation, _duration) \
|
||
|
{.frame = {.xScale = _xScale, .yScale = _yScale, .rotation = _rotation, .duration = _duration}}
|
||
|
#define AFFINEANIMCMD_LOOP(_count) \
|
||
|
{.loop = {.type = AFFINEANIMCMDTYPE_LOOP, .count = _count}}
|
||
|
#define AFFINEANIMCMD_JUMP(_target) \
|
||
|
{.jump = {.type = AFFINEANIMCMDTYPE_JUMP, .target = _target}}
|
||
|
#define AFFINEANIMCMD_END \
|
||
|
{.type = AFFINEANIMCMDTYPE_END}
|
||
|
#define AFFINEANIMCMD_LOOP(_count) \
|
||
|
{.loop = {.type = AFFINEANIMCMDTYPE_LOOP, .count = _count}}
|
||
|
#define AFFINEANIMCMD_JUMP(_target) \
|
||
|
{.jump = {.type = AFFINEANIMCMDTYPE_JUMP, .target = _target}}
|
||
|
|
||
|
struct AffineAnimState
|
||
|
{
|
||
|
u8 animNum;
|
||
|
u8 animCmdIndex;
|
||
|
u8 delayCounter;
|
||
|
u8 loopCounter;
|
||
|
s16 xScale;
|
||
|
s16 yScale;
|
||
|
u16 rotation;
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
SUBSPRITES_OFF,
|
||
|
SUBSPRITES_ON,
|
||
|
SUBSPRITES_IGNORE_PRIORITY, // on but priority is ignored
|
||
|
};
|
||
|
|
||
|
struct Subsprite
|
||
|
{
|
||
|
u16 x;
|
||
|
u16 y;
|
||
|
u16 shape:2;
|
||
|
u16 size:2;
|
||
|
u16 tileOffset:10;
|
||
|
u16 priority:2;
|
||
|
};
|
||
|
|
||
|
struct SubspriteTable
|
||
|
{
|
||
|
u8 subspriteCount;
|
||
|
const struct Subsprite *subsprites;
|
||
|
};
|
||
|
|
||
|
struct Sprite;
|
||
|
|
||
|
struct SpriteTemplate
|
||
|
{
|
||
|
u16 tileTag;
|
||
|
u16 paletteTag;
|
||
|
const struct OamData *oam;
|
||
|
const union AnimCmd *const *anims;
|
||
|
const struct SpriteFrameImage *images;
|
||
|
const union AffineAnimCmd *const *affineAnims;
|
||
|
void (*callback)(struct Sprite *);
|
||
|
};
|
||
|
|
||
|
struct Sprite
|
||
|
{
|
||
|
/*0x00*/ struct OamData oam;
|
||
|
/*0x08*/ const union AnimCmd *const *anims;
|
||
|
/*0x0C*/ const struct SpriteFrameImage *images;
|
||
|
/*0x10*/ const union AffineAnimCmd *const *affineAnims;
|
||
|
/*0x14*/ const struct SpriteTemplate *template;
|
||
|
/*0x18*/ const struct SubspriteTable *subspriteTables;
|
||
|
/*0x1C*/ void (*callback)(struct Sprite *);
|
||
|
|
||
|
/*0x20*/ struct Coords16 pos1;
|
||
|
/*0x24*/ struct Coords16 pos2;
|
||
|
/*0x28*/ s8 centerToCornerVecX;
|
||
|
/*0x29*/ s8 centerToCornerVecY;
|
||
|
|
||
|
/*0x2A*/ u8 animNum;
|
||
|
/*0x2B*/ u8 animCmdIndex;
|
||
|
/*0x2C*/ u8 animDelayCounter:6;
|
||
|
u8 animPaused:1;
|
||
|
u8 affineAnimPaused:1;
|
||
|
/*0x2D*/ u8 animLoopCounter;
|
||
|
|
||
|
// general purpose data fields
|
||
|
/*0x2E*/ s16 data0;
|
||
|
/*0x30*/ s16 data1;
|
||
|
/*0x32*/ s16 data2;
|
||
|
/*0x34*/ s16 data3;
|
||
|
/*0x36*/ s16 data4;
|
||
|
/*0x38*/ s16 data5;
|
||
|
/*0x3A*/ s16 data6;
|
||
|
/*0x3C*/ s16 data7;
|
||
|
|
||
|
/*0x3E*/ u16 inUse:1; //1
|
||
|
u16 coordOffsetEnabled:1; //2
|
||
|
u16 invisible:1; //4
|
||
|
u16 flags_3:1; //8
|
||
|
u16 flags_4:1; //0x10
|
||
|
u16 flags_5:1; //0x20
|
||
|
u16 flags_6:1; //0x40
|
||
|
u16 flags_7:1; //0x80
|
||
|
/*0x3F*/ u16 hFlip:1;
|
||
|
u16 vFlip:1;
|
||
|
u16 animBeginning:1;
|
||
|
u16 affineAnimBeginning:1;
|
||
|
u16 animEnded:1;
|
||
|
u16 affineAnimEnded:1;
|
||
|
u16 usingSheet:1;
|
||
|
u16 flags_f:1;
|
||
|
|
||
|
/*0x40*/ u16 sheetTileStart;
|
||
|
|
||
|
/*0x42*/ u8 subspriteTableNum:6;
|
||
|
u8 subspriteMode:2;
|
||
|
|
||
|
/*0x43*/ u8 subpriority;
|
||
|
};
|
||
|
|
||
|
struct OamMatrix
|
||
|
{
|
||
|
s16 a;
|
||
|
s16 b;
|
||
|
s16 c;
|
||
|
s16 d;
|
||
|
};
|
||
|
|
||
|
extern struct Sprite gSprites[];
|
||
|
|
||
|
extern const struct OamData gDummyOamData;
|
||
|
|
||
|
void ResetSpriteData(void);
|
||
|
void AnimateSprites(void);
|
||
|
void BuildOamBuffer(void);
|
||
|
u8 CreateSprite(const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority);
|
||
|
u8 CreateSpriteAtEnd(const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority);
|
||
|
u8 CreateInvisibleSprite(void (*callback)(struct Sprite *));
|
||
|
u8 CreateSpriteAndAnimate(struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority);
|
||
|
void DestroySprite(struct Sprite *sprite);
|
||
|
void ResetOamRange(u8 a, u8 b);
|
||
|
void LoadOam(void);
|
||
|
void SetOamMatrix(u8 matrixNum, u16 a, u16 b, u16 c, u16 d);
|
||
|
void CalcCenterToCornerVec(struct Sprite *sprite, u8 shape, u8 size, u8 affineMode);
|
||
|
void SpriteCallbackDummy(struct Sprite *sprite);
|
||
|
void ProcessSpriteCopyRequests(void);
|
||
|
void RequestSpriteCopy(const u8 *src, u8 *dest, u16 size);
|
||
|
void FreeSpriteTiles(struct Sprite *sprite);
|
||
|
void FreeSpritePalette(struct Sprite *sprite);
|
||
|
void FreeSpriteOamMatrix(struct Sprite *sprite);
|
||
|
void RequestSpriteCopy(const u8 *src, u8 *dest, u16 size);
|
||
|
void FreeSpriteTiles(struct Sprite *sprite);
|
||
|
void FreeSpritePalette(struct Sprite *sprite);
|
||
|
void FreeSpriteOamMatrix(struct Sprite *sprite);
|
||
|
void FreeSpriteTilesByTag(u16 tag);
|
||
|
void FreeSpriteTileRanges(void);
|
||
|
void AnimateSprite(struct Sprite *sprite);
|
||
|
bool8 AddSpriteToOamBuffer(struct Sprite *object, u8 *oamIndex);
|
||
|
|
||
|
#endif //GUARD_SPRITE_H
|