diff --git a/gflib/sprite.c b/gflib/sprite.c index ae8629b343..2355829ff9 100644 --- a/gflib/sprite.c +++ b/gflib/sprite.c @@ -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; } diff --git a/include/event_object_movement.h b/include/event_object_movement.h index f7366de8ea..586e98bffb 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -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); diff --git a/src/event_object_movement.c b/src/event_object_movement.c index cf55ab3512..bc6d7aceb8 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -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; } diff --git a/src/field_effect_helpers.c b/src/field_effect_helpers.c index 67102a83b2..0eb58bf31f 100755 --- a/src/field_effect_helpers.c +++ b/src/field_effect_helpers.c @@ -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;