summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mail.c6
-rw-r--r--src/pokemon_icon.c299
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 = &image;
+ DestroySprite(sprite);
+}
+
+void sub_8097414(struct Sprite *sprite, u8 animNum)
+{
+ sprite->animNum = animNum;
+ sprite->animDelayCounter = 0;
+ sprite->animCmdIndex = 0;
+}