pokeemerald/src/trainer_pokemon_sprites.c

380 lines
12 KiB
C
Raw Normal View History

2017-09-19 01:39:20 +02:00
#include "global.h"
2017-09-19 02:00:46 +02:00
#include "sprite.h"
2017-09-19 14:22:43 +02:00
#include "window.h"
#include "malloc.h"
2017-09-19 03:26:11 +02:00
#include "palette.h"
2017-09-19 02:00:46 +02:00
#include "decompress.h"
2018-08-19 01:06:10 +02:00
#include "trainer_pokemon_sprites.h"
2019-04-04 23:53:06 +02:00
#include "data.h"
2018-08-19 01:06:10 +02:00
#include "pokemon.h"
#include "constants/trainers.h"
2017-09-19 02:00:46 +02:00
2018-08-19 01:06:10 +02:00
struct PicData
{
2017-09-19 04:23:13 +02:00
u8 *frames;
2017-09-19 14:13:53 +02:00
struct SpriteFrameImage *images;
2017-09-19 04:23:13 +02:00
u16 paletteTag;
u8 spriteId;
u8 active;
2017-09-19 01:39:20 +02:00
};
2018-08-19 01:06:10 +02:00
#define PICS_COUNT 8
2017-09-19 01:39:20 +02:00
2018-08-19 01:06:10 +02:00
static EWRAM_DATA struct SpriteTemplate sCreatingSpriteTemplate = {};
static EWRAM_DATA struct PicData sSpritePics[PICS_COUNT] = {};
2017-09-19 01:39:20 +02:00
2018-08-19 01:06:10 +02:00
static const struct PicData sDummyPicData = {};
2021-10-18 07:39:07 +02:00
static const struct OamData sOamData_Normal =
{
.shape = SPRITE_SHAPE(64x64),
.size = SPRITE_SIZE(64x64)
};
2021-10-18 07:39:07 +02:00
static const struct OamData sOamData_Affine =
{
2019-12-05 04:26:43 +01:00
.affineMode = ST_OAM_AFFINE_NORMAL,
.shape = SPRITE_SHAPE(64x64),
.size = SPRITE_SIZE(64x64)
};
2017-09-19 01:39:20 +02:00
2018-08-19 01:06:10 +02:00
static void DummyPicSpriteCallback(struct Sprite *sprite)
2017-09-19 01:39:20 +02:00
{
}
2018-08-19 01:06:10 +02:00
bool16 ResetAllPicSprites(void)
2017-09-19 01:39:20 +02:00
{
int i;
2018-08-19 01:06:10 +02:00
for (i = 0; i < PICS_COUNT; i ++)
sSpritePics[i] = sDummyPicData;
2017-09-19 01:39:20 +02:00
return FALSE;
}
2017-09-19 02:00:46 +02:00
2018-08-19 01:06:10 +02:00
static bool16 DecompressPic(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer, bool8 ignoreDeoxys)
2017-09-19 02:00:46 +02:00
{
if (!isTrainer)
{
if (isFrontPic)
{
if (!ignoreDeoxys)
LoadSpecialPokePic(&gMonFrontPicTable[species], dest, species, personality, isFrontPic);
else
LoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], dest, species, personality, isFrontPic);
}
else
{
if (!ignoreDeoxys)
LoadSpecialPokePic(&gMonBackPicTable[species], dest, species, personality, isFrontPic);
else
LoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species], dest, species, personality, isFrontPic);
}
}
else
{
if (isFrontPic)
DecompressPicFromTable(&gTrainerFrontPicTable[species], dest, species);
else
DecompressPicFromTable(&gTrainerBackPicTable[species], dest, species);
}
return FALSE;
}
2017-09-19 03:26:11 +02:00
2018-08-19 01:06:10 +02:00
static bool16 DecompressPic_HandleDeoxys(u16 species, u32 personality, bool8 isFrontPic, u8 *dest, bool8 isTrainer)
2017-09-19 03:26:11 +02:00
{
2018-08-19 01:06:10 +02:00
return DecompressPic(species, personality, isFrontPic, dest, isTrainer, FALSE);
2017-09-19 03:26:11 +02:00
}
2018-08-19 01:06:10 +02:00
static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
2017-09-19 03:26:11 +02:00
{
if (!isTrainer)
{
2021-09-14 19:14:14 +02:00
if (paletteTag == TAG_NONE)
2017-09-19 03:26:11 +02:00
{
2021-09-14 19:14:14 +02:00
sCreatingSpriteTemplate.paletteTag = TAG_NONE;
2019-07-25 18:56:08 +02:00
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x100 + paletteSlot * 0x10, 0x20);
2017-09-19 03:26:11 +02:00
}
else
{
2018-08-19 01:06:10 +02:00
sCreatingSpriteTemplate.paletteTag = paletteTag;
2018-12-17 23:00:08 +01:00
LoadCompressedSpritePalette(GetMonSpritePalStructFromOtIdPersonality(species, otId, personality));
2017-09-19 03:26:11 +02:00
}
}
else
{
2021-09-14 19:14:14 +02:00
if (paletteTag == TAG_NONE)
2017-09-19 03:26:11 +02:00
{
2021-09-14 19:14:14 +02:00
sCreatingSpriteTemplate.paletteTag = TAG_NONE;
2017-09-19 03:26:11 +02:00
LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, 0x100 + paletteSlot * 0x10, 0x20);
}
else
{
2018-08-19 01:06:10 +02:00
sCreatingSpriteTemplate.paletteTag = paletteTag;
2018-12-17 23:00:08 +01:00
LoadCompressedSpritePalette(&gTrainerFrontPicPaletteTable[species]);
2017-09-19 03:26:11 +02:00
}
}
}
2017-09-19 03:28:28 +02:00
2018-08-19 01:06:10 +02:00
static void LoadPicPaletteBySlot(u16 species, u32 otId, u32 personality, u8 paletteSlot, bool8 isTrainer)
2017-09-19 03:28:28 +02:00
{
if (!isTrainer)
2019-07-25 18:56:08 +02:00
LoadCompressedPalette(GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality), paletteSlot * 0x10, 0x20);
2017-09-19 03:28:28 +02:00
else
LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, paletteSlot * 0x10, 0x20);
}
2017-09-19 03:31:28 +02:00
2018-08-19 01:06:10 +02:00
static void AssignSpriteAnimsTable(bool8 isTrainer)
2017-09-19 03:31:28 +02:00
{
if (!isTrainer)
sCreatingSpriteTemplate.anims = gAnims_MonPic;
2017-09-19 03:31:28 +02:00
else
sCreatingSpriteTemplate.anims = gTrainerFrontAnimsPtrTable[0];
2017-09-19 03:31:28 +02:00
}
2017-09-19 04:23:13 +02:00
2018-08-19 01:06:10 +02:00
static u16 CreatePicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer, bool8 ignoreDeoxys)
2017-09-19 04:23:13 +02:00
{
u8 i;
u8 *framePics;
struct SpriteFrameImage *images;
int j;
u8 spriteId;
2018-08-19 01:06:10 +02:00
for (i = 0; i < PICS_COUNT; i ++)
2017-09-19 04:23:13 +02:00
{
2018-08-19 01:06:10 +02:00
if (!sSpritePics[i].active)
2017-09-19 04:23:13 +02:00
break;
}
2018-08-19 01:06:10 +02:00
if (i == PICS_COUNT)
return 0xFFFF;
2021-10-18 07:39:07 +02:00
2017-09-19 04:23:13 +02:00
framePics = Alloc(4 * 0x800);
if (!framePics)
return 0xFFFF;
2021-10-18 07:39:07 +02:00
2017-09-19 04:23:13 +02:00
images = Alloc(4 * sizeof(struct SpriteFrameImage));
if (!images)
{
Free(framePics);
return 0xFFFF;
2017-09-19 04:23:13 +02:00
}
2018-08-19 01:06:10 +02:00
if (DecompressPic(species, personality, isFrontPic, framePics, isTrainer, ignoreDeoxys))
2017-09-19 04:23:13 +02:00
{
// debug trap?
return 0xFFFF;
2017-09-19 04:23:13 +02:00
}
for (j = 0; j < 4; j ++)
{
images[j].data = framePics + 0x800 * j;
images[j].size = 0x800;
}
2021-09-14 19:14:14 +02:00
sCreatingSpriteTemplate.tileTag = TAG_NONE;
2021-10-18 07:39:07 +02:00
sCreatingSpriteTemplate.oam = &sOamData_Normal;
2018-08-19 01:06:10 +02:00
AssignSpriteAnimsTable(isTrainer);
sCreatingSpriteTemplate.images = images;
sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
sCreatingSpriteTemplate.callback = DummyPicSpriteCallback;
LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, isTrainer);
spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0);
2021-09-14 19:14:14 +02:00
if (paletteTag == TAG_NONE)
2017-09-19 04:23:13 +02:00
gSprites[spriteId].oam.paletteNum = paletteSlot;
2018-08-19 01:06:10 +02:00
sSpritePics[i].frames = framePics;
sSpritePics[i].images = images;
sSpritePics[i].paletteTag = paletteTag;
sSpritePics[i].spriteId = spriteId;
sSpritePics[i].active = TRUE;
2017-09-19 04:23:13 +02:00
return spriteId;
}
2017-09-19 04:41:54 +02:00
2018-08-19 01:06:10 +02:00
static u16 CreatePicSprite_HandleDeoxys(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 isTrainer)
2017-09-19 04:41:54 +02:00
{
2018-08-19 01:06:10 +02:00
return CreatePicSprite(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, isTrainer, FALSE);
2017-09-19 04:41:54 +02:00
}
2021-10-18 07:39:07 +02:00
u16 CreateMonPicSprite_Affine(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
2017-09-19 04:41:54 +02:00
{
u8 *framePics;
struct SpriteFrameImage *images;
int j;
u8 i;
u8 spriteId;
2021-10-18 07:39:07 +02:00
u8 type;
2017-09-19 04:41:54 +02:00
2021-10-18 07:39:07 +02:00
for (i = 0; i < PICS_COUNT; i++)
2017-09-19 04:41:54 +02:00
{
2018-08-19 01:06:10 +02:00
if (!sSpritePics[i].active)
2017-09-19 04:41:54 +02:00
break;
}
2018-08-19 01:06:10 +02:00
if (i == PICS_COUNT)
return 0xFFFF;
2021-10-18 07:39:07 +02:00
framePics = Alloc(4 * MON_PIC_SIZE);
2017-09-19 04:41:54 +02:00
if (!framePics)
return 0xFFFF;
2021-10-18 07:39:07 +02:00
if (flags & F_MON_PIC_NO_AFFINE)
2017-09-19 04:41:54 +02:00
{
2021-10-18 07:39:07 +02:00
flags &= ~F_MON_PIC_NO_AFFINE;
type = MON_PIC_AFFINE_NONE;
2017-09-19 04:41:54 +02:00
}
else
{
2021-10-18 07:39:07 +02:00
type = flags;
2017-09-19 04:41:54 +02:00
}
images = Alloc(4 * sizeof(struct SpriteFrameImage));
if (!images)
{
Free(framePics);
return 0xFFFF;
2017-09-19 04:41:54 +02:00
}
2018-08-19 01:06:10 +02:00
if (DecompressPic(species, personality, flags, framePics, FALSE, FALSE))
2017-09-19 04:41:54 +02:00
{
// debug trap?
return 0xFFFF;
2017-09-19 04:41:54 +02:00
}
for (j = 0; j < 4; j ++)
{
2021-10-18 07:39:07 +02:00
images[j].data = framePics + MON_PIC_SIZE * j;
images[j].size = MON_PIC_SIZE;
2017-09-19 04:41:54 +02:00
}
2021-09-14 19:14:14 +02:00
sCreatingSpriteTemplate.tileTag = TAG_NONE;
2019-04-04 23:53:06 +02:00
sCreatingSpriteTemplate.anims = gMonFrontAnimsPtrTable[species];
2018-08-19 01:06:10 +02:00
sCreatingSpriteTemplate.images = images;
2021-10-18 07:39:07 +02:00
if (type == MON_PIC_AFFINE_FRONT)
2017-09-19 04:41:54 +02:00
{
2021-01-23 05:22:37 +01:00
sCreatingSpriteTemplate.affineAnims = gAffineAnims_BattleSpriteOpponentSide;
2021-10-18 07:39:07 +02:00
sCreatingSpriteTemplate.oam = &sOamData_Affine;
2017-09-19 04:41:54 +02:00
}
2021-10-18 07:39:07 +02:00
else if (type == MON_PIC_AFFINE_BACK)
2017-09-19 04:41:54 +02:00
{
2021-01-23 05:22:37 +01:00
sCreatingSpriteTemplate.affineAnims = gAffineAnims_BattleSpritePlayerSide;
2021-10-18 07:39:07 +02:00
sCreatingSpriteTemplate.oam = &sOamData_Affine;
2017-09-19 04:41:54 +02:00
}
2021-10-18 07:39:07 +02:00
else // MON_PIC_AFFINE_NONE
2017-09-19 04:41:54 +02:00
{
2021-10-18 07:39:07 +02:00
sCreatingSpriteTemplate.oam = &sOamData_Normal;
2018-08-19 01:06:10 +02:00
sCreatingSpriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
2017-09-19 04:41:54 +02:00
}
2018-08-19 01:06:10 +02:00
sCreatingSpriteTemplate.callback = DummyPicSpriteCallback;
LoadPicPaletteByTagOrSlot(species, otId, personality, paletteSlot, paletteTag, FALSE);
spriteId = CreateSprite(&sCreatingSpriteTemplate, x, y, 0);
2021-09-14 19:14:14 +02:00
if (paletteTag == TAG_NONE)
2017-09-19 04:41:54 +02:00
gSprites[spriteId].oam.paletteNum = paletteSlot;
2018-08-19 01:06:10 +02:00
sSpritePics[i].frames = framePics;
sSpritePics[i].images = images;
sSpritePics[i].paletteTag = paletteTag;
sSpritePics[i].spriteId = spriteId;
sSpritePics[i].active = TRUE;
2017-09-19 04:41:54 +02:00
return spriteId;
}
2017-09-19 14:13:53 +02:00
2018-08-19 01:06:10 +02:00
static u16 FreeAndDestroyPicSpriteInternal(u16 spriteId)
2017-09-19 14:13:53 +02:00
{
u8 i;
u8 *framePics;
struct SpriteFrameImage *images;
2018-08-19 01:06:10 +02:00
for (i = 0; i < PICS_COUNT; i ++)
2017-09-19 14:13:53 +02:00
{
2018-08-19 01:06:10 +02:00
if (sSpritePics[i].spriteId == spriteId)
2017-09-19 14:13:53 +02:00
break;
}
2018-08-19 01:06:10 +02:00
if (i == PICS_COUNT)
return 0xFFFF;
2021-10-18 07:39:07 +02:00
2018-08-19 01:06:10 +02:00
framePics = sSpritePics[i].frames;
images = sSpritePics[i].images;
2021-09-14 19:14:14 +02:00
if (sSpritePics[i].paletteTag != TAG_NONE)
2017-09-19 14:13:53 +02:00
FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[spriteId].oam.paletteNum));
DestroySprite(&gSprites[spriteId]);
Free(framePics);
Free(images);
2018-08-19 01:06:10 +02:00
sSpritePics[i] = sDummyPicData;
2017-09-19 14:13:53 +02:00
return 0;
}
2017-09-19 14:22:43 +02:00
2021-10-18 07:39:07 +02:00
static u16 LoadPicSpriteInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId, bool8 isTrainer)
2017-09-19 14:22:43 +02:00
{
2018-08-19 01:06:10 +02:00
if (DecompressPic_HandleDeoxys(species, personality, isFrontPic, (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA), FALSE))
return 0xFFFF;
2021-10-18 07:39:07 +02:00
2018-08-19 01:06:10 +02:00
LoadPicPaletteBySlot(species, otId, personality, paletteSlot, isTrainer);
2017-09-19 14:22:43 +02:00
return 0;
}
2017-09-19 14:32:49 +02:00
2020-02-07 18:48:47 +01:00
static u16 CreateTrainerCardSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId, bool8 isTrainer)
2017-09-19 14:32:49 +02:00
{
u8 *framePics;
framePics = Alloc(4 * 0x800);
2018-08-19 01:06:10 +02:00
if (framePics && !DecompressPic_HandleDeoxys(species, personality, isFrontPic, framePics, isTrainer))
2017-09-19 14:32:49 +02:00
{
BlitBitmapRectToWindow(windowId, framePics, 0, 0, 0x40, 0x40, destX, destY, 0x40, 0x40);
2018-08-19 01:06:10 +02:00
LoadPicPaletteBySlot(species, otId, personality, paletteSlot, isTrainer);
2017-09-19 14:32:49 +02:00
Free(framePics);
return 0;
}
return 0xFFFF;
2017-09-19 14:32:49 +02:00
}
2017-09-19 14:35:27 +02:00
2018-08-19 01:06:10 +02:00
static u16 CreateMonPicSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag, bool8 ignoreDeoxys)
2017-09-19 14:35:27 +02:00
{
2018-08-19 01:06:10 +02:00
return CreatePicSprite(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE, ignoreDeoxys);
2017-09-19 14:35:27 +02:00
}
2017-09-19 14:36:45 +02:00
2018-08-19 01:06:10 +02:00
u16 CreateMonPicSprite_HandleDeoxys(u16 species, u32 otId, u32 personality, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
2017-09-19 14:36:45 +02:00
{
2018-08-19 01:06:10 +02:00
return CreateMonPicSprite(species, otId, personality, isFrontPic, x, y, paletteSlot, paletteTag, FALSE);
2017-09-19 14:36:45 +02:00
}
2017-09-19 14:53:31 +02:00
2018-08-19 01:06:10 +02:00
u16 FreeAndDestroyMonPicSprite(u16 spriteId)
2017-09-19 14:53:31 +02:00
{
2018-08-19 01:06:10 +02:00
return FreeAndDestroyPicSpriteInternal(spriteId);
2017-09-19 14:53:31 +02:00
}
2021-10-18 07:39:07 +02:00
// Unused
static u16 LoadMonPicInWindow(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
2017-09-19 14:53:31 +02:00
{
2021-10-18 07:39:07 +02:00
return LoadPicSpriteInWindow(species, otId, personality, isFrontPic, paletteSlot, windowId, FALSE);
2017-09-19 14:53:31 +02:00
}
2020-02-07 18:48:47 +01:00
// Unused, FRLG only
u16 CreateTrainerCardMonIconSprite(u16 species, u32 otId, u32 personality, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
2017-09-19 14:53:31 +02:00
{
2020-02-07 18:48:47 +01:00
return CreateTrainerCardSprite(species, otId, personality, isFrontPic, destX, destY, paletteSlot, windowId, FALSE);
2017-09-19 14:53:31 +02:00
}
2018-08-19 01:06:10 +02:00
u16 CreateTrainerPicSprite(u16 species, bool8 isFrontPic, s16 x, s16 y, u8 paletteSlot, u16 paletteTag)
2017-09-19 14:53:31 +02:00
{
2018-08-19 01:06:10 +02:00
return CreatePicSprite_HandleDeoxys(species, 0, 0, isFrontPic, x, y, paletteSlot, paletteTag, TRUE);
2017-09-19 14:53:31 +02:00
}
2018-08-19 01:06:10 +02:00
u16 FreeAndDestroyTrainerPicSprite(u16 spriteId)
2017-09-19 14:53:31 +02:00
{
2018-08-19 01:06:10 +02:00
return FreeAndDestroyPicSpriteInternal(spriteId);
2017-09-19 14:53:31 +02:00
}
2021-10-18 07:39:07 +02:00
// Unused
static u16 LoadTrainerPicInWindow(u16 species, bool8 isFrontPic, u8 paletteSlot, u8 windowId)
2017-09-19 14:53:31 +02:00
{
2021-10-18 07:39:07 +02:00
return LoadPicSpriteInWindow(species, 0, 0, isFrontPic, paletteSlot, windowId, TRUE);
2017-09-19 14:53:31 +02:00
}
2020-02-07 18:48:47 +01:00
u16 CreateTrainerCardTrainerPicSprite(u16 species, bool8 isFrontPic, u16 destX, u16 destY, u8 paletteSlot, u8 windowId)
2017-09-19 14:53:31 +02:00
{
2020-02-07 18:48:47 +01:00
return CreateTrainerCardSprite(species, 0, 0, isFrontPic, destX, destY, paletteSlot, windowId, TRUE);
2017-09-19 14:53:31 +02:00
}
2018-08-19 01:06:10 +02:00
u16 PlayerGenderToFrontTrainerPicId_Debug(u8 gender, bool8 getClass)
{
2018-08-19 01:06:10 +02:00
if (getClass == TRUE)
{
2021-10-18 07:39:07 +02:00
if (gender != MALE)
return gFacilityClassToPicIndex[FACILITY_CLASS_MAY];
2021-10-18 07:39:07 +02:00
else
return gFacilityClassToPicIndex[FACILITY_CLASS_BRENDAN];
}
2018-08-19 01:06:10 +02:00
return gender;
}