Added override table for standalone follower palettes.
This commit is contained in:
parent
4afb386ab4
commit
6bceacf403
4 changed files with 56 additions and 12 deletions
|
@ -8,6 +8,8 @@ extern u8 ALIGNED(4) gDecompressionBuffer[0x4000];
|
|||
void LZDecompressWram(const u32 *src, void *dest);
|
||||
void LZDecompressVram(const u32 *src, void *dest);
|
||||
|
||||
bool32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize);
|
||||
|
||||
u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src);
|
||||
void LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer);
|
||||
bool8 LoadCompressedSpriteSheetUsingHeap(const struct CompressedSpriteSheet *src);
|
||||
|
|
|
@ -426,6 +426,17 @@ const struct ObjectEventGraphicsInfo gCastformObjectGraphics[] =
|
|||
{TAG_NONE, OBJ_EVENT_PAL_TAG_CASTFORM_SNOWY, OBJ_EVENT_PAL_TAG_NONE, 512, 32, 32, 2, SHADOW_SIZE_M, FALSE, FALSE, TRACKS_NONE, &gObjectEventBaseOam_32x32, sOamTables_32x32, sAnimTable_Following, sPicTable_CastformSnowy, gDummySpriteAffineAnimTable},
|
||||
};
|
||||
|
||||
// Standalone follower palettes
|
||||
// If not NULL, entries here override the front-sprite-based pals
|
||||
// used by OBJ_EVENT_PAL_TAG_DYNAMIC
|
||||
// Palette data may be compressed, or not
|
||||
const void* const gFollowerPalettes[][2] =
|
||||
{
|
||||
// Must have at least one entry, or ARRAY_COUNT comparison fails
|
||||
// (SPECIES_NONE does not use OBJ_EVENT_PAL_TAG_DYNAMIC anyway)
|
||||
[SPECIES_NONE] = {gMonPalette_CircledQuestionMark, gMonShinyPalette_CircledQuestionMark},
|
||||
};
|
||||
|
||||
#if OW_MON_POKEBALLS
|
||||
|
||||
#define POKEBALL_GFX_INFO(NAME) \
|
||||
|
|
|
@ -19,6 +19,24 @@ void LZDecompressVram(const u32 *src, void *dest)
|
|||
LZ77UnCompVram(src, dest);
|
||||
}
|
||||
|
||||
// Checks if `ptr` is likely LZ77 data
|
||||
// Checks word-alignment, min/max size, and header byte
|
||||
bool32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize) {
|
||||
const u8 *data = ptr;
|
||||
u32 size;
|
||||
// Compressed data must be word aligned
|
||||
if (((u32)ptr) & 3)
|
||||
return FALSE;
|
||||
// Check LZ77 header byte
|
||||
// See https://problemkaputt.de/gbatek.htm#biosdecompressionfunctions
|
||||
if (data[0] != 0x10)
|
||||
return FALSE;
|
||||
|
||||
// Read 24-bit uncompressed size
|
||||
size = data[1] | (data[2] << 8) | (data[3] << 16);
|
||||
return (size >= minSize && size <= maxSize);
|
||||
}
|
||||
|
||||
u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src)
|
||||
{
|
||||
struct SpriteSheet dest;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "fieldmap.h"
|
||||
#include "follower_helper.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "graphics.h"
|
||||
#include "mauville_old_man.h"
|
||||
#include "metatile_behavior.h"
|
||||
#include "overworld.h"
|
||||
|
@ -189,7 +190,7 @@ static u8 DoJumpSpecialSpriteMovement(struct Sprite *);
|
|||
static void CreateLevitateMovementTask(struct ObjectEvent *);
|
||||
static void DestroyLevitateMovementTask(u8);
|
||||
static bool8 GetFollowerInfo(u16 *species, u8 *form, u8 *shiny);
|
||||
static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool8 shiny);
|
||||
static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny);
|
||||
static const struct ObjectEventGraphicsInfo * SpeciesToGraphicsInfo(u16 species, u8 form);
|
||||
static bool8 NpcTakeStep(struct Sprite *);
|
||||
static bool8 IsElevationMismatchAt(u8, s16, s16);
|
||||
|
@ -1698,7 +1699,7 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *),
|
|||
u16 species;
|
||||
u8 form;
|
||||
bool8 shiny;
|
||||
u8 paletteNum;
|
||||
u32 paletteNum;
|
||||
|
||||
spriteTemplate = Alloc(sizeof(struct SpriteTemplate));
|
||||
if (graphicsId == OBJ_EVENT_GFX_OW_MON && GetFollowerInfo(&species, &form, &shiny)) {
|
||||
|
@ -1715,9 +1716,8 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *),
|
|||
CopyObjectGraphicsInfoToSpriteTemplate(graphicsId, callback, spriteTemplate, &subspriteTables);
|
||||
|
||||
if (spriteTemplate->paletteTag == OBJ_EVENT_PAL_TAG_DYNAMIC) {
|
||||
const struct CompressedSpritePalette *spritePalette = &(shiny ? gMonShinyPaletteTable : gMonPaletteTable)[species];
|
||||
paletteNum = LoadDynamicFollowerPalette(species, form, shiny);
|
||||
spriteTemplate->paletteTag = spritePalette->tag;
|
||||
spriteTemplate->paletteTag = GetSpritePaletteTagByPaletteNum(paletteNum);
|
||||
} else if (spriteTemplate->paletteTag != TAG_NONE)
|
||||
LoadObjectEventPalette(spriteTemplate->paletteTag);
|
||||
|
||||
|
@ -1825,18 +1825,31 @@ static const struct ObjectEventGraphicsInfo * SpeciesToGraphicsInfo(u16 species,
|
|||
}
|
||||
|
||||
// Find, or load, the palette for the specified pokemon info
|
||||
static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool8 shiny) {
|
||||
static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny) {
|
||||
u32 paletteNum;
|
||||
// Note that the shiny palette tag is `species + SPECIES_SHINY_TAG`, which must be increased with more pokemon
|
||||
// so that palette tags do not overlap
|
||||
const struct CompressedSpritePalette *spritePalette = &(shiny ? gMonShinyPaletteTable : gMonPaletteTable)[species];
|
||||
if ((paletteNum = IndexOfSpritePaletteTag(spritePalette->tag)) == 0xFF) {
|
||||
// Load compressed palette
|
||||
LoadCompressedSpritePalette(spritePalette);
|
||||
paletteNum = IndexOfSpritePaletteTag(spritePalette->tag); // Tag is always present
|
||||
if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) // don't want to weather blend in fog
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
struct SpritePalette spritePalette = {.tag = shiny ? (species + SPECIES_SHINY_TAG) : species};
|
||||
// palette already loaded
|
||||
if ((paletteNum = IndexOfSpritePaletteTag(spritePalette.tag)) < 16)
|
||||
return paletteNum;
|
||||
|
||||
// Use matching front sprite's normal/shiny palettes
|
||||
spritePalette.data = (u16*)((shiny ? gMonShinyPaletteTable : gMonPaletteTable)[species].data);
|
||||
// Use standalone palette, unless entry is OOB or NULL (fallback to front-sprite-based)
|
||||
if (species < ARRAY_COUNT(gFollowerPalettes) && gFollowerPalettes[species][shiny & 1])
|
||||
spritePalette.data = gFollowerPalettes[species][shiny & 1];
|
||||
|
||||
// Check if pal data must be decompressed
|
||||
if (IsLZ77Data(spritePalette.data, PLTT_SIZE_4BPP, PLTT_SIZE_4BPP)) {
|
||||
// IsLZ77Data guarantees word-alignment, so casting this is safe
|
||||
LZ77UnCompWram((u32*)spritePalette.data, gDecompressionBuffer);
|
||||
spritePalette.data = (void*)gDecompressionBuffer;
|
||||
}
|
||||
|
||||
paletteNum = LoadSpritePalette(&spritePalette);
|
||||
if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) // don't want to weather blend in fog
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue