Improved support for 64x64 followers. Updated reflection code.
Added 24x24 subsprite tables.
This commit is contained in:
parent
8df538479a
commit
9c77aa3c66
4 changed files with 1621 additions and 887 deletions
|
@ -85,6 +85,8 @@
|
|||
#define SAFE_DIV(a, b) ((a) / (b))
|
||||
#endif
|
||||
|
||||
#define IS_POW_OF_TWO(n) (((n) & ((n)-1)) == 0)
|
||||
|
||||
// The below macro does a%n, but (to match) will switch to a&(n-1) if n is a power of 2.
|
||||
// There are cases where GF does a&(n-1) where we would really like to have a%n, because
|
||||
// if n is changed to a value that isn't a power of 2 then a&(n-1) is unlikely to work as
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6749,19 +6749,26 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct
|
|||
return TRUE;
|
||||
// Set graphics, palette, and affine animation
|
||||
} else if ((duration == 0 && sprite->data[3] == 3) || (duration == 1 && sprite->data[3] == 7)) {
|
||||
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny);
|
||||
LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite);
|
||||
// Initialize affine animation
|
||||
sprite->affineAnims = sAffineAnims_PokeballFollower;
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
|
||||
InitSpriteAffineAnim(sprite);
|
||||
StartSpriteAffineAnim(sprite, sprite->data[6] >> 4);
|
||||
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny);
|
||||
LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite);
|
||||
// Initialize affine animation
|
||||
sprite->affineAnims = sAffineAnims_PokeballFollower;
|
||||
#if LARGE_OW_SUPPORT
|
||||
if (IS_POW_OF_TWO(-sprite->centerToCornerVecX)) {
|
||||
#endif
|
||||
sprite->affineAnims = sAffineAnims_PokeballFollower;
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
|
||||
InitSpriteAffineAnim(sprite);
|
||||
StartSpriteAffineAnim(sprite, sprite->data[6] >> 4);
|
||||
#if LARGE_OW_SUPPORT
|
||||
}
|
||||
#endif
|
||||
// Restore original palette & disable affine
|
||||
} else if ((duration == 0 && sprite->data[3] == 1) || (duration == 1 && sprite->data[3] == 3)) {
|
||||
sprite->affineAnimEnded = TRUE;
|
||||
FreeSpriteOamMatrix(sprite);
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
||||
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny);
|
||||
sprite->affineAnimEnded = TRUE;
|
||||
FreeSpriteOamMatrix(sprite);
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
||||
FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -6782,20 +6789,26 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct
|
|||
sprite->data[2] = 2;
|
||||
return FALSE;
|
||||
} else if (sprite->data[3] == 11) { // Set palette to white & start affine
|
||||
LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite);
|
||||
sprite->affineAnims = sAffineAnims_PokeballFollower;
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
|
||||
#if LARGE_OW_SUPPORT
|
||||
sprite->subspriteTableNum = 1;
|
||||
#endif
|
||||
InitSpriteAffineAnim(sprite);
|
||||
StartSpriteAffineAnim(sprite, sprite->data[6]);
|
||||
LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite);
|
||||
#if LARGE_OW_SUPPORT
|
||||
// Only do affine if sprite width is power of 2
|
||||
// (effect looks weird on sprites composed of subsprites like 48x48, etc)
|
||||
if (IS_POW_OF_TWO(-sprite->centerToCornerVecX)) {
|
||||
#endif
|
||||
sprite->affineAnims = sAffineAnims_PokeballFollower;
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
|
||||
InitSpriteAffineAnim(sprite);
|
||||
StartSpriteAffineAnim(sprite, sprite->data[6]);
|
||||
#if LARGE_OW_SUPPORT
|
||||
}
|
||||
#endif
|
||||
sprite->subspriteTableNum = 0;
|
||||
} else if (sprite->data[3] == 7) { // Free white palette and change to pokeball, disable affine
|
||||
sprite->affineAnimEnded = TRUE;
|
||||
FreeSpriteOamMatrix(sprite);
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
||||
ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL);
|
||||
objectEvent->inanimate = FALSE;
|
||||
sprite->affineAnimEnded = TRUE;
|
||||
FreeSpriteOamMatrix(sprite);
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
||||
ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL);
|
||||
objectEvent->inanimate = FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -8853,9 +8866,6 @@ void ObjectEventUpdateElevation(struct ObjectEvent *objEvent, struct Sprite *spr
|
|||
#endif
|
||||
return;
|
||||
}
|
||||
#if LARGE_OW_SUPPORT
|
||||
sprite->subspriteMode = SUBSPRITES_ON;
|
||||
#endif
|
||||
|
||||
objEvent->currentElevation = curElevation;
|
||||
|
||||
|
@ -9246,6 +9256,9 @@ static void DoGroundEffects_OnSpawn(struct ObjectEvent *objEvent, struct Sprite
|
|||
if (objEvent->triggerGroundEffectsOnMove)
|
||||
{
|
||||
flags = 0;
|
||||
#if LARGE_OW_SUPPORT
|
||||
sprite->subspriteMode = SUBSPRITES_ON;
|
||||
#endif
|
||||
UpdateObjectEventElevationAndPriority(objEvent, sprite);
|
||||
GetAllGroundEffectFlags_OnSpawn(objEvent, &flags);
|
||||
SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite);
|
||||
|
@ -9262,6 +9275,9 @@ static void DoGroundEffects_OnBeginStep(struct ObjectEvent *objEvent, struct Spr
|
|||
if (objEvent->triggerGroundEffectsOnMove)
|
||||
{
|
||||
flags = 0;
|
||||
#if LARGE_OW_SUPPORT
|
||||
sprite->subspriteMode = SUBSPRITES_ON;
|
||||
#endif
|
||||
UpdateObjectEventElevationAndPriority(objEvent, sprite);
|
||||
GetAllGroundEffectFlags_OnBeginStep(objEvent, &flags);
|
||||
SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite);
|
||||
|
|
|
@ -13,11 +13,15 @@
|
|||
#include "trig.h"
|
||||
#include "constants/event_objects.h"
|
||||
#include "constants/field_effects.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "constants/songs.h"
|
||||
|
||||
#define OBJ_EVENT_PAL_TAG_NONE 0x11FF // duplicate of define in event_object_movement.c
|
||||
#define PAL_TAG_REFLECTION_OFFSET 0x2000 // reflection tag value is paletteTag + 0x2000
|
||||
#define PAL_RAW_REFLECTION_OFFSET 0x4000 // raw reflection tag is paletteNum + 0x4000
|
||||
#define HIGH_BRIDGE_PAL_TAG 0x4010
|
||||
// Build a unique tag for reflection's palette based on based tag, or paletteNum
|
||||
#define REFLECTION_PAL_TAG(tag, num) ((tag) == TAG_NONE ? (num) + PAL_RAW_REFLECTION_OFFSET : (tag) + PAL_TAG_REFLECTION_OFFSET)
|
||||
|
||||
static void UpdateObjectReflectionSprite(struct Sprite *);
|
||||
static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite);
|
||||
|
@ -65,8 +69,9 @@ void SetUpReflection(struct ObjectEvent *objectEvent, struct Sprite *sprite, boo
|
|||
StartSpriteAnim(reflectionSprite, 0);
|
||||
reflectionSprite->affineAnims = gDummySpriteAffineAnimTable;
|
||||
reflectionSprite->affineAnimBeginning = TRUE;
|
||||
reflectionSprite->subspriteMode = SUBSPRITES_OFF;
|
||||
reflectionSprite->sReflectionObjEventId = sprite->data[0];
|
||||
reflectionSprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
|
||||
reflectionSprite->subspriteTableNum = 0;
|
||||
reflectionSprite->sReflectionObjEventId = sprite->sReflectionObjEventId;
|
||||
reflectionSprite->sReflectionObjEventLocalId = objectEvent->localId;
|
||||
reflectionSprite->sIsStillReflection = stillReflection;
|
||||
LoadObjectReflectionPalette(objectEvent, reflectionSprite);
|
||||
|
@ -93,7 +98,7 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct
|
|||
&& ((bridgeType = MetatileBehavior_GetBridgeType(objectEvent->previousMetatileBehavior))
|
||||
|| (bridgeType = MetatileBehavior_GetBridgeType(objectEvent->currentMetatileBehavior))))
|
||||
{
|
||||
reflectionSprite->data[2] = bridgeReflectionVerticalOffsets[bridgeType - 1];
|
||||
reflectionSprite->sReflectionVerticalOffset = bridgeReflectionVerticalOffsets[bridgeType - 1];
|
||||
LoadObjectHighBridgeReflectionPalette(objectEvent, reflectionSprite);
|
||||
}
|
||||
else
|
||||
|
@ -104,76 +109,71 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct
|
|||
|
||||
// Apply a blue tint effect to a palette
|
||||
static void ApplyPondFilter(u8 paletteNum, u16 *dest) {
|
||||
u8 i, val, r, g, b;
|
||||
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
|
||||
u16 *src = gPlttBufferUnfaded + 0x100 + paletteNum * 16;
|
||||
for (i = 0; i < 16; i++) {
|
||||
r = src[i] & 0x1F;
|
||||
g = (src[i] >> 5) & 0x1F;
|
||||
b = (src[i] >> 10) & 0x1F;
|
||||
b += 10;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
*dest++ = (b << 10) | (g << 5) | r;
|
||||
}
|
||||
u32 i, r, g, b;
|
||||
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
|
||||
u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum);
|
||||
*dest++ = *src++; // copy transparency
|
||||
for (i = 0; i < 16 - 1; i++) {
|
||||
r = GET_R(src[i]);
|
||||
g = GET_G(src[i]);
|
||||
b = GET_B(src[i]);
|
||||
b += 10;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
*dest++ = RGB2(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply a ice tint effect to a palette
|
||||
static void ApplyIceFilter(u8 paletteNum, u16 *dest) {
|
||||
u8 i, val, r, g, b;
|
||||
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
|
||||
u16 *src = gPlttBufferUnfaded + 0x100 + paletteNum * 16;
|
||||
for (i = 0; i < 16; i++) {
|
||||
r = src[i] & 0x1F;
|
||||
r -= 5;
|
||||
if (r > 31)
|
||||
r = 0;
|
||||
g = (src[i] >> 5) & 0x1F;
|
||||
g += 3;
|
||||
if (g > 31)
|
||||
g = 31;
|
||||
b = (src[i] >> 10) & 0x1F;
|
||||
b += 16;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
*dest++ = (b << 10) | (g << 5) | r;
|
||||
}
|
||||
u32 i, r, g, b;
|
||||
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
|
||||
u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum);
|
||||
*dest++ = *src++; // copy transparency
|
||||
for (i = 0; i < 16 - 1; i++) {
|
||||
r = GET_R(src[i]);
|
||||
r -= 5;
|
||||
if (r > 31)
|
||||
r = 0;
|
||||
g = GET_G(src[i]);
|
||||
g += 3;
|
||||
if (g > 31)
|
||||
g = 31;
|
||||
b = GET_B(src[i]);
|
||||
b += 16;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
*dest++ = RGB2(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
||||
{
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
||||
const struct Sprite *mainSprite = &gSprites[objectEvent->spriteId];
|
||||
u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum);
|
||||
u16 paletteTag = baseTag == 0xFFFF ? mainSprite->oam.paletteNum + PAL_RAW_REFLECTION_OFFSET : baseTag + PAL_TAG_REFLECTION_OFFSET;
|
||||
u16 paletteTag = REFLECTION_PAL_TAG(baseTag, mainSprite->oam.paletteNum);
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(paletteTag);
|
||||
if (paletteNum == 0xFF) { // Load filtered palette
|
||||
u16 filteredData[16] = {0};
|
||||
struct SpritePalette filteredPalette = {.tag = paletteTag, .data = filteredData};
|
||||
if (sprite->data[7] == FALSE) {
|
||||
ApplyPondFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
} else {
|
||||
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
}
|
||||
paletteNum = LoadSpritePalette(&filteredPalette);
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
if (paletteNum <= 16) { // Load filtered palette
|
||||
u16 filteredData[16];
|
||||
struct SpritePalette filteredPal = {.tag = paletteTag, .data = filteredData};
|
||||
if (sprite->sIsStillReflection == FALSE)
|
||||
ApplyPondFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
else
|
||||
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
paletteNum = LoadSpritePalette(&filteredPal);
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
}
|
||||
sprite->oam.paletteNum = paletteNum;
|
||||
sprite->oam.objMode = 1; // Alpha blending
|
||||
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
}
|
||||
|
||||
#define HIGH_BRIDGE_PAL_TAG 0x4010
|
||||
|
||||
// When walking on a bridge high above water (Route 120), the reflection is a solid dark blue color.
|
||||
// This is so the sprite blends in with the dark water metatile underneath the bridge.
|
||||
static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
||||
{
|
||||
u16 blueData[16] = {0};
|
||||
u16 blueData[16];
|
||||
struct SpritePalette bluePalette = {.tag = HIGH_BRIDGE_PAL_TAG, .data = blueData};
|
||||
u8 i;
|
||||
for (i = 1; i < 16; i++) {
|
||||
blueData[i] = 0x55c9;
|
||||
}
|
||||
CpuFill16(0x55C9, blueData, PLTT_SIZE_4BPP);
|
||||
sprite->oam.paletteNum = LoadSpritePalette(&bluePalette);
|
||||
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum);
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
|
|||
struct ObjectEvent *objectEvent = &gObjectEvents[reflectionSprite->data[0]];
|
||||
struct Sprite *mainSprite = &gSprites[objectEvent->spriteId];
|
||||
|
||||
if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->data[1])
|
||||
if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->sReflectionObjEventLocalId)
|
||||
{
|
||||
reflectionSprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum);
|
||||
|
@ -191,37 +191,37 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
|
|||
}
|
||||
|
||||
// Only filter palette if not using the high bridge blue palette
|
||||
// This is basically a copy of LoadObjectRegularReflectionPalette
|
||||
if (IndexOfSpritePaletteTag(HIGH_BRIDGE_PAL_TAG) != reflectionSprite->oam.paletteNum) {
|
||||
u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum);
|
||||
u16 paletteTag = baseTag == 0xFFFF ? mainSprite->oam.paletteNum + PAL_RAW_REFLECTION_OFFSET : baseTag + PAL_TAG_REFLECTION_OFFSET;
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(paletteTag);
|
||||
if (paletteNum == 0xFF) { // Build filtered palette
|
||||
u16 filteredData[16] = {0};
|
||||
struct SpritePalette filteredPalette = {.tag = paletteTag, .data = filteredData};
|
||||
// Free palette if unused
|
||||
reflectionSprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum);
|
||||
reflectionSprite->inUse = TRUE;
|
||||
if (reflectionSprite->data[7] == FALSE) {
|
||||
ApplyPondFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
} else {
|
||||
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum);
|
||||
u16 paletteTag = REFLECTION_PAL_TAG(baseTag, mainSprite->oam.paletteNum);
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(paletteTag);
|
||||
if (paletteNum >= 16) { // Build filtered palette
|
||||
u16 filteredData[16];
|
||||
struct SpritePalette filteredPal = {.tag = paletteTag, .data = filteredData};
|
||||
// Free palette if unused
|
||||
reflectionSprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum);
|
||||
reflectionSprite->inUse = TRUE;
|
||||
if (reflectionSprite->sIsStillReflection == FALSE) {
|
||||
ApplyPondFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
} else {
|
||||
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
}
|
||||
paletteNum = LoadSpritePalette(&filteredPal);
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
}
|
||||
paletteNum = LoadSpritePalette(&filteredPalette);
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
}
|
||||
reflectionSprite->oam.paletteNum = paletteNum;
|
||||
reflectionSprite->oam.paletteNum = paletteNum;
|
||||
}
|
||||
reflectionSprite->oam.shape = mainSprite->oam.shape;
|
||||
reflectionSprite->oam.size = mainSprite->oam.size;
|
||||
reflectionSprite->oam.matrixNum = mainSprite->oam.matrixNum | ST_OAM_VFLIP;
|
||||
reflectionSprite->oam.tileNum = mainSprite->oam.tileNum;
|
||||
reflectionSprite->subspriteTables = mainSprite->subspriteTables;
|
||||
reflectionSprite->subspriteTableNum = mainSprite->subspriteTableNum;
|
||||
reflectionSprite->invisible = mainSprite->invisible;
|
||||
reflectionSprite->x = mainSprite->x;
|
||||
// reflectionSprite->data[2] holds an additional vertical offset, used by the high bridges on Route 120
|
||||
reflectionSprite->y = mainSprite->y + GetReflectionVerticalOffset(objectEvent) + reflectionSprite->data[2];
|
||||
// sReflectionVerticalOffset is only set for high bridges
|
||||
reflectionSprite->y = mainSprite->y + GetReflectionVerticalOffset(objectEvent) + reflectionSprite->sReflectionVerticalOffset;
|
||||
reflectionSprite->centerToCornerVecX = mainSprite->centerToCornerVecX;
|
||||
reflectionSprite->centerToCornerVecY = mainSprite->centerToCornerVecY;
|
||||
reflectionSprite->x2 = mainSprite->x2;
|
||||
|
@ -231,15 +231,17 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
|
|||
if (objectEvent->hideReflection == TRUE)
|
||||
reflectionSprite->invisible = TRUE;
|
||||
|
||||
// Check if the reflection is not still.
|
||||
if (reflectionSprite->data[7] == FALSE)
|
||||
// Support "virtual" sprites which can't be rotated via affines
|
||||
if (reflectionSprite->subspriteTables[0].subsprites) {
|
||||
reflectionSprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
||||
return;
|
||||
}
|
||||
if (reflectionSprite->sIsStillReflection == FALSE)
|
||||
{
|
||||
// Sets the reflection sprite's rot/scale matrix to the appropriate
|
||||
// matrix based on whether or not the main sprite is horizontally flipped.
|
||||
// If the sprite is facing to the east, then it is flipped, and its matrixNum is 8.
|
||||
reflectionSprite->oam.matrixNum = 0;
|
||||
if (mainSprite->oam.matrixNum & ST_OAM_HFLIP)
|
||||
reflectionSprite->oam.matrixNum = 1;
|
||||
// Sets the reflection sprite's rot/scale matrix to the correct
|
||||
// water reflection matrix based on the main sprite's facing direction.
|
||||
// If the sprite is facing east, then it's flipped, and its matrixNum is 1.
|
||||
reflectionSprite->oam.matrixNum = (mainSprite->oam.matrixNum & ST_OAM_HFLIP) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue