Added inter-time-of-day blending.
This commit is contained in:
parent
3bd46b5b7a
commit
22c429d0d6
4 changed files with 181 additions and 52 deletions
|
@ -44,6 +44,12 @@ struct LinkPlayerObjectEvent
|
|||
u8 movementMode;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) TimeBlendSettings {
|
||||
u16 weight:9;
|
||||
u16 time1:3;
|
||||
u16 time0:3;
|
||||
};
|
||||
|
||||
// Exported RAM declarations
|
||||
extern struct WarpData gLastUsedWarp;
|
||||
extern struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4];
|
||||
|
|
|
@ -77,9 +77,9 @@ void BlendPalettes(u32 selectedPalettes, u8 coeff, u16 color);
|
|||
void BlendPalettesUnfaded(u32, u8, u16);
|
||||
void BlendPalettesGradually(u32 selectedPalettes, s8 delay, u8 coeff, u8 coeffTarget, u16 color, u8 priority, u8 id);
|
||||
void AveragePalettes(u16 *palette0, u16* palette1, u16* dest, u16 weight);
|
||||
void TimeBlendPalette(u16 palOffset, u16 numEntries, u8 coeff, u16 blendColor);
|
||||
void TimeBlendPalette(u16 palOffset, u32 coeff, u32 blendColor);
|
||||
void TintPalette_RGB_Copy(u16 palOffset, u16 numEntries, u8 coeff, u16 blendColor);
|
||||
void TimeBlendPalettes(u32 palettes, u8 coeff, u16 color);
|
||||
void TimeBlendPalettes(u32 palettes, u32 coeff, u32 blendColor);
|
||||
void TintPalette_GrayScale(u16 *palette, u16 count);
|
||||
void TintPalette_GrayScale2(u16 *palette, u16 count);
|
||||
void TintPalette_SepiaTone(u16 *palette, u16 count);
|
||||
|
|
|
@ -186,7 +186,9 @@ static u16 (*sPlayerKeyInterceptCallback)(u32);
|
|||
static bool8 sReceivingFromLink;
|
||||
static u8 sRfuKeepAliveTimer;
|
||||
|
||||
u8 static gTimeOfDayState;
|
||||
static u8 gTimeOfDayState;
|
||||
static u8 timeCounter;
|
||||
static struct TimeBlendSettings currentTimeBlend;
|
||||
|
||||
// IWRAM common
|
||||
u16 *gBGTilemapBuffers1;
|
||||
|
@ -1472,12 +1474,39 @@ static const struct TimeOfDayBlend sTimeOfDayBlendVars[] =
|
|||
};
|
||||
|
||||
u8 UpdateTimeOfDay(void) {
|
||||
s8 hours, minutes;
|
||||
RtcCalcLocalTime();
|
||||
if (gLocalTime.hours >= 20 || gLocalTime.hours < 4)
|
||||
return gTimeOfDay = TIME_OF_DAY_NIGHT;
|
||||
else if (gLocalTime.hours >= 10 && gLocalTime.hours < 20)
|
||||
hours = gLocalTime.hours;
|
||||
minutes = gLocalTime.minutes;
|
||||
if (hours >= 22 || hours < 4) {
|
||||
currentTimeBlend.weight = 256;
|
||||
return gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_NIGHT;
|
||||
} else if (hours >= 4 && hours < 7) { // night->twilight
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_NIGHT;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_TWILIGHT;
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 4) * 60 + minutes) / ((7-4)*60);
|
||||
return gTimeOfDay = TIME_OF_DAY_DAY;
|
||||
return gTimeOfDay = TIME_OF_DAY_TWILIGHT;
|
||||
} else if (hours >= 7 && hours < 10) { // twilight->day
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_TWILIGHT;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_DAY;
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 7) * 60 + minutes) / ((10-7)*60);
|
||||
return gTimeOfDay = TIME_OF_DAY_DAY;
|
||||
} else if (hours >= 10 && hours < 18) { // day
|
||||
currentTimeBlend.weight = 256;
|
||||
return gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_DAY;
|
||||
} else if (hours >= 18 && hours < 20) { // day->twilight
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_DAY;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_TWILIGHT;
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 18) * 60 + minutes) / ((20-18)*60);
|
||||
return gTimeOfDay = TIME_OF_DAY_TWILIGHT;
|
||||
} else if (hours >= 20 && hours < 22) { // twilight->night
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_TWILIGHT;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_NIGHT;
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 20) * 60 + minutes) / ((22-20)*60);
|
||||
return gTimeOfDay = TIME_OF_DAY_NIGHT;
|
||||
} else { // This should never occur
|
||||
return TIME_OF_DAY_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static bool8 MapHasNaturalLight(u8 mapType) { // Weather a map type is naturally lit/outside
|
||||
|
@ -1485,7 +1514,7 @@ static bool8 MapHasNaturalLight(u8 mapType) { // Weather a map type is naturally
|
|||
|| mapType == MAP_TYPE_OCEAN_ROUTE;
|
||||
}
|
||||
|
||||
static bool8 FadePalettesWithTime(void) {
|
||||
static bool8 FadePalettesWithTime(void) { // Only used to fade back in
|
||||
gTimeOfDayState = 0;
|
||||
gTimeOfDay = UpdateTimeOfDay();
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
|
@ -1495,8 +1524,7 @@ static bool8 FadePalettesWithTime(void) {
|
|||
}
|
||||
|
||||
void UpdatePalettesWithTime(u32 palettes) {
|
||||
// Only blend if not transitioning between times and the map type allows
|
||||
if (gTimeOfDayState == 0 && MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
u8 i, j;
|
||||
u16 tempPaletteBuffer[16];
|
||||
for (i = 0; i < 16; i++) {
|
||||
|
@ -1509,10 +1537,14 @@ void UpdatePalettesWithTime(u32 palettes) {
|
|||
return;
|
||||
for (i = 0; palettes; i++) {
|
||||
if (palettes & 1) {
|
||||
TimeBlendPalette(i*16, 16, sTimeOfDayBlendVars[gTimeOfDay].coeff, sTimeOfDayBlendVars[gTimeOfDay].blendColor);
|
||||
TimeBlendPalette(i*16, sTimeOfDayBlendVars[currentTimeBlend.time0].coeff, sTimeOfDayBlendVars[currentTimeBlend.time0].blendColor);
|
||||
if (currentTimeBlend.weight == 256) {
|
||||
palettes >>= 1;
|
||||
continue;
|
||||
}
|
||||
CpuFastCopy(&gPlttBufferFaded[i*16], tempPaletteBuffer, 32);
|
||||
TimeBlendPalette(i*16, 16, sTimeOfDayBlendVars[TIME_OF_DAY_TWILIGHT].coeff, sTimeOfDayBlendVars[TIME_OF_DAY_TWILIGHT].blendColor);
|
||||
AveragePalettes(tempPaletteBuffer, &gPlttBufferFaded[i*16], &gPlttBufferFaded[i*16], 256);
|
||||
TimeBlendPalette(i*16, sTimeOfDayBlendVars[currentTimeBlend.time1].coeff, sTimeOfDayBlendVars[currentTimeBlend.time1].blendColor);
|
||||
AveragePalettes(tempPaletteBuffer, &gPlttBufferFaded[i*16], &gPlttBufferFaded[i*16], currentTimeBlend.weight);
|
||||
}
|
||||
palettes >>= 1;
|
||||
}
|
||||
|
@ -1535,6 +1567,19 @@ static void OverworldBasic(void)
|
|||
UpdatePaletteFade();
|
||||
UpdateTilesetAnimations();
|
||||
DoScheduledBgTilemapCopiesToVram();
|
||||
if (!(gPaletteFade.active || (timeCounter++ % 60))) {
|
||||
struct TimeBlendSettings cachedBlend = {
|
||||
.time0 = currentTimeBlend.time0,
|
||||
.time1 = currentTimeBlend.time1,
|
||||
.weight = currentTimeBlend.weight,
|
||||
};
|
||||
timeCounter = 0;
|
||||
UpdateTimeOfDay();
|
||||
if (cachedBlend.time0 != currentTimeBlend.time0
|
||||
|| cachedBlend.time1 != currentTimeBlend.time1
|
||||
|| cachedBlend.weight != currentTimeBlend.weight)
|
||||
UpdatePalettesWithTime(0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
// This CB2 is used when starting
|
||||
|
@ -1545,9 +1590,7 @@ void CB2_OverworldBasic(void)
|
|||
|
||||
void CB2_Overworld(void)
|
||||
{
|
||||
u32 *debugPtr = (u32*) 0x0203de00;
|
||||
bool32 fading = (gPaletteFade.active != 0);
|
||||
*debugPtr = (u32) &gTimeOfDay;
|
||||
if (fading)
|
||||
SetVBlankCallback(NULL);
|
||||
OverworldBasic();
|
||||
|
|
154
src/palette.c
154
src/palette.c
|
@ -496,13 +496,13 @@ static u8 UpdateTimeOfDayPaletteFade(void)
|
|||
if (gPaletteFade.yDec) {
|
||||
if (gPaletteFade.objPaletteToggle) { // sprite palettes
|
||||
if (gPaletteFade.y >= gPaletteFade.targetY || GetSpritePaletteTagByPaletteNum(paletteNum) & 0x8000)
|
||||
TimeBlendPalette(paletteOffset, 16, gPaletteFade.y, gPaletteFade.blendColor);
|
||||
TimeBlendPalette(paletteOffset, gPaletteFade.y, gPaletteFade.blendColor);
|
||||
// tile palettes
|
||||
} else if (gPaletteFade.y >= gPaletteFade.targetY || (paletteNum >= 13 && paletteNum <= 15)) {
|
||||
TimeBlendPalette(paletteOffset, 16, gPaletteFade.y, gPaletteFade.blendColor);
|
||||
TimeBlendPalette(paletteOffset, gPaletteFade.y, gPaletteFade.blendColor);
|
||||
}
|
||||
} else {
|
||||
TimeBlendPalette(paletteOffset, 16, gPaletteFade.y, gPaletteFade.blendColor);
|
||||
TimeBlendPalette(paletteOffset, gPaletteFade.y, gPaletteFade.blendColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1010,45 +1010,125 @@ void AveragePalettes(u16 *palette0, u16* palette1, u16* dest, u16 weight) {
|
|||
#define DEFAULT_LIGHT_COLOR 0x3f9f
|
||||
|
||||
// Like BlendPalette, but ignores blendColor if the transparency high bit is set
|
||||
void TimeBlendPalette(u16 palOffset, u16 numEntries, u8 coeff, u16 blendColor) {
|
||||
u16 i;
|
||||
u16 defaultBlendColor = DEFAULT_LIGHT_COLOR;
|
||||
s8 r, g, b;
|
||||
struct PlttData *data2 = (struct PlttData *)&blendColor;
|
||||
struct PlttData *data3;
|
||||
struct PlttData *blendData;
|
||||
u16 altBlendIndices = 0;
|
||||
for (i = 0; i < numEntries; i++) {
|
||||
u16 index = i + palOffset;
|
||||
struct PlttData *data1 = (struct PlttData *)&gPlttBufferUnfaded[index];
|
||||
if (i == 0) {
|
||||
if (data1->unused_15) { // Color 0 is a bitmask for which colors to blend; color 15 is the alt blend color
|
||||
gPlttBufferFaded[index] = gPlttBufferUnfaded[index];
|
||||
altBlendIndices = gPlttBufferUnfaded[index] << 1; // bit 0 specifies color 1, etc.
|
||||
data3 = (struct PlttData *)&gPlttBufferUnfaded[index+15];
|
||||
if (!data3->unused_15) // use default blend color instead
|
||||
data3 = (struct PlttData *)&defaultBlendColor;
|
||||
}
|
||||
continue;
|
||||
// Optimization help by lucktyphlosion
|
||||
void TimeBlendPalette(u16 palOffset, u32 coeff, u32 blendColor) {
|
||||
s32 newR, newG, newB, defR, defG, defB;
|
||||
u16 * palDataSrc = gPlttBufferUnfaded + palOffset;
|
||||
u16 * palDataDst = gPlttBufferFaded + palOffset;
|
||||
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
|
||||
u16 *palDataSrcEnd = palDataSrc + 16;
|
||||
u16 altBlendIndices = *palDataDst++ = *palDataSrc++; // color 0 is copied through unchanged
|
||||
u32 altBlendColor;
|
||||
|
||||
coeff *= 2;
|
||||
newR = (blendColor << 27) >> 27;
|
||||
newG = (blendColor << 22) >> 27;
|
||||
newB = (blendColor << 17) >> 27;
|
||||
|
||||
if (altBlendIndices >> 15) { // High bit set; bitmask of which colors to alt-blend
|
||||
// Note that bit 0 of altBlendIndices specifies color 1
|
||||
altBlendColor = palDataSrc[14]; // color 15
|
||||
if (altBlendColor >> 15) { // Set alternate blend color
|
||||
defR = (altBlendColor << 27) >> 27;
|
||||
defG = (altBlendColor << 22) >> 27;
|
||||
defB = (altBlendColor << 17) >> 27;
|
||||
} else { // Set default blend color
|
||||
defR = (defaultBlendColor << 27) >> 27;
|
||||
defG = (defaultBlendColor << 22) >> 27;
|
||||
defB = (defaultBlendColor << 17) >> 27;
|
||||
}
|
||||
r = data1->r;
|
||||
g = data1->g;
|
||||
b = data1->b;
|
||||
blendData = (altBlendIndices && altBlendIndices & (1 << i)) ? data3 : data2;
|
||||
gPlttBufferFaded[index] = RGB(r + (((blendData->r - r) * coeff) >> 4),
|
||||
g + (((blendData->g - g) * coeff) >> 4),
|
||||
b + (((blendData->b - b) * coeff) >> 4));
|
||||
} else {
|
||||
altBlendIndices = 0;
|
||||
}
|
||||
while (palDataSrc != palDataSrcEnd) {
|
||||
u32 palDataSrcColor = *palDataSrc;
|
||||
s32 r = (palDataSrcColor << 27) >> 27;
|
||||
s32 g = (palDataSrcColor << 22) >> 27;
|
||||
s32 b = (palDataSrcColor << 17) >> 27;
|
||||
|
||||
if (altBlendIndices & 1) {
|
||||
*palDataDst = ((r + (((defR - r) * coeff) >> 5)) << 0)
|
||||
| ((g + (((defG - g) * coeff) >> 5)) << 5)
|
||||
| ((b + (((defB - b) * coeff) >> 5)) << 10);
|
||||
} else { // Use provided blend color
|
||||
*palDataDst = ((r + (((newR - r) * coeff) >> 5)) << 0)
|
||||
| ((g + (((newG - g) * coeff) >> 5)) << 5)
|
||||
| ((b + (((newB - b) * coeff) >> 5)) << 10);
|
||||
}
|
||||
palDataSrc++;
|
||||
palDataDst++;
|
||||
altBlendIndices >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply time effect to a series of palettes
|
||||
void TimeBlendPalettes(u32 palettes, u8 coeff, u16 color) {
|
||||
u16 paletteOffset;
|
||||
for (paletteOffset = 0; palettes; paletteOffset += 16) {
|
||||
if (palettes & 1)
|
||||
TimeBlendPalette(paletteOffset, 16, coeff, color);
|
||||
void TimeBlendPalettes(u32 palettes, u32 coeff, u32 blendColor) {
|
||||
s32 newR, newG, newB, defR, defG, defB, altR, altG, altB;
|
||||
u16 * palDataSrc;
|
||||
u16 * palDataDst;
|
||||
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
|
||||
|
||||
if (!palettes)
|
||||
return;
|
||||
|
||||
coeff *= 2;
|
||||
newR = (blendColor << 27) >> 27;
|
||||
newG = (blendColor << 22) >> 27;
|
||||
newB = (blendColor << 17) >> 27;
|
||||
defR = (defaultBlendColor << 27) >> 27;
|
||||
defG = (defaultBlendColor << 22) >> 27;
|
||||
defB = (defaultBlendColor << 17) >> 27;
|
||||
palDataSrc = gPlttBufferUnfaded;
|
||||
palDataDst = gPlttBufferFaded;
|
||||
|
||||
do {
|
||||
if (palettes & 1) {
|
||||
u16 *palDataSrcEnd = palDataSrc + 16;
|
||||
u16 altBlendIndices = *palDataDst++ = *palDataSrc++; // color 0 is copied through
|
||||
u32 altBlendColor;
|
||||
if (altBlendIndices >> 15) { // High bit set; bitmask of which colors to alt-blend
|
||||
// Note that bit 0 of altBlendIndices specifies color 1
|
||||
altBlendColor = palDataSrc[14]; // color 15
|
||||
if (altBlendColor >> 15) { // Set alternate blend color
|
||||
altR = (altBlendColor << 27) >> 27;
|
||||
altG = (altBlendColor << 22) >> 27;
|
||||
altB = (altBlendColor << 17) >> 27;
|
||||
} else {
|
||||
altBlendColor = 0;
|
||||
}
|
||||
} else {
|
||||
altBlendIndices = 0;
|
||||
}
|
||||
while (palDataSrc != palDataSrcEnd) {
|
||||
u32 palDataSrcColor = *palDataSrc;
|
||||
s32 r = (palDataSrcColor << 27) >> 27;
|
||||
s32 g = (palDataSrcColor << 22) >> 27;
|
||||
s32 b = (palDataSrcColor << 17) >> 27;
|
||||
|
||||
if (altBlendIndices & 1) {
|
||||
if (altBlendColor) { // Use alternate blend color
|
||||
*palDataDst = ((r + (((altR - r) * coeff) >> 5)) << 0)
|
||||
| ((g + (((altG - g) * coeff) >> 5)) << 5)
|
||||
| ((b + (((altB - b) * coeff) >> 5)) << 10);
|
||||
} else { // Use default blend color
|
||||
*palDataDst = ((r + (((defR - r) * coeff) >> 5)) << 0)
|
||||
| ((g + (((defG - g) * coeff) >> 5)) << 5)
|
||||
| ((b + (((defB - b) * coeff) >> 5)) << 10);
|
||||
}
|
||||
} else { // Use provided blend color
|
||||
*palDataDst = ((r + (((newR - r) * coeff) >> 5)) << 0)
|
||||
| ((g + (((newG - g) * coeff) >> 5)) << 5)
|
||||
| ((b + (((newB - b) * coeff) >> 5)) << 10);
|
||||
}
|
||||
palDataSrc++;
|
||||
palDataDst++;
|
||||
altBlendIndices >>= 1;
|
||||
}
|
||||
} else {
|
||||
palDataSrc += 16;
|
||||
palDataDst += 16;
|
||||
}
|
||||
palettes >>= 1;
|
||||
}
|
||||
} while (palettes);
|
||||
}
|
||||
|
||||
void BlendPalettesUnfaded(u32 selectedPalettes, u8 coeff, u16 color)
|
||||
|
|
Loading…
Reference in a new issue