Merge branch 'lighting' into lighting-expanded-id

This commit is contained in:
Ariel A 2024-08-12 23:11:27 -04:00
commit 8a8c27c6c7
11 changed files with 152 additions and 132 deletions

View File

@ -1,4 +1,7 @@
725252905baf28dbb9298dd5fa0daaf0e804a455
afbb88d77ada8a636a318ec32b61b4ea849d85ab
f861504cfc50941768286c0703d24ab0aaceb88e
ebbcb7d025cff716eec5008b5dd2b7d55aa8c3f3
ebbcb7d025cff716eec5008b5dd2b7d55aa8c3f3
# 24759293+aarant@users.noreply.github.com
# meta: cleaned up spacing of lighting code
0ae5cb1e39f64955107707bbacd1d6dfc117fc01

View File

@ -14,6 +14,8 @@
#define PALETTE_FADE_STATUS_LOADING 0xFF
#define PALETTES_BG 0x0000FFFF
// like PALETTES_BG but excludes UI pals [13, 15]
#define PALETTES_MAP 0x00001FFF
#define PALETTES_OBJECTS 0xFFFF0000
#define PALETTES_ALL (PALETTES_BG | PALETTES_OBJECTS)
@ -24,6 +26,11 @@
#define OBJ_PLTT_ID(n) (OBJ_PLTT_OFFSET + PLTT_ID(n))
#define OBJ_PLTT_ID2(n) (PLTT_ID((n) + 16))
// Used to determine whether a sprite palette tag
// should be excluded from time (and weather) blending
#define BLEND_IMMUNE_FLAG (1 << 15)
#define IS_BLEND_IMMUNE_TAG(tag) ((tag) & BLEND_IMMUNE_FLAG)
enum
{
FAST_FADE_IN_FROM_WHITE,

View File

@ -34,7 +34,7 @@ static const u8 sHappyMsg11[] = _("Your POKéMON has caught the scent of\nsmoke.
static const u8 sHappyMsg12[] = _("{STR_VAR_1} is poking at your belly.");
static const u8 sHappyMsg13[] = _("Your POKéMON stretched out its body\nand is relaxing.");
static const u8 sHappyMsg14[] = _("{STR_VAR_1} looks like it wants to\nlead!");
static const u8 sHappyMsg15[] = _("{STR_VAR_1} is doing it's best to\nkeep up with you.");
static const u8 sHappyMsg15[] = _("{STR_VAR_1} is doing its best to\nkeep up with you.");
static const u8 sHappyMsg16[] = _("{STR_VAR_1} is happily cuddling up\nto you!");
static const u8 sHappyMsg17[] = _("{STR_VAR_1} is full of life!");
static const u8 sHappyMsg18[] = _("{STR_VAR_1} seems to be very happy!");
@ -134,7 +134,7 @@ const struct FollowerMsgInfo gFollowerUpsetMessages[] = {
// Unconditional angry messages
static const u8 sAngryMsg00[] = _("{STR_VAR_1} let out a roar!");
static const u8 sAngryMsg01[] = _("{STR_VAR_1} is making a face like\nits angry!");
static const u8 sAngryMsg01[] = _("{STR_VAR_1} is making a face like\nit's angry!");
static const u8 sAngryMsg02[] = _("{STR_VAR_1} seems to be angry for\nsome reason.");
static const u8 sAngryMsg03[] = _("Your POKéMON turned to face the\nother way, showing a defiant face.");
static const u8 sAngryMsg04[] = _("{STR_VAR_1} cried out.");

View File

@ -2254,7 +2254,9 @@ bool32 CheckMsgCondition(const struct MsgCondition *cond, struct Pokemon *mon, u
case MSG_COND_MUSIC:
return (cond->data.raw == GetCurrentMapMusic());
case MSG_COND_TIME_OF_DAY:
return (cond->data.raw == gTimeOfDay);
// Must match time of day, have natural light on the map,
// and not have weather that obscures the sky
return (cond->data.raw == gTimeOfDay && MapHasNaturalLight(gMapHeader.mapType) && GetCurrentWeather() < WEATHER_RAIN);
case MSG_COND_NEAR_MB:
multi = FindMetatileBehaviorWithinRange(
obj->currentCoords.x, obj->currentCoords.y,

View File

@ -64,6 +64,7 @@
#include "constants/battle_frontier.h"
#include "constants/weather.h"
#include "constants/metatile_labels.h"
#include "constants/rgb.h"
#include "palette.h"
#define TAG_ITEM_ICON 5500
@ -3395,7 +3396,7 @@ void SetDeoxysRockPalette(void)
u32 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE);
LoadPalette(&sDeoxysRockPalettes[(u8)VarGet(VAR_DEOXYS_ROCK_LEVEL)], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4));
// Set faded to all black, weather blending handled during fade-in
CpuFill16(0, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], 32);
CpuFill16(RGB_BLACK, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], PLTT_SIZE_4BPP);
}
void SetPCBoxToSendMon(u8 boxId)

