Added dynamic reflections.
This commit is contained in:
parent
db46bf855d
commit
12a2ec9f26
4 changed files with 90 additions and 52 deletions
|
@ -1599,14 +1599,18 @@ void AllocSpriteTileRange(u16 tag, u16 start, u16 count)
|
|||
void FreeAllSpritePalettes(void)
|
||||
{
|
||||
u8 i;
|
||||
u16 emptyPalette[16] = {0};
|
||||
gReservedSpritePaletteCount = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
sSpritePaletteTags[i] = 0xFFFF;
|
||||
LoadPalette(emptyPalette, i * 16 + 0x100, 32); // TODO: For debugging only
|
||||
}
|
||||
|
||||
u8 LoadSpritePalette(const struct SpritePalette *palette)
|
||||
{
|
||||
u8 index = IndexOfSpritePaletteTag(palette->tag);
|
||||
u8 i;
|
||||
u16 *debugPtr = (u16*) 0x0203d800;
|
||||
|
||||
if (index != 0xFF)
|
||||
return index;
|
||||
|
@ -1620,6 +1624,9 @@ u8 LoadSpritePalette(const struct SpritePalette *palette)
|
|||
else
|
||||
{
|
||||
sSpritePaletteTags[index] = palette->tag;
|
||||
for (i = 0; i < 16; i++) {
|
||||
debugPtr[i] = sSpritePaletteTags[i];
|
||||
}
|
||||
DoLoadSpritePalette(palette->data, index * 16);
|
||||
return index;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,6 @@ u8 GetObjectEventIdByXY(s16, s16);
|
|||
void SetObjectEventDirection(struct ObjectEvent *, u8);
|
||||
u8 GetFirstInactiveObjectEventId(void);
|
||||
void RemoveObjectEventByLocalIdAndMap(u8, u8, u8);
|
||||
void LoadPlayerObjectReflectionPalette(u16, u8);
|
||||
void LoadSpecialObjectReflectionPalette(u16, u8);
|
||||
void TryMoveObjectEventToMapCoords(u8, u8, u8, s16, s16);
|
||||
void PatchObjectPalette(u16, u8);
|
||||
|
@ -108,6 +107,7 @@ u8 SpawnSpecialObjectEventParameterized(u8 graphicsId, u8 movementBehavior, u8 l
|
|||
u8 SpawnSpecialObjectEvent(struct ObjectEventTemplate *);
|
||||
void SetSpritePosToMapCoords(s16, s16, s16 *, s16 *);
|
||||
void CameraObjectReset1(void);
|
||||
u8 UpdateSpritePalette(struct SpritePalette *, struct Sprite *);
|
||||
void ObjectEventSetGraphicsId(struct ObjectEvent *, u8 graphicsId);
|
||||
void ObjectEventTurn(struct ObjectEvent *, u8);
|
||||
void ObjectEventTurnByLocalIdAndMap(u8, u8, u8, u8);
|
||||
|
|
|
@ -1874,37 +1874,36 @@ static void SetPlayerAvatarObjectEventIdAndObjectId(u8 objectEventId, u8 spriteI
|
|||
SetPlayerAvatarExtraStateTransition(gObjectEvents[objectEventId].graphicsId, PLAYER_AVATAR_FLAG_5);
|
||||
}
|
||||
|
||||
// Update sprite's palette, freeing old palette if necessary
|
||||
u8 UpdateSpritePalette(struct SpritePalette * spritePalette, struct Sprite * sprite) {
|
||||
u8 paletteNum = sprite->oam.paletteNum;
|
||||
// Free palette if otherwise unused
|
||||
sprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(paletteNum);
|
||||
sprite->inUse = TRUE;
|
||||
paletteNum = IndexOfSpritePaletteTag(spritePalette->tag);
|
||||
if (paletteNum == 0xFF) {
|
||||
paletteNum = LoadSpritePalette(spritePalette);
|
||||
}
|
||||
sprite->oam.paletteNum = paletteNum;
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
void ObjectEventSetGraphicsId(struct ObjectEvent *objectEvent, u8 graphicsId)
|
||||
{
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(graphicsId);
|
||||
struct Sprite *sprite = &gSprites[objectEvent->spriteId];
|
||||
u16 i;
|
||||
u8 paletteNum;
|
||||
u16 *debugPtr = (u16*) 0x0203d008;
|
||||
|
||||
*debugPtr = graphicsId;
|
||||
*(debugPtr + 1) = graphicsInfo->paletteSlot;
|
||||
if (graphicsInfo->paletteSlot == 0) { // Hack until I can fix this
|
||||
if (graphicsInfo->paletteSlot == 0 && FALSE) { // Hack until I can fix this
|
||||
PatchObjectPalette(graphicsInfo->paletteTag1, graphicsInfo->paletteSlot);
|
||||
paletteNum = 0;
|
||||
} else {
|
||||
paletteNum = sprite->oam.paletteNum;
|
||||
// Free old palette if otherwise unused
|
||||
sprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(paletteNum);
|
||||
sprite->inUse = TRUE;
|
||||
|
||||
i = FindObjectEventPaletteIndexByTag(graphicsInfo->paletteTag1);
|
||||
*(debugPtr + 2) = i;
|
||||
paletteNum = IndexOfSpritePaletteTag(sObjectEventSpritePalettes[i].tag);
|
||||
*(debugPtr + 3) = paletteNum;
|
||||
if (paletteNum == 0xFF) { // Load palette
|
||||
paletteNum = LoadSpritePalette(&sObjectEventSpritePalettes[i]);
|
||||
}
|
||||
paletteNum = UpdateSpritePalette((struct SpritePalette *)&sObjectEventSpritePalettes[i], sprite);
|
||||
}
|
||||
*(debugPtr + 4) = paletteNum;
|
||||
sprite->oam.paletteNum = paletteNum;
|
||||
*((u32*) (debugPtr + 6)) = (u32) &sprite->oam;
|
||||
sprite->oam.shape = graphicsInfo->oam->shape;
|
||||
sprite->oam.size = graphicsInfo->oam->size;
|
||||
sprite->images = graphicsInfo->images;
|
||||
|
@ -2010,9 +2009,6 @@ static void get_berry_tree_graphics(struct ObjectEvent *objectEvent, struct Spri
|
|||
if (berryId > ITEM_TO_BERRY(LAST_BERRY_INDEX))
|
||||
berryId = 0;
|
||||
|
||||
// ObjectEventSetGraphicsId(objectEvent, gBerryTreeObjectEventGraphicsIdTablePointers[berryId][berryStage]);
|
||||
// sprite->images = gBerryTreePicTablePointers[berryId];
|
||||
// sprite->oam.paletteNum = gBerryTreePaletteSlotTablePointers[berryId][berryStage];
|
||||
SetBerryTreeGraphics(objectEvent, berryId, berryStage);
|
||||
StartSpriteAnim(sprite, berryStage);
|
||||
}
|
||||
|
@ -4592,7 +4588,6 @@ bool8 MovementType_FollowPlayer_Shadow(struct ObjectEvent *objectEvent, struct S
|
|||
MoveObjectEventToMapCoords(objectEvent, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.x, gObjectEvents[gPlayerAvatar.objectEventId].currentCoords.y);
|
||||
return FALSE;
|
||||
}
|
||||
// __asm__(".2byte 0xBE00");
|
||||
sprite->data[1] = 1; // Enter idle state
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -7,18 +7,20 @@
|
|||
#include "fieldmap.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "metatile_behavior.h"
|
||||
#include "palette.h"
|
||||
#include "sound.h"
|
||||
#include "sprite.h"
|
||||
#include "trig.h"
|
||||
#include "constants/field_effects.h"
|
||||
#include "constants/songs.h"
|
||||
|
||||
#define OBJ_EVENT_PAL_START 0x1103 // duplicate of define in event_object_movement.c
|
||||
#define OBJ_EVENT_PAL_TAG_NONE 0x11FF // duplicate of define in event_object_movement.c
|
||||
|
||||
static void UpdateObjectReflectionSprite(struct Sprite *);
|
||||
static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite);
|
||||
static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *, u8);
|
||||
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *, u8);
|
||||
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *, struct Sprite *);
|
||||
static void sub_81561FC(struct Sprite *, u8, u8);
|
||||
static void FadeFootprintsTireTracks_Step0(struct Sprite *);
|
||||
static void FadeFootprintsTireTracks_Step1(struct Sprite *);
|
||||
|
@ -34,7 +36,7 @@ static u32 ShowDisguiseFieldEffect(u8, u8, u8);
|
|||
|
||||
#define sReflectionObjEventId data[0]
|
||||
#define sReflectionObjEventLocalId data[1]
|
||||
#define sReflectionVerticalOffset data[2]
|
||||
#define sReflectionVerticalOffset data[2]
|
||||
#define sIsStillReflection data[7]
|
||||
|
||||
void SetUpReflection(struct ObjectEvent *objectEvent, struct Sprite *sprite, bool8 stillReflection)
|
||||
|
@ -44,7 +46,6 @@ void SetUpReflection(struct ObjectEvent *objectEvent, struct Sprite *sprite, boo
|
|||
reflectionSprite = &gSprites[CreateCopySpriteAt(sprite, sprite->pos1.x, sprite->pos1.y, 0x98)];
|
||||
reflectionSprite->callback = UpdateObjectReflectionSprite;
|
||||
reflectionSprite->oam.priority = 3;
|
||||
reflectionSprite->oam.paletteNum = gReflectionEffectPaletteMap[reflectionSprite->oam.paletteNum];
|
||||
reflectionSprite->usingSheet = TRUE;
|
||||
reflectionSprite->anims = gDummySpriteAnimTable;
|
||||
StartSpriteAnim(reflectionSprite, 0);
|
||||
|
@ -77,31 +78,50 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct
|
|||
}
|
||||
else
|
||||
{
|
||||
LoadObjectRegularReflectionPalette(objectEvent, reflectionSprite->oam.paletteNum);
|
||||
LoadObjectRegularReflectionPalette(objectEvent, sprite);
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent, u8 paletteIndex)
|
||||
{
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
||||
// Apply a blue tint effect to a palette
|
||||
static void ApplyReflectionFilter(u8 paletteNum, u16 *dest) {
|
||||
u32 *debugPtr = (u32*) 0x0203d600;
|
||||
u8 i, val, r, g, b;
|
||||
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
|
||||
u16 *src = gPlttBufferUnfaded + 0x100 + paletteNum * 16;
|
||||
*(debugPtr + 2) = (u32) (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;
|
||||
}
|
||||
}
|
||||
|
||||
graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
||||
if (graphicsInfo->reflectionPaletteTag != OBJ_EVENT_PAL_TAG_NONE)
|
||||
{
|
||||
if (graphicsInfo->paletteSlot == 0)
|
||||
{
|
||||
LoadPlayerObjectReflectionPalette(graphicsInfo->paletteTag, paletteIndex);
|
||||
}
|
||||
else if (graphicsInfo->paletteSlot == 10)
|
||||
{
|
||||
LoadSpecialObjectReflectionPalette(graphicsInfo->paletteTag, paletteIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
PatchObjectPalette(GetObjectPaletteTag(paletteIndex), paletteIndex);
|
||||
}
|
||||
UpdateSpritePaletteWithWeather(paletteIndex);
|
||||
static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
||||
{
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId);
|
||||
u16 baseTag = gSprites[objectEvent->spriteId].oam.paletteNum;
|
||||
u16 paletteTag = baseTag + OBJ_EVENT_PAL_TAG_NONE + 0x1000;
|
||||
struct SpritePalette filteredPalette;
|
||||
u16 filteredData[16] = {0};
|
||||
u8 paletteIndex = IndexOfSpritePaletteTag(paletteTag);
|
||||
u32 *debugPtr = (u32*) 0x0203d600;
|
||||
if (paletteIndex == 0xFF) { // Build filtered palette
|
||||
*(debugPtr) = baseTag;
|
||||
*(debugPtr + 1) = (u32) filteredData;
|
||||
__asm__(".2byte 0xBE00");
|
||||
ApplyReflectionFilter(baseTag, filteredData);
|
||||
*(debugPtr + 1) = (u32) filteredData;
|
||||
__asm__(".2byte 0xBE00");
|
||||
filteredPalette.tag = paletteTag;
|
||||
filteredPalette.data = filteredData;
|
||||
paletteIndex = LoadSpritePalette(&filteredPalette);
|
||||
// UpdateSpritePaletteWithWeather(paletteIndex);
|
||||
}
|
||||
sprite->oam.paletteNum = paletteIndex;
|
||||
}
|
||||
|
||||
// When walking on a bridge high above water (Route 120), the reflection is a solid dark blue color.
|
||||
|
@ -120,18 +140,34 @@ static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEven
|
|||
|
||||
static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
|
||||
{
|
||||
struct ObjectEvent *objectEvent;
|
||||
struct Sprite *mainSprite;
|
||||
struct ObjectEvent *objectEvent = &gObjectEvents[reflectionSprite->data[0]];
|
||||
struct Sprite *mainSprite = &gSprites[objectEvent->spriteId];
|
||||
u16 baseTag = mainSprite->oam.paletteNum;
|
||||
u16 paletteTag = baseTag + OBJ_EVENT_PAL_TAG_NONE + 0x1000;
|
||||
struct SpritePalette filteredPalette;
|
||||
u16 filteredData[16] = {0};
|
||||
u8 paletteNum;
|
||||
|
||||
objectEvent = &gObjectEvents[reflectionSprite->sReflectionObjEventId];
|
||||
mainSprite = &gSprites[objectEvent->spriteId];
|
||||
if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->sReflectionObjEventLocalId)
|
||||
if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->data[1])
|
||||
{
|
||||
reflectionSprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
reflectionSprite->oam.paletteNum = gReflectionEffectPaletteMap[mainSprite->oam.paletteNum];
|
||||
// Free palette if unused
|
||||
reflectionSprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum);
|
||||
reflectionSprite->inUse = TRUE;
|
||||
paletteNum = IndexOfSpritePaletteTag(paletteTag);
|
||||
if (paletteNum == 0xFF) { // Build filtered palette
|
||||
ApplyReflectionFilter(baseTag, filteredData);
|
||||
filteredPalette.tag = paletteTag;
|
||||
filteredPalette.data = filteredData;
|
||||
paletteNum = LoadSpritePalette(&filteredPalette);
|
||||
}
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue