diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mail.c | 6 | ||||
-rw-r--r-- | src/pokemon_icon.c | 299 |
2 files changed, 302 insertions, 3 deletions
diff --git a/src/mail.c b/src/mail.c index f6b7e2c4d..54dec0031 100644 --- a/src/mail.c +++ b/src/mail.c @@ -600,11 +600,11 @@ static bool8 DoInitMailView(void) switch (sMailViewResources->monIconType) { case MAIL_ICON_BEAD: - sub_80970E0(iconId); + LoadMonIconPalette(iconId); sMailViewResources->monIconSpriteId = sub_8096ECC(iconId, SpriteCallbackDummy, 0x60, 0x80, 0, FALSE); break; case MAIL_ICON_DREAM: - sub_80970E0(iconId); + LoadMonIconPalette(iconId); sMailViewResources->monIconSpriteId = sub_8096ECC(iconId, SpriteCallbackDummy, 0x28, 0x80, 0, FALSE); break; } @@ -726,7 +726,7 @@ static void ShowMailCB_Teardown(void) { case MAIL_ICON_BEAD: case MAIL_ICON_DREAM: - sub_8097168(sub_8096FD4(sMailViewResources->mail->species)); + FreeMonIconPalette(sub_8096FD4(sMailViewResources->mail->species)); sub_8097070(&gSprites[sMailViewResources->monIconSpriteId]); break; } diff --git a/src/pokemon_icon.c b/src/pokemon_icon.c new file mode 100644 index 000000000..1f739651f --- /dev/null +++ b/src/pokemon_icon.c @@ -0,0 +1,299 @@ +#include "global.h" +#include "palette.h" +#include "mail_data.h" +#include "pokemon_icon.h" +#include "constants/species.h" + +#define POKE_ICON_BASE_PAL_TAG 56000 + +struct MonIconSpriteTemplate +{ + const struct OamData * oam; + const u8 *image; + const union AnimCmd *const * anims; + const union AffineAnimCmd *const * affineAnims; + SpriteCallback callback; + u16 paletteTag; +}; + +static u8 CreateMonIconSprite(const struct MonIconSpriteTemplate * template, s16 x, s16 y, u8 subpriority); +void sub_80973D8(struct Sprite * sprite); + +extern const u8 *const gMonIconTable[NUM_SPECIES]; +extern const u8 gMonIconPaletteIndices[NUM_SPECIES]; +extern const struct SpritePalette gMonIconPaletteTable[6]; +extern const struct OamData sMonIconOamData; +extern const union AnimCmd *const sMonIconAnims[]; +extern const union AffineAnimCmd *const sMonIconAffineAnims[]; +extern const u16 sSpriteImageSizes[3][4]; + +u8 CreateMonIcon(u16 species, SpriteCallback callback, s16 x, s16 y, u8 subpriority, u32 personality, bool32 extra) +{ + u8 spriteId; + struct MonIconSpriteTemplate iconTemplate = + { + .oam = &sMonIconOamData, + .image = GetMonIconPtr(species, personality, extra), + .anims = sMonIconAnims, + .affineAnims = sMonIconAffineAnims, + .callback = callback, + .paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species], + }; + + if (species > NUM_SPECIES) + iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG; + + spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority); + + UpdateMonIconFrame(&gSprites[spriteId]); + + return spriteId; +} + +u8 sub_8096ECC(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, bool32 extra) +{ + u8 spriteId; + struct MonIconSpriteTemplate iconTemplate = + { + .oam = &sMonIconOamData, + .image = NULL, + .anims = sMonIconAnims, + .affineAnims = sMonIconAffineAnims, + .callback = callback, + .paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species], + }; + + iconTemplate.image = GetMonIconTiles(species, extra); + spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority); + + UpdateMonIconFrame(&gSprites[spriteId]); + + return spriteId; +} + +u16 GetIconSpecies(u16 species, u32 personality) +{ + u16 result; + + if (species == SPECIES_UNOWN) + { + u16 letter = GetUnownLetterByPersonality(personality); + if (letter == 0) + letter = SPECIES_UNOWN; + else + letter += (SPECIES_UNOWN_B - 1); + result = letter; + } + else + { + if (species > NUM_SPECIES) + result = SPECIES_NONE; + else + result = species; + } + + return result; +} + +u16 GetUnownLetterByPersonality(u32 personality) +{ + if (!personality) + return 0; + else + return (((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 0x1C; +} + +u16 sub_8096FD4(u16 species) +{ + u16 value; + + if (MailSpeciesToSpecies(species, &value) == SPECIES_UNOWN) + { + if (value == 0) + value += SPECIES_UNOWN; + else + value += (SPECIES_UNOWN_B - 1); + return value; + } + else + { + if (species > (SPECIES_UNOWN_B - 1)) + species = SPECIES_NONE; + return GetIconSpecies(species, 0); + } +} + +const u8* GetMonIconTiles(u16 species, bool32 extra) +{ + const u8* iconSprite = gMonIconTable[species]; + if (species == SPECIES_DEOXYS && extra == TRUE) + iconSprite += 0x400; + return iconSprite; +} + +const u8 *GetMonIconPtr(u16 species, u32 personality, bool32 extra) +{ + return GetMonIconTiles(GetIconSpecies(species, personality), extra); +} + +void sub_8097070(struct Sprite * sprite) +{ + sub_80973D8(sprite); +} + +void sub_809707C(void) +{ + u8 i; + for (i = 0; i < NELEMS(gMonIconPaletteTable); i++) + LoadSpritePalette(&gMonIconPaletteTable[i]); +} + +void SafeLoadMonIconPalette(u16 species) +{ + u8 palIndex; + if (species > NUM_SPECIES) + species = SPECIES_NONE; + palIndex = gMonIconPaletteIndices[species]; + if (IndexOfSpritePaletteTag(gMonIconPaletteTable[palIndex].tag) == 0xFF) + LoadSpritePalette(&gMonIconPaletteTable[palIndex]); +} + +void LoadMonIconPalette(u16 species) +{ + u8 palIndex; + palIndex = gMonIconPaletteIndices[species]; + if (IndexOfSpritePaletteTag(gMonIconPaletteTable[palIndex].tag) == 0xFF) + LoadSpritePalette(&gMonIconPaletteTable[palIndex]); +} + +void FreeMonIconPalettes(void) +{ + u8 i; + for (i = 0; i < 6; i++) + FreeSpritePaletteByTag(gMonIconPaletteTable[i].tag); +} +void SafeFreeMonIconPalette(u16 species) +{ + u8 palIndex; + if (species > NUM_SPECIES) + species = SPECIES_NONE; + palIndex = gMonIconPaletteIndices[species]; + FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag); +} + +void FreeMonIconPalette(u16 species) +{ + u8 palIndex; + palIndex = gMonIconPaletteIndices[species]; + FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag); +} + +void sub_809718C(struct Sprite * sprite) +{ + UpdateMonIconFrame(sprite); +} + +void sub_8097198(u16 offset) +{ + int i; + if (offset <= 0x100 - 0x60) + { + for (i = 0; i < (int)NELEMS(gMonIconPaletteTable); i++) + { + LoadPalette(gMonIconPaletteTable[i].data, offset, 0x20); + offset += 0x10; + } + } +} +const u16* GetValidMonIconPalettePtr(u16 species) +{ + if (species > NUM_SPECIES) + species = SPECIES_NONE; + return gMonIconPaletteTable[gMonIconPaletteIndices[species]].data; +} + +u8 GetValidMonIconPalIndex(u16 species) +{ + if (species > NUM_SPECIES) + species = SPECIES_NONE; + return gMonIconPaletteIndices[species]; +} + +u8 GetMonIconPaletteIndexFromSpecies(u16 species) +{ + return gMonIconPaletteIndices[species]; +} + +u8 UpdateMonIconFrame(struct Sprite *sprite) +{ + u8 result = 0; + + if (sprite->animDelayCounter == 0) + { + s16 frame = sprite->anims[sprite->animNum][sprite->animCmdIndex].frame.imageValue; + + switch (frame) + { + case -1: + break; + case -2: + sprite->animCmdIndex = 0; + break; + default: + RequestSpriteCopy( + // pointer arithmetic is needed to get the correct pointer to perform the sprite copy on. + // because sprite->images is a struct def, it has to be casted to (u8 *) before any + // arithmetic can be performed. + (u8 *)sprite->images + (sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] * frame), + (u8 *)(OBJ_VRAM0 + sprite->oam.tileNum * TILE_SIZE_4BPP), + sSpriteImageSizes[sprite->oam.shape][sprite->oam.size]); + sprite->animDelayCounter = sprite->anims[sprite->animNum][sprite->animCmdIndex].frame.duration & 0xFF; + sprite->animCmdIndex++; + result = sprite->animCmdIndex; + break; + } + } + else + { + sprite->animDelayCounter--; + } + return result; +} + +static u8 CreateMonIconSprite(const struct MonIconSpriteTemplate *iconTemplate, s16 x, s16 y, u8 subpriority) +{ + u8 spriteId; + + struct SpriteFrameImage image = { NULL, sSpriteImageSizes[iconTemplate->oam->shape][iconTemplate->oam->size] }; + + struct SpriteTemplate spriteTemplate = + { + .tileTag = 0xFFFF, + .paletteTag = iconTemplate->paletteTag, + .oam = iconTemplate->oam, + .anims = iconTemplate->anims, + .images = &image, + .affineAnims = iconTemplate->affineAnims, + .callback = iconTemplate->callback, + }; + + spriteId = CreateSprite(&spriteTemplate, x, y, subpriority); + gSprites[spriteId].animPaused = TRUE; + gSprites[spriteId].animBeginning = FALSE; + gSprites[spriteId].images = (const struct SpriteFrameImage *)iconTemplate->image; + return spriteId; +} + +void sub_80973D8(struct Sprite *sprite) +{ + struct SpriteFrameImage image = { NULL, sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] }; + sprite->images = ℑ + DestroySprite(sprite); +} + +void sub_8097414(struct Sprite *sprite, u8 animNum) +{ + sprite->animNum = animNum; + sprite->animDelayCounter = 0; + sprite->animCmdIndex = 0; +} |