View File

@ -495,7 +495,7 @@ static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex)
{
// don't blend special palettes immune to blending
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE ||
(curPalIndex >= 16 && GetSpritePaletteTagByPaletteNum(curPalIndex - 16) >> 15))
(curPalIndex >= 16 && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(curPalIndex - 16))))
{
// No palette change.
palOffset += 16;
@ -684,7 +684,7 @@ static void ApplyFogBlend(u8 blendCoeff, u16 blendColor)
CpuFastCopy(gPlttBufferUnfaded, gPlttBufferFaded, PLTT_BUFFER_SIZE * 2);
UpdatePalettesWithTime(PALETTES_ALL);
// Then blend tile palettes [0, 12] faded->faded with fadeIn color
BlendPalettesFine(0x1FFF, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
BlendPalettesFine(PALETTES_MAP, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
// Do fog blending on marked sprite palettes
for (curPalIndex = 16; curPalIndex < 32; curPalIndex++) {
@ -708,7 +708,7 @@ static bool8 LightenSpritePaletteInFog(u8 paletteIndex)
{
u16 i;
if (paletteIndex >= 16 && (GetSpritePaletteTagByPaletteNum(i - 16) >> 15)) // don't blend specialpalette tags
if (paletteIndex >= 16 && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteIndex - 16)))
return FALSE;
for (i = 0; i < gWeatherPtr->lightenedFogSpritePalsCount; i++)

View File

@ -1386,20 +1386,20 @@ static void DestroyFogHorizontalSprites(void);
// Updates just the color of shadows to match special weather blending
u8 UpdateShadowColor(u16 color) {
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
u16 ALIGNED(4) tempBuffer[16];
u16 blendedColor;
if (paletteNum != 0xFF) {
u16 index = (paletteNum+16)*16+SHADOW_COLOR_INDEX;
gPlttBufferUnfaded[index] = gPlttBufferFaded[index] = color;
// Copy to temporary buffer, blend, and keep just the shadow color index
CpuFastCopy(&gPlttBufferFaded[index-SHADOW_COLOR_INDEX], tempBuffer, 32);
UpdateSpritePaletteWithTime(paletteNum);
blendedColor = gPlttBufferFaded[index];
CpuFastCopy(tempBuffer, &gPlttBufferFaded[index-SHADOW_COLOR_INDEX], 32);
gPlttBufferFaded[index] = blendedColor;
}
return paletteNum;
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
u16 ALIGNED(4) tempBuffer[16];
u16 blendedColor;
if (paletteNum < 16) {
u16 index = OBJ_PLTT_ID(paletteNum)+SHADOW_COLOR_INDEX;
gPlttBufferUnfaded[index] = gPlttBufferFaded[index] = color;
// Copy to temporary buffer, blend, and keep just the shadow color index
CpuFastCopy(&gPlttBufferFaded[index-SHADOW_COLOR_INDEX], tempBuffer, PLTT_SIZE_4BPP);
UpdateSpritePaletteWithTime(paletteNum);
blendedColor = gPlttBufferFaded[index];
CpuFastCopy(tempBuffer, &gPlttBufferFaded[index-SHADOW_COLOR_INDEX], PLTT_SIZE_4BPP);
gPlttBufferFaded[index] = blendedColor;
}
return paletteNum;
}
void FogHorizontal_InitVars(void)

View File

@ -55,7 +55,7 @@ static const u8* const sFearTexts[] = {sCondMsg29, sCondMsg30, NULL};
static const u8 sCondMsg31[] = _("{STR_VAR_1} is taking shelter in the\ngrass from the rain.");
static const u8 sCondMsg32[] = _("{STR_VAR_1} seems very cold.");
static const u8 sCondMsg33[] = _("{STR_VAR_1} is staring at the sea.");
static const u8 sCondMsg34[] = _("Your pokemon is staring intently at\nthe sea!");
static const u8 sCondMsg34[] = _("Your POKéMON is staring intently at\nthe sea!");
static const u8 sCondMsg35[] = _("{STR_VAR_1} is looking at the\nsurging sea.");
static const u8* const sSeaTexts[] = {sCondMsg33, sCondMsg34, sCondMsg35, NULL};
static const u8 sCondMsg36[] = _("{STR_VAR_1} is listening to the\nsound of the waterfall.");

View File

@ -1473,9 +1473,9 @@ void CB1_Overworld(void)
const struct BlendSettings gTimeOfDayBlend[] =
{
[TIME_OF_DAY_NIGHT] = {.coeff = 10, .blendColor = TINT_NIGHT, .isTint = TRUE},
[TIME_OF_DAY_TWILIGHT] = {.coeff = 4, .blendColor = 0xA8B0E0, .isTint = TRUE},
[TIME_OF_DAY_DAY] = {.coeff = 0, .blendColor = 0},
[TIME_OF_DAY_NIGHT] = {.coeff = 10, .blendColor = TINT_NIGHT, .isTint = TRUE},
[TIME_OF_DAY_TWILIGHT] = {.coeff = 4, .blendColor = 0xA8B0E0, .isTint = TRUE},
[TIME_OF_DAY_DAY] = {.coeff = 0, .blendColor = 0},
};
u8 UpdateTimeOfDay(void) {
@ -1523,8 +1523,12 @@ u8 UpdateTimeOfDay(void) {
}
bool8 MapHasNaturalLight(u8 mapType) { // Whether a map type is naturally lit/outside
return mapType == MAP_TYPE_TOWN || mapType == MAP_TYPE_CITY || mapType == MAP_TYPE_ROUTE
|| mapType == MAP_TYPE_OCEAN_ROUTE;
return (
mapType == MAP_TYPE_TOWN
|| mapType == MAP_TYPE_CITY
|| mapType == MAP_TYPE_ROUTE
|| mapType == MAP_TYPE_OCEAN_ROUTE
);
}
// Update & mix day / night bg palettes (into unfaded)
@ -1536,7 +1540,7 @@ void UpdateAltBgPalettes(u16 palettes) {
return;
palettes &= ~((1 << NUM_PALS_IN_PRIMARY) - 1) | primary->swapPalettes;
palettes &= ((1 << NUM_PALS_IN_PRIMARY) - 1) | (secondary->swapPalettes << NUM_PALS_IN_PRIMARY);
palettes &= 0x1FFE; // don't blend palette 0, [13,15]
palettes &= PALETTES_MAP ^ (1 << 0); // don't blend palette 0, [13,15]
palettes >>= 1; // start at palette 1
if (!palettes)
return;
@ -1553,40 +1557,42 @@ void UpdateAltBgPalettes(u16 palettes) {
}
void UpdatePalettesWithTime(u32 palettes) {
if (MapHasNaturalLight(gMapHeader.mapType)) {
u32 i;
u32 mask = 1 << 16;
if (palettes >= 0x10000)
for (i = 0; i < 16; i++, mask <<= 1)
if (GetSpritePaletteTagByPaletteNum(i) >> 15) // Don't blend special sprite palette tags
palettes &= ~(mask);
if (MapHasNaturalLight(gMapHeader.mapType)) {
u32 i;
u32 mask = 1 << 16;
if (palettes >= (1 << 16))
for (i = 0; i < 16; i++, mask <<= 1)
if (IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(i)))
palettes &= ~(mask);
palettes &= 0xFFFF1FFF; // Don't blend UI BG palettes [13,15]
palettes &= PALETTES_MAP | PALETTES_OBJECTS; // Don't blend UI pals
if (!palettes)
return;
TimeMixPalettes(palettes,
gPlttBufferUnfaded,
gPlttBufferFaded,
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
currentTimeBlend.weight);
}
return;
TimeMixPalettes(
palettes,
gPlttBufferUnfaded,
gPlttBufferFaded,
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
currentTimeBlend.weight
);
}
}
u8 UpdateSpritePaletteWithTime(u8 paletteNum) {
if (MapHasNaturalLight(gMapHeader.mapType)) {
u16 offset;
if (GetSpritePaletteTagByPaletteNum(paletteNum) >> 15)
return paletteNum;
offset = (paletteNum + 16) << 4;
TimeMixPalettes(1,
gPlttBufferUnfaded + offset,
gPlttBufferFaded + offset,
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
currentTimeBlend.weight);
}
return paletteNum;
if (MapHasNaturalLight(gMapHeader.mapType)) {
if (IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteNum)))
return paletteNum;
TimeMixPalettes(
1,
&gPlttBufferUnfaded[OBJ_PLTT_ID(paletteNum)],
&gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)],
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
currentTimeBlend.weight
);
}
return paletteNum;
}
static void OverworldBasic(void)
@ -1602,19 +1608,20 @@ static void OverworldBasic(void)
DoScheduledBgTilemapCopiesToVram();
// Every minute if no palette fade is active, update TOD blending as needed
if (!gPaletteFade.active && ++gTimeUpdateCounter >= 3600) {
struct TimeBlendSettings cachedBlend = {
.time0 = currentTimeBlend.time0,
.time1 = currentTimeBlend.time1,
.weight = currentTimeBlend.weight,
};
gTimeUpdateCounter = 0;
UpdateTimeOfDay();
if (cachedBlend.time0 != currentTimeBlend.time0
|| cachedBlend.time1 != currentTimeBlend.time1
|| cachedBlend.weight != currentTimeBlend.weight) {
struct TimeBlendSettings cachedBlend = {
.time0 = currentTimeBlend.time0,
.time1 = currentTimeBlend.time1,
.weight = currentTimeBlend.weight,
};
gTimeUpdateCounter = 0;
UpdateTimeOfDay();
if (cachedBlend.time0 != currentTimeBlend.time0
|| cachedBlend.time1 != currentTimeBlend.time1
|| cachedBlend.weight != currentTimeBlend.weight)
{
UpdateAltBgPalettes(PALETTES_BG);
UpdatePalettesWithTime(PALETTES_ALL);
}
}
}
}

