Skip to content

Commit

Permalink
Merge pull request #308 from DizzyEggg/sprite_oams
Browse files Browse the repository at this point in the history
  • Loading branch information
SethBarberee authored Dec 23, 2024
2 parents 48e36ec + 6441fae commit ac32ebd
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 1,821 deletions.
220 changes: 215 additions & 5 deletions include/structs/sprite_oam.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,220 @@ typedef struct SpriteOAM
#define SPRITEOAM_MASK_UNK6_3 (SPRITEOAM_MAX_UNK6_3 << SPRITEOAM_SHIFT_UNK6_3) // ~ 0xFFF7
*/

// Seems to be the "working" Y coord. Gets copied to attrib1's Y coord in `AddSprite()`.
// kermalis is too lazy to rename it atm since we're still figuring things out
#define SPRITEOAM_MAX_UNK6_4 0xFFF
#define SPRITEOAM_SHIFT_UNK6_4 4
#define SPRITEOAM_MASK_UNK6_4 (SPRITEOAM_MAX_UNK6_4 << SPRITEOAM_SHIFT_UNK6_4) // ~ 0xF
// It's the "working" Y coord. Gets copied to attrib1's Y coord in `AddSprite()`.
#define SPRITEOAM_MAX_WORKING_Y 0xFFF
#define SPRITEOAM_SHIFT_WORKING_Y 4
#define SPRITEOAM_MASK_WORKING_Y (SPRITEOAM_MAX_WORKING_Y << SPRITEOAM_SHIFT_WORKING_Y) // ~ 0xF

// These seem to work most(all?) of the time.
// These have to be macros, because static inlines WON'T match.

#define SpriteSetOamY(spritePtr, _oamY) \
{ \
u32 _oamYSpriteVal = _oamY; \
_oamYSpriteVal &= SPRITEOAM_MAX_Y; \
_oamYSpriteVal <<= SPRITEOAM_SHIFT_Y; \
(spritePtr)->attrib1 &= ~SPRITEOAM_MASK_Y; \
(spritePtr)->attrib1 |= _oamYSpriteVal; \
}

#define SpriteSetAffine1(spritePtr, _affine1) \
{ \
u32 _affine1Val = _affine1; \
_affine1Val &= SPRITEOAM_MAX_AFFINEMODE1; \
_affine1Val <<= SPRITEOAM_SHIFT_AFFINEMODE1; \
(spritePtr)->attrib1 &= ~SPRITEOAM_MASK_AFFINEMODE1; \
(spritePtr)->attrib1 |= _affine1Val; \
}

#define SpriteSetAffine2(spritePtr, _affine2) \
{ \
u32 _affine2Val = _affine2; \
_affine2Val &= SPRITEOAM_MAX_AFFINEMODE2; \
_affine2Val <<= SPRITEOAM_SHIFT_AFFINEMODE2; \
(spritePtr)->attrib1 &= ~SPRITEOAM_MASK_AFFINEMODE2; \
(spritePtr)->attrib1 |= _affine2Val; \
}

#define SpriteSetObjMode(spritePtr, _objMode) \
{ \
u32 _objModeVal = _objMode; \
_objModeVal &= SPRITEOAM_MAX_OBJMODE; \
_objModeVal <<= SPRITEOAM_SHIFT_OBJMODE; \
(spritePtr)->attrib1 &= ~SPRITEOAM_MASK_OBJMODE; \
(spritePtr)->attrib1 |= _objModeVal; \
}

#define SpriteSetMosaic(spritePtr, _mosaic) \
{ \
u32 _mosaicVal = _mosaic; \
_mosaicVal &= SPRITEOAM_MAX_MOSAIC; \
_mosaicVal <<= SPRITEOAM_SHIFT_MOSAIC; \
(spritePtr)->attrib1 &= ~SPRITEOAM_MASK_MOSAIC; \
(spritePtr)->attrib1 |= _mosaicVal; \
}

#define SpriteSetBpp(spritePtr, _bpp) \
{ \
u32 _bppVal = _bpp; \
_bppVal &= SPRITEOAM_MAX_BPP; \
_bppVal <<= SPRITEOAM_SHIFT_BPP; \
(spritePtr)->attrib1 &= ~SPRITEOAM_MASK_BPP; \
(spritePtr)->attrib1 |= _bppVal; \
}

#define SpriteSetShape(spritePtr, _shape) \
{ \
u32 _shapeVal = _shape; \
_shapeVal &= SPRITEOAM_MAX_SHAPE; \
_shapeVal <<= SPRITEOAM_SHIFT_SHAPE; \
(spritePtr)->attrib1 &= ~SPRITEOAM_MASK_SHAPE; \
(spritePtr)->attrib1 |= _shapeVal; \
}

#define SpriteGetTileNum_LocalVar(spritePtr, _tileNum) \
{ \
_tileNum = (spritePtr)->attrib3; \
_tileNum >>= SPRITEOAM_SHIFT_TILENUM; \
_tileNum &= SPRITEOAM_MAX_TILENUM; \
}

#define SpriteSetTileNum(spritePtr, _tileNum) \
{ \
u32 _tileNumVal = _tileNum; \
_tileNumVal &= SPRITEOAM_MAX_TILENUM; \
_tileNumVal <<= SPRITEOAM_SHIFT_TILENUM; \
(spritePtr)->attrib3 &= ~SPRITEOAM_MASK_TILENUM; \
(spritePtr)->attrib3 |= _tileNumVal; \
}

#define SpriteAddTileNum(spritePtr, addVal) \
{ \
u32 _tileNumValAdd; \
SpriteGetTileNum_LocalVar(spritePtr, _tileNumValAdd); \
_tileNumValAdd += (addVal); \
SpriteSetTileNum(spritePtr, _tileNumValAdd); \
}

#define SpriteSetPriority(spritePtr, _priority) \
{ \
u32 _priorityVal = _priority; \
_priorityVal &= SPRITEOAM_MAX_PRIORITY; \
_priorityVal <<= SPRITEOAM_SHIFT_PRIORITY; \
(spritePtr)->attrib3 &= ~SPRITEOAM_MASK_PRIORITY; \
(spritePtr)->attrib3 |= _priorityVal; \
}

#define SpriteSetPalNum(spritePtr, _palNum) \
{ \
u32 _palNumVal = _palNum; \
_palNumVal &= SPRITEOAM_MAX_PALETTENUM; \
_palNumVal <<= SPRITEOAM_SHIFT_PALETTENUM; \
(spritePtr)->attrib3 &= ~SPRITEOAM_MASK_PALETTENUM; \
(spritePtr)->attrib3 |= _palNumVal; \
}

#define SpriteSetMatrixNum(spritePtr, _matrixNum) \
{ \
u32 _matrixNumVal = _matrixNum; \
_matrixNumVal &= SPRITEOAM_MAX_MATRIXNUM; \
_matrixNumVal <<= SPRITEOAM_SHIFT_MATRIXNUM; \
(spritePtr)->attrib2 &= ~SPRITEOAM_MASK_MATRIXNUM; \
(spritePtr)->attrib2 |= _matrixNumVal; \
}

// Needed for TryCreateModeArrows. No difference to SpriteSetMatrixNum other than not creating one additional local variable.
#define SpriteSetMatrixNum_UseLocalVar(spritePtr, _matrixNum) \
{ \
_matrixNum &= SPRITEOAM_MAX_MATRIXNUM; \
_matrixNum <<= SPRITEOAM_SHIFT_MATRIXNUM; \
(spritePtr)->attrib2 &= ~SPRITEOAM_MASK_MATRIXNUM; \
(spritePtr)->attrib2 |= _matrixNum; \
}

#define SpriteSetSize(spritePtr, _size) \
{ \
u32 _sizeVal = _size; \
_sizeVal &= SPRITEOAM_MAX_SIZE; \
_sizeVal <<= SPRITEOAM_SHIFT_SIZE; \
(spritePtr)->attrib2 &= ~SPRITEOAM_MASK_SIZE; \
(spritePtr)->attrib2 |= _sizeVal; \
}

#define SpriteGetX(spritePtr)(((spritePtr)->attrib2 >> SPRITEOAM_SHIFT_X) & SPRITEOAM_MAX_X)

#define SpriteSetX(spritePtr, _x) \
{ \
u32 _xSpriteVal = _x; \
_xSpriteVal &= SPRITEOAM_MAX_X; \
_xSpriteVal <<= SPRITEOAM_SHIFT_X; \
(spritePtr)->attrib2 &= ~SPRITEOAM_MASK_X; \
(spritePtr)->attrib2 |= _xSpriteVal; \
}

// Hacky way of matching functions in menu_input.c AddMenuCursorSprite_, sub_801332C sub_8013470
#define SpriteSetX_MatrixNumSize0(spritePtr, _x) \
{ \
u32 _xSpriteVal = _x; \
_xSpriteVal &= SPRITEOAM_MAX_X; \
_xSpriteVal <<= SPRITEOAM_SHIFT_X; \
(spritePtr)->attrib2 &= ~SPRITEOAM_MASK_X; \
(spritePtr)->attrib2 = _xSpriteVal; \
}

#define SpriteGetY(spritePtr)(((spritePtr)->unk6 >> SPRITEOAM_SHIFT_WORKING_Y) & SPRITEOAM_MAX_WORKING_Y)

#define SpriteGetY_LocalVar(spritePtr, _y) \
{ \
_y = (spritePtr)->unk6; \
_y >>= SPRITEOAM_SHIFT_WORKING_Y; \
_y &= SPRITEOAM_MAX_WORKING_Y; \
}

#define SpriteSetY(spritePtr, _y) \
{ \
u32 _ySpriteVal = _y; \
_ySpriteVal &= SPRITEOAM_MAX_WORKING_Y; \
_ySpriteVal <<= SPRITEOAM_SHIFT_WORKING_Y; \
(spritePtr)->unk6 &= ~SPRITEOAM_MASK_WORKING_Y; \
(spritePtr)->unk6 |= _ySpriteVal; \
}

#define SpriteAddY(spritePtr, addVal) \
{ \
u32 _yVal; \
SpriteGetY_LocalVar(spritePtr, _yVal); \
_yVal += (addVal); \
SpriteSetY(spritePtr, _yVal); \
}

#define SpriteSetUnk6_0(spritePtr, _unk6_0) \
{ \
u32 _unk6_0Val = _unk6_0; \
_unk6_0Val &= SPRITEOAM_MAX_UNK6_0; \
_unk6_0Val <<= SPRITEOAM_SHIFT_UNK6_0; \
(spritePtr)->unk6 &= ~SPRITEOAM_MASK_UNK6_0; \
(spritePtr)->unk6 |= _unk6_0Val; \
}

#define SpriteGetUnk6_1(spritePtr)(((spritePtr)->unk6 >> SPRITEOAM_SHIFT_UNK6_1) & SPRITEOAM_MAX_UNK6_1)

#define SpriteSetUnk6_1(spritePtr, _unk6_1) \
{ \
u32 _unk6_1Val = _unk6_1; \
_unk6_1Val &= SPRITEOAM_MAX_UNK6_1; \
_unk6_1Val <<= SPRITEOAM_SHIFT_UNK6_1; \
(spritePtr)->unk6 &= ~SPRITEOAM_MASK_UNK6_1; \
(spritePtr)->unk6 |= _unk6_1Val; \
}

#define SpriteSetUnk6_2(spritePtr, _unk6_2) \
{ \
u32 _unk6_2Val = _unk6_2; \
_unk6_2Val &= SPRITEOAM_MAX_UNK6_2; \
_unk6_2Val <<= SPRITEOAM_SHIFT_UNK6_2; \
(spritePtr)->unk6 &= ~SPRITEOAM_MASK_UNK6_2; \
(spritePtr)->unk6 |= _unk6_2Val; \
}

#endif // GUARD_SPRITE_OAM_H
63 changes: 17 additions & 46 deletions src/code_803E724.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,52 +367,23 @@ void sub_803EDF0(void)

// sprite oam memes strike again
if (x >= -32 && y >= -8 && x < 240 && y < 160) {
u32 r9;
u32 unk6;
u32 shape, spriteX, palNum, prio, tileNum;

unk6 = y & SPRITEOAM_MAX_UNK6_4;
unk6 <<= SPRITEOAM_SHIFT_UNK6_4;
gUnknown_202EDDC.unk6 &= ~SPRITEOAM_MASK_UNK6_4;
gUnknown_202EDDC.unk6 |= unk6;

gUnknown_202EDDC.attrib1 &= ~SPRITEOAM_MASK_AFFINEMODE1;
gUnknown_202EDDC.attrib1 &= ~SPRITEOAM_MASK_AFFINEMODE2;
r9 = 3;
gUnknown_202EDDC.attrib1 &= ~SPRITEOAM_MASK_OBJMODE;
gUnknown_202EDDC.attrib1 &= ~SPRITEOAM_MASK_MOSAIC;
gUnknown_202EDDC.attrib1 &= ~SPRITEOAM_MASK_BPP;

shape = 1 << SPRITEOAM_SHIFT_SHAPE;
gUnknown_202EDDC.attrib1 &= ~SPRITEOAM_MASK_SHAPE;
gUnknown_202EDDC.attrib1 |= shape;

spriteX = x & SPRITEOAM_MAX_X;
gUnknown_202EDDC.attrib2 &= ~SPRITEOAM_MASK_X;
gUnknown_202EDDC.attrib2 |= spriteX;

gUnknown_202EDDC.attrib2 &= ~SPRITEOAM_MASK_MATRIXNUM;
gUnknown_202EDDC.attrib2 &= ~SPRITEOAM_MASK_SIZE;
gUnknown_202EDDC.attrib2 |= 1 << SPRITEOAM_SHIFT_SIZE;

tileNum = 0x216 << SPRITEOAM_SHIFT_TILENUM;
gUnknown_202EDDC.attrib3 &= ~SPRITEOAM_MASK_TILENUM;
gUnknown_202EDDC.attrib3 |= tileNum;

prio = gDungeon->unk181e8.unk18208 & r9;
prio <<= SPRITEOAM_SHIFT_PRIORITY;
gUnknown_202EDDC.attrib3 &= ~SPRITEOAM_MASK_PRIORITY;
gUnknown_202EDDC.attrib3 |= prio;

palNum = gUnknown_202EDE8.unk2;
palNum &= 0xF;
palNum <<= SPRITEOAM_SHIFT_PALETTENUM;
gUnknown_202EDDC.attrib3 &= ~SPRITEOAM_MASK_PALETTENUM;
gUnknown_202EDDC.attrib3 |= palNum;

gUnknown_202EDDC.unk6 &= ~SPRITEOAM_MASK_UNK6_0;
gUnknown_202EDDC.unk6 &= ~SPRITEOAM_MASK_UNK6_1;
gUnknown_202EDDC.unk6 &= ~SPRITEOAM_MASK_UNK6_2;
SpriteSetY(&gUnknown_202EDDC, y);
SpriteSetAffine1(&gUnknown_202EDDC, 0);
SpriteSetAffine2(&gUnknown_202EDDC, 0);
SpriteSetObjMode(&gUnknown_202EDDC, 0);
SpriteSetMosaic(&gUnknown_202EDDC, 0);
SpriteSetBpp(&gUnknown_202EDDC, 0);
SpriteSetShape(&gUnknown_202EDDC, 1);
SpriteSetX(&gUnknown_202EDDC, x);
SpriteSetMatrixNum(&gUnknown_202EDDC, 0);
SpriteSetSize(&gUnknown_202EDDC, 1);
SpriteSetTileNum(&gUnknown_202EDDC, 0x216);
SpriteSetPriority(&gUnknown_202EDDC, gDungeon->unk181e8.unk18208);
SpriteSetPalNum(&gUnknown_202EDDC, gUnknown_202EDE8.unk2);

SpriteSetUnk6_0(&gUnknown_202EDDC, 0);
SpriteSetUnk6_1(&gUnknown_202EDDC, 0);
SpriteSetUnk6_2(&gUnknown_202EDDC, 0);

AddSprite(&gUnknown_202EDDC, 0x100, NULL, NULL);
}
Expand Down
Loading

0 comments on commit ac32ebd

Please sign in to comment.