feat: overhaul cursed apple sprite with custom tile data, vibrant palette, and dynamic pulsing glow

This commit is contained in:
phillip committed 2026-10-03 21:02:59 +02:00
1 parent 60bf111400
commit 08a4b41280
4 files changed
+44 -25

No files matched your search

+34 -23
View File
@@ -100,33 +100,33 @@ void setup() {
consoleSelect(&topScreen);
dmaCopy(tilemapPal, SPRITE_PALETTE_SUB, tilemapPalLen);
dmaCopy(tilemapPal,SPRITE_PALETTE_SUB,tilemapPalLen);
// Setup vibrant base colors for the Cursed Apple sprite (neon electric purple with toxic green horn)
SPRITE_PALETTE_SUB[CURSE_PAL_OUTLINE] = RGB15(5, 0, 12); // Deep mystical dark purple outline
SPRITE_PALETTE_SUB[CURSE_PAL_FILL] = RGB15(22, 2, 28); // Vibrant Electric Purple
SPRITE_PALETTE_SUB[CURSE_PAL_GLOW] = RGB15(29, 6, 31); // Radiant Neon Magenta Glow
SPRITE_PALETTE_SUB[CURSE_PAL_CORE] = RGB15(31, 26, 31); // Glowing White-Pink Core
SPRITE_PALETTE_SUB[CURSE_PAL_LEAF] = RGB15(2, 31, 10); // Toxic Radioactive Neon Green
// Recolor a copy of the rotten-apple tile (shadow/outline/fill/rot-spots) into unused
// palette slots to make the "cursed" apple sprite, since all 12 tiles are already in use.
const uint16_t CURSE_PAL_SHADOW = 14;
const uint16_t CURSE_PAL_OUTLINE = 15;
const uint16_t CURSE_PAL_FILL = 16;
const uint16_t CURSE_PAL_GLOW = 17;
// 8x8 256-color tile data for Cursed Apple (vibrant electric purple apple with radioactive green horn & glowing core)
static const uint32_t CURSED_APPLE_TILE[16] = {
0x10000000, 0x00001414,
0x10101000, 0x00101014,
0x12111110, 0x10111112,
0x13121110, 0x10111112,
0x13131110, 0x10111112,
0x13121110, 0x10111211,
0x11111000, 0x00101111,
0x10100000, 0x00101000,
};
SPRITE_PALETTE_SUB[CURSE_PAL_SHADOW] = RGB15(9, 5, 12);
SPRITE_PALETTE_SUB[CURSE_PAL_OUTLINE] = RGB15(10, 0, 14);
SPRITE_PALETTE_SUB[CURSE_PAL_FILL] = RGB15(18, 0, 22);
SPRITE_PALETTE_SUB[CURSE_PAL_GLOW] = RGB15(28, 0, 24);
const auto *rottenTilePixels = static_cast<const uint8_t *>(get_sprite_pointer(11));
uint8_t cursedTilePixels[64];
for (int i = 0; i < 64; i++) {
switch (rottenTilePixels[i]) {
case 5: cursedTilePixels[i] = static_cast<uint8_t>(CURSE_PAL_SHADOW); break;
case 7: cursedTilePixels[i] = static_cast<uint8_t>(CURSE_PAL_OUTLINE); break;
case 10: cursedTilePixels[i] = static_cast<uint8_t>(CURSE_PAL_FILL); break;
case 12: cursedTilePixels[i] = static_cast<uint8_t>(CURSE_PAL_GLOW); break;
default: cursedTilePixels[i] = rottenTilePixels[i]; break;
}
// Copy cursed apple tile directly into allocated VRAM (32 halfwords)
auto *destAppleCursed = static_cast<uint16_t *>(renderAssets.gfx_apple_cursed);
const auto *srcAppleCursed = reinterpret_cast<const uint16_t *>(CURSED_APPLE_TILE);
for (size_t i = 0; i < 32; i++) {
destAppleCursed[i] = srcAppleCursed[i];
}
dmaCopy(cursedTilePixels, renderAssets.gfx_apple_cursed, 64);
audio_setup(audioContext);
@@ -138,6 +138,17 @@ void handle_vblank() {
consoleSelect(&topScreen);
draw_stats(gameState, renderAssets, internals, audio_is_music_enabled(audioContext), frame);
}
// Dynamic pulsing radioactive glow for Cursed Apples (smooth 60fps breathing)
const uint8_t pulse = (frame >> 2U) & 7U; // 8-step cycle
const uint8_t wave = (pulse < 4U) ? pulse : static_cast<uint8_t>(7U - pulse); // 0, 1, 2, 3, 3, 2, 1, 0
SPRITE_PALETTE_SUB[CURSE_PAL_FILL] = static_cast<uint16_t>(RGB15(20 + (wave * 3), 2 + wave, 26 + wave));
SPRITE_PALETTE_SUB[CURSE_PAL_GLOW] = static_cast<uint16_t>(RGB15(26 + wave, 6 + (wave * 4), 31));
SPRITE_PALETTE_SUB[CURSE_PAL_CORE] = (wave >= 2U)
? static_cast<uint16_t>(RGB15(31, 31, 31))
: static_cast<uint16_t>(RGB15(31, 22 + (wave * 3), 31));
SPRITE_PALETTE_SUB[CURSE_PAL_LEAF] = static_cast<uint16_t>(RGB15(2 + (wave * 2), 31, 10 + (wave * 3)));
oamUpdate(&oamSub);
//flashy_colors();
}