diff options
Diffstat (limited to 'src/pokemon_icon.c')
-rw-r--r-- | src/pokemon_icon.c | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/src/pokemon_icon.c b/src/pokemon_icon.c index 4d1cc51c5..253ab2cb4 100644 --- a/src/pokemon_icon.c +++ b/src/pokemon_icon.c @@ -1,9 +1,28 @@ #include "global.h" #include "sprite.h" +#include "mail.h" #include "graphics.h" +#include "constants/species.h" +#include "palette.h" +#include "pokemon_icon.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; + void (*callback)(struct Sprite *); + u16 paletteTag; +}; + +// static functions +static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *, s16, s16, u8); + +// .rodata + const u8 * const gMonIconTable[] = { gMonIcon_Bulbasaur, @@ -1012,3 +1031,288 @@ const u16 sSpriteImageSizes[3][4] = 0x400, // 4×8 }, }; + +u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), 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 > SPECIES_EGG) + iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG; + + spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority); + + UpdateMonIconFrame(&gSprites[spriteId]); + + return spriteId; +} + +u8 sub_80D2D78(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 mon_icon_convert_unown_species_id(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 > SPECIES_EGG) + result = 260; + else + result = species; + } + + return result; +} + +u16 GetUnownLetterByPersonality(u32 personality) +{ + if (!personality) + return 0; + return (((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 0x1C; +} + +u16 sub_80D2E84(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 = 260; + return mon_icon_convert_unown_species_id(species, 0); + } +} + +const u8 *GetMonIconPtr(u16 species, u32 personality, bool32 extra) +{ + return GetMonIconTiles(mon_icon_convert_unown_species_id(species, personality), extra); +} + + + +void sub_80D2EF8(struct Sprite *sprite) +{ + sub_80D328C(sprite); +} + +void LoadMonIconPalettes(void) +{ + u8 i; + for (i = 0; i < 6; i++) + LoadSpritePalette(&gMonIconPaletteTable[i]); +} + +// unused +void SafeLoadMonIconPalette(u16 species) +{ + u8 palIndex; + if (species > SPECIES_EGG) + species = 260; + palIndex = gMonIconPaletteIndices[species]; + if (IndexOfSpritePaletteTag(gMonIconPaletteTable[palIndex].tag) == 0xFF) + LoadSpritePalette(&gMonIconPaletteTable[palIndex]); +} + +void LoadMonIconPalette(u16 species) +{ + u8 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); +} + +// unused +void SafeFreeMonIconPalette(u16 species) +{ + u8 palIndex; + if (species > SPECIES_EGG) + species = 260; + palIndex = gMonIconPaletteIndices[species]; + FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag); +} + +void FreeMonIconPalette(u16 species) +{ + u8 palIndex; + palIndex = gMonIconPaletteIndices[species]; + FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag); +} + +void sub_80D3014(struct Sprite *sprite) +{ + UpdateMonIconFrame(sprite); +} + +const u8* GetMonIconTiles(u16 species, bool32 extra) +{ + const u8* iconSprite = gMonIconTable[species]; + if(species == SPECIES_DEOXYS && extra == TRUE) + { + iconSprite = (const u8*)(0x400 + (u32)iconSprite); //WTF? + } + return iconSprite; +} + +void sub_80D304C(u16 offset) +{ + s32 i; + const struct SpritePalette* monIconPalettePtr; + + if(offset <= 0xA0) + { + monIconPalettePtr = gMonIconPaletteTable; + for(i = 5; i >= 0 ; i--) + { + LoadPalette(monIconPalettePtr->data, offset, 0x20); + offset += 0x10; + monIconPalettePtr++; + } + } +} + +u8 sub_80D3080(u16 species) +{ + if (species > SPECIES_EGG) + species = 260; + return gMonIconPaletteIndices[species]; +} + +u8 sub_80D30A0(u16 species) +{ + return gMonIconPaletteIndices[species]; +} + +const u16* GetValidMonIconPalettePtr(u16 species) +{ + if (species > SPECIES_EGG) + species = 260; + return gMonIconPaletteTable[gMonIconPaletteIndices[species]].data; +} + +// TODO: try to find a way to avoid using asm statement +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]); + { + register u8 duration asm("r0") = sprite->anims[sprite->animNum][sprite->animCmdIndex].frame.duration; + sprite->animDelayCounter = duration; + } + sprite->animCmdIndex++; + result = sprite->animCmdIndex; + break; + } + } + else + { + sprite->animDelayCounter--; + } + return result; +} + +static u8 CreateMonIconSprite(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_80D328C(struct Sprite *sprite) +{ + struct SpriteFrameImage image = { NULL, sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] }; + sprite->images = ℑ + DestroySprite(sprite); +} + +void sub_80D32C8(struct Sprite *sprite, u8 animNum) +{ + sprite->animNum = animNum; + sprite->animDelayCounter = 0; + sprite->animCmdIndex = 0; +} |