View File

@ -515,25 +515,25 @@ static u8 UpdateTimeOfDayPaletteFade(void)
u32 i;
u32 j = 1;
for (i = 0; i < 16; i++, j <<= 1) { // Mask out palettes that should not be light blended
if ((selectedPalettes & j) && !(GetSpritePaletteTagByPaletteNum(i) >> 15))
timePalettes |= j;
if ((selectedPalettes & j) && !IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(i)))
timePalettes |= j;
}
} else { // tile palettes, don't blend [13, 15]
timePalettes = selectedPalettes & 0x1FFF;
timePalettes = selectedPalettes & PALETTES_MAP;
}
TimeMixPalettes(timePalettes, src, dst, gPaletteFade.bld0, gPaletteFade.bld1, gPaletteFade.weight);
// palettes that were not blended above must be copied through
if ((copyPalettes = ~timePalettes)) {
u16 * src1 = src;
u16 * dst1 = dst;
while (copyPalettes) {
if (copyPalettes & 1)
CpuFastCopy(src1, dst1, 32);
copyPalettes >>= 1;
src1 += 16;
dst1 += 16;
}
u16 * src1 = src;
u16 * dst1 = dst;
while (copyPalettes) {
if (copyPalettes & 1)
CpuFastCopy(src1, dst1, 32);
copyPalettes >>= 1;
src1 += 16;
dst1 += 16;
}
}
// Then, blend from faded->faded with native BlendPalettes
@ -1330,58 +1330,59 @@ void TintPalette_CustomTone(u16 *palette, u16 count, u16 rTone, u16 gTone, u16 b
// Tints from Unfaded to Faded, using a 15-bit GBA color
void TintPalette_RGB_Copy(u16 palOffset, u32 blendColor) {
s32 newR, newG, newB, rTone, gTone, bTone;
u16 * src = gPlttBufferUnfaded + palOffset;
u16 * dst = gPlttBufferFaded + palOffset;
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
u16 *srcEnd = src + 16;
u16 altBlendIndices = *dst++ = *src++; // color 0 is copied through unchanged
u32 altBlendColor;
newR = ((blendColor << 27) >> 27) << 3;
newG = ((blendColor << 22) >> 27) << 3;
newB = ((blendColor << 17) >> 27) << 3;
if (altBlendIndices >> 15) { // High bit set; bitmask of which colors to alt-blend
// Note that bit 0 of altBlendIndices specifies color 1
altBlendColor = src[14]; // color 15
if (altBlendColor >> 15) { // Set alternate blend color
rTone = ((altBlendColor << 27) >> 27) << 3;
gTone = ((altBlendColor << 22) >> 27) << 3;
bTone = ((altBlendColor << 17) >> 27) << 3;
} else { // Set default blend color
rTone = ((defaultBlendColor << 27) >> 27) << 3;
gTone = ((defaultBlendColor << 22) >> 27) << 3;
bTone = ((defaultBlendColor << 17) >> 27) << 3;
s32 newR, newG, newB, rTone, gTone, bTone;
u16 * src = gPlttBufferUnfaded + palOffset;
u16 * dst = gPlttBufferFaded + palOffset;
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
u16 *srcEnd = src + 16;
u16 altBlendIndices = *dst++ = *src++; // color 0 is copied through unchanged
u32 altBlendColor;
newR = ((blendColor << 27) >> 27) << 3;
newG = ((blendColor << 22) >> 27) << 3;
newB = ((blendColor << 17) >> 27) << 3;
if (altBlendIndices >> 15) { // High bit set; bitmask of which colors to alt-blend
// Note that bit 0 of altBlendIndices specifies color 1
altBlendColor = src[14]; // color 15
if (altBlendColor >> 15) { // Set alternate blend color
rTone = ((altBlendColor << 27) >> 27) << 3;
gTone = ((altBlendColor << 22) >> 27) << 3;
bTone = ((altBlendColor << 17) >> 27) << 3;
} else { // Set default blend color
rTone = ((defaultBlendColor << 27) >> 27) << 3;
gTone = ((defaultBlendColor << 22) >> 27) << 3;
bTone = ((defaultBlendColor << 17) >> 27) << 3;
}
} else {
altBlendIndices = 0;
}
} else {
altBlendIndices = 0;
}
while (src != srcEnd) {
u32 srcColor = *src;
s32 r = (srcColor << 27) >> 27;
s32 g = (srcColor << 22) >> 27;
s32 b = (srcColor << 17) >> 27;
if (altBlendIndices & 1) {
r = (u16)((rTone * r)) >> 8;
g = (u16)((gTone * g)) >> 8;
b = (u16)((bTone * b)) >> 8;
} else { // Use provided blend color
r = (u16)((newR * r)) >> 8;
g = (u16)((newG * g)) >> 8;
b = (u16)((newB * b)) >> 8;
while (src != srcEnd) {
u32 srcColor = *src;
s32 r = (srcColor << 27) >> 27;
s32 g = (srcColor << 22) >> 27;
s32 b = (srcColor << 17) >> 27;
if (altBlendIndices & 1) {
r = (u16)((rTone * r)) >> 8;
g = (u16)((gTone * g)) >> 8;
b = (u16)((bTone * b)) >> 8;
} else { // Use provided blend color
r = (u16)((newR * r)) >> 8;
g = (u16)((newG * g)) >> 8;
b = (u16)((newB * b)) >> 8;
}
if (r > 31)
r = 31;
if (g > 31)
g = 31;
if (b > 31)
b = 31;
src++;
*dst++ = RGB2(r, g, b);
altBlendIndices >>= 1;
}
if (r > 31)
r = 31;
if (g > 31)
g = 31;
if (b > 31)
b = 31;
src++;
*dst++ = RGB2(r, g, b);
altBlendIndices >>= 1;
}
}
#define tCoeff data[0]

View File

@ -385,8 +385,7 @@ void UpdatePulseBlend(struct PulseBlend *pulseBlend)
if (--pulseBlendPalette->delayCounter == 0xFF)
{
pulseBlendPalette->delayCounter = pulseBlendPalette->pulseBlendSettings.delay;
// TODO: Optimize pulse blending
CpuFastCopy(gPlttBufferUnfaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, gPlttBufferFaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, 32);
CpuFastCopy(gPlttBufferUnfaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, gPlttBufferFaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, PLTT_SIZE_4BPP);
UpdatePalettesWithTime(1 << (pulseBlendPalette->pulseBlendSettings.paletteOffset >> 4));
// pulseBlendSettings has a numColors field, but it is only ever set to 16 (for mirage tower)
// So, it's ok to use the fine blending here which blends the entire palette