mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-27 04:04:17 +01:00
1536 lines
43 KiB
C
1536 lines
43 KiB
C
#include "global.h"
|
|
#include "hall_of_fame.h"
|
|
#include "task.h"
|
|
#include "palette.h"
|
|
#include "sprite.h"
|
|
#include "pokemon.h"
|
|
#include "text.h"
|
|
#include "text_window.h"
|
|
#include "malloc.h"
|
|
#include "gpu_regs.h"
|
|
#include "graphics.h"
|
|
#include "main.h"
|
|
#include "sound.h"
|
|
#include "constants/songs.h"
|
|
#include "decompress.h"
|
|
#include "save.h"
|
|
#include "strings.h"
|
|
#include "window.h"
|
|
#include "credits.h"
|
|
#include "bg.h"
|
|
#include "constants/game_stat.h"
|
|
#include "util.h"
|
|
#include "string_util.h"
|
|
#include "m4a.h"
|
|
#include "international_string_util.h"
|
|
#include "scanline_effect.h"
|
|
#include "trig.h"
|
|
#include "random.h"
|
|
#include "event_data.h"
|
|
#include "overworld.h"
|
|
#include "menu.h"
|
|
#include "fldeff_misc.h"
|
|
#include "trainer_pokemon_sprites.h"
|
|
#include "data.h"
|
|
#include "confetti_util.h"
|
|
#include "constants/rgb.h"
|
|
|
|
#define HALL_OF_FAME_MAX_TEAMS 50
|
|
#define TAG_CONFETTI 1001
|
|
|
|
struct HallofFameMon
|
|
{
|
|
u32 tid;
|
|
u32 personality;
|
|
u16 species:9;
|
|
u16 lvl:7;
|
|
u8 nick[POKEMON_NAME_LENGTH];
|
|
};
|
|
|
|
struct HallofFameTeam
|
|
{
|
|
struct HallofFameMon mon[PARTY_SIZE];
|
|
};
|
|
|
|
STATIC_ASSERT(sizeof(struct HallofFameTeam) * HALL_OF_FAME_MAX_TEAMS <= SECTOR_DATA_SIZE * NUM_HOF_SECTORS, HallOfFameFreeSpace);
|
|
|
|
struct HofGfx
|
|
{
|
|
u16 state;
|
|
u8 field_2[16];
|
|
u8 tilemap1[0x1000];
|
|
u8 tilemap2[0x1000];
|
|
};
|
|
|
|
static EWRAM_DATA u32 sHofFadePalettes = 0;
|
|
static EWRAM_DATA struct HallofFameTeam *sHofMonPtr = NULL;
|
|
static EWRAM_DATA struct HofGfx *sHofGfxPtr = NULL;
|
|
|
|
static void ClearVramOamPltt_LoadHofPal(void);
|
|
static void LoadHofGfx(void);
|
|
static void InitHofBgs(void);
|
|
static bool8 CreateHofConfettiSprite(void);
|
|
static void StartCredits(void);
|
|
static bool8 LoadHofBgs(void);
|
|
static void Task_Hof_InitMonData(u8 taskId);
|
|
static void Task_Hof_InitTeamSaveData(u8 taskId);
|
|
static void Task_Hof_SetMonDisplayTask(u8 taskId);
|
|
static void Task_Hof_TrySaveData(u8 taskId);
|
|
static void Task_Hof_WaitToDisplayMon(u8 taskId);
|
|
static void Task_Hof_DisplayMon(u8 taskId);
|
|
static void Task_Hof_PrintMonInfoAfterAnimating(u8 taskId);
|
|
static void Task_Hof_TryDisplayAnotherMon(u8 taskId);
|
|
static void Task_Hof_PaletteFadeAndPrintWelcomeText(u8 taskId);
|
|
static void Task_Hof_DoConfetti(u8 taskId);
|
|
static void Task_Hof_WaitToDisplayPlayer(u8 taskId);
|
|
static void Task_Hof_DisplayPlayer(u8 taskId);
|
|
static void Task_Hof_WaitAndPrintPlayerInfo(u8 taskId);
|
|
static void Task_Hof_ExitOnKeyPressed(u8 taskId);
|
|
static void Task_Hof_HandlePaletteOnExit(u8 taskId);
|
|
static void Task_Hof_HandleExit(u8 taskId);
|
|
static void Task_HofPC_CopySaveData(u8 taskId);
|
|
static void Task_HofPC_PrintDataIsCorrupted(u8 taskId);
|
|
static void Task_HofPC_DrawSpritesPrintText(u8 taskId);
|
|
static void Task_HofPC_PrintMonInfo(u8 taskId);
|
|
static void Task_HofPC_HandleInput(u8 taskId);
|
|
static void Task_HofPC_HandlePaletteOnExit(u8 taskId);
|
|
static void Task_HofPC_HandleExit(u8 taskId);
|
|
static void Task_HofPC_ExitOnButtonPress(u8 taskId);
|
|
static void SpriteCB_GetOnScreenAndAnimate(struct Sprite *sprite);
|
|
static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u8 unused2);
|
|
static void HallOfFame_PrintWelcomeText(u8 unusedPossiblyWindowId, u8 unused2);
|
|
static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2);
|
|
static void Task_DoDomeConfetti(u8 taskId);
|
|
static void SpriteCB_HofConfetti(struct Sprite* sprite);
|
|
|
|
static const struct BgTemplate sHof_BgTemplates[] =
|
|
{
|
|
{
|
|
.bg = 0,
|
|
.charBaseIndex = 2,
|
|
.mapBaseIndex = 31,
|
|
.screenSize = 0,
|
|
.paletteMode = 0,
|
|
.priority = 0,
|
|
.baseTile = 0
|
|
},
|
|
{
|
|
.bg = 1,
|
|
.charBaseIndex = 0,
|
|
.mapBaseIndex = 30,
|
|
.screenSize = 0,
|
|
.paletteMode = 0,
|
|
.priority = 1,
|
|
.baseTile = 0
|
|
},
|
|
{
|
|
.bg = 3,
|
|
.charBaseIndex = 0,
|
|
.mapBaseIndex = 29,
|
|
.screenSize = 0,
|
|
.paletteMode = 0,
|
|
.priority = 3,
|
|
.baseTile = 0
|
|
},
|
|
};
|
|
|
|
static const struct WindowTemplate sHof_WindowTemplate = {
|
|
.bg = 0,
|
|
.tilemapLeft = 2,
|
|
.tilemapTop = 2,
|
|
.width = 14,
|
|
.height = 6,
|
|
.paletteNum = 14,
|
|
.baseBlock = 1
|
|
};
|
|
|
|
static const u8 sMonInfoTextColors[4] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY};
|
|
static const u8 sPlayerInfoTextColors[4] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY};
|
|
static const u8 sUnusedTextColors[4] = {TEXT_COLOR_RED, TEXT_COLOR_LIGHT_RED, TEXT_COLOR_TRANSPARENT};
|
|
|
|
static const struct CompressedSpriteSheet sSpriteSheet_Confetti[] =
|
|
{
|
|
{.data = gConfetti_Gfx, .size = 0x220, .tag = TAG_CONFETTI},
|
|
{},
|
|
};
|
|
|
|
static const struct CompressedSpritePalette sSpritePalette_Confetti[] =
|
|
{
|
|
{.data = gConfetti_Pal, .tag = TAG_CONFETTI},
|
|
{},
|
|
};
|
|
|
|
static const s16 sHallOfFame_MonFullTeamPositions[PARTY_SIZE][4] =
|
|
{
|
|
{120, 210, 120, 40},
|
|
{326, 220, 56, 40},
|
|
{-86, 220, 184, 40},
|
|
{120, -62, 120, 88},
|
|
{-70, -92, 200, 88},
|
|
{310, -92, 40, 88}
|
|
};
|
|
|
|
static const s16 sHallOfFame_MonHalfTeamPositions[PARTY_SIZE / 2][4] =
|
|
{
|
|
{120, 234, 120, 64},
|
|
{326, 244, 56, 64},
|
|
{-86, 244, 184, 64}
|
|
};
|
|
|
|
static const struct OamData sOamData_Confetti =
|
|
{
|
|
.y = 0,
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
.mosaic = 0,
|
|
.bpp = ST_OAM_4BPP,
|
|
.shape = SPRITE_SHAPE(8x8),
|
|
.x = 0,
|
|
.matrixNum = 0,
|
|
.size = SPRITE_SIZE(8x8),
|
|
.tileNum = 0,
|
|
.priority = 0,
|
|
.paletteNum = 0,
|
|
.affineParam = 0,
|
|
};
|
|
|
|
static const union AnimCmd sAnim_PinkConfettiA[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_RedConfettiA[] =
|
|
{
|
|
ANIMCMD_FRAME(1, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_BlueConfettiA[] =
|
|
{
|
|
ANIMCMD_FRAME(2, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_RedConfettiB[] =
|
|
{
|
|
ANIMCMD_FRAME(3, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_BlueConfettiB[] =
|
|
{
|
|
ANIMCMD_FRAME(4, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_YellowConfettiA[] =
|
|
{
|
|
ANIMCMD_FRAME(5, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_WhiteConfettiA[] =
|
|
{
|
|
ANIMCMD_FRAME(6, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_GreenConfettiA[] =
|
|
{
|
|
ANIMCMD_FRAME(7, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_PinkConfettiB[] =
|
|
{
|
|
ANIMCMD_FRAME(8, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_BlueConfettiC[] =
|
|
{
|
|
ANIMCMD_FRAME(9, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_YellowConfettiB[] =
|
|
{
|
|
ANIMCMD_FRAME(10, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_WhiteConfettiB[] =
|
|
{
|
|
ANIMCMD_FRAME(11, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_GreenConfettiB[] =
|
|
{
|
|
ANIMCMD_FRAME(12, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_PinkConfettiC[] =
|
|
{
|
|
ANIMCMD_FRAME(13, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_RedConfettiC[] =
|
|
{
|
|
ANIMCMD_FRAME(14, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_YellowConfettiC[] =
|
|
{
|
|
ANIMCMD_FRAME(15, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sAnim_WhiteConfettiC[] =
|
|
{
|
|
ANIMCMD_FRAME(16, 30),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd * const sAnims_Confetti[] =
|
|
{
|
|
sAnim_PinkConfettiA,
|
|
sAnim_RedConfettiA,
|
|
sAnim_BlueConfettiA,
|
|
sAnim_RedConfettiB,
|
|
sAnim_BlueConfettiB,
|
|
sAnim_YellowConfettiA,
|
|
sAnim_WhiteConfettiA,
|
|
sAnim_GreenConfettiA,
|
|
sAnim_PinkConfettiB,
|
|
sAnim_BlueConfettiC,
|
|
sAnim_YellowConfettiB,
|
|
sAnim_WhiteConfettiB,
|
|
sAnim_GreenConfettiB,
|
|
sAnim_PinkConfettiC,
|
|
sAnim_RedConfettiC,
|
|
sAnim_YellowConfettiC,
|
|
sAnim_WhiteConfettiC
|
|
};
|
|
|
|
static const struct SpriteTemplate sSpriteTemplate_HofConfetti =
|
|
{
|
|
.tileTag = TAG_CONFETTI,
|
|
.paletteTag = TAG_CONFETTI,
|
|
.oam = &sOamData_Confetti,
|
|
.anims = sAnims_Confetti,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCB_HofConfetti
|
|
};
|
|
|
|
static const u16 sHallOfFame_Pal[] = INCBIN_U16("graphics/misc/japanese_hof.gbapal");
|
|
|
|
static const u32 sHallOfFame_Gfx[] = INCBIN_U32("graphics/misc/japanese_hof.4bpp.lz");
|
|
|
|
static const struct HallofFameMon sDummyFameMon =
|
|
{
|
|
.tid = 0x3EA03EA,
|
|
.personality = 0,
|
|
.species = SPECIES_NONE,
|
|
.lvl = 0,
|
|
.nick = {0}
|
|
};
|
|
|
|
// Unused, order of party slots on Hall of Fame screen
|
|
static const u8 sHallOfFame_SlotOrder[] = {
|
|
2, 1, 3,
|
|
6, 4, 5,
|
|
};
|
|
|
|
// code
|
|
static void VBlankCB_HallOfFame(void)
|
|
{
|
|
LoadOam();
|
|
ProcessSpriteCopyRequests();
|
|
TransferPlttBuffer();
|
|
}
|
|
|
|
static void CB2_HallOfFame(void)
|
|
{
|
|
RunTasks();
|
|
RunTextPrinters();
|
|
AnimateSprites();
|
|
BuildOamBuffer();
|
|
UpdatePaletteFade();
|
|
}
|
|
|
|
static bool8 InitHallOfFameScreen(void)
|
|
{
|
|
switch (gMain.state)
|
|
{
|
|
case 0:
|
|
SetVBlankCallback(NULL);
|
|
ClearVramOamPltt_LoadHofPal();
|
|
sHofGfxPtr = AllocZeroed(sizeof(*sHofGfxPtr));
|
|
gMain.state = 1;
|
|
break;
|
|
case 1:
|
|
LoadHofGfx();
|
|
gMain.state++;
|
|
break;
|
|
case 2:
|
|
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
|
|
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 7));
|
|
SetGpuReg(REG_OFFSET_BLDY, 0);
|
|
InitHofBgs();
|
|
sHofGfxPtr->state = 0;
|
|
gMain.state++;
|
|
break;
|
|
case 3:
|
|
if (!LoadHofBgs())
|
|
{
|
|
SetVBlankCallback(VBlankCB_HallOfFame);
|
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK);
|
|
gMain.state++;
|
|
}
|
|
break;
|
|
case 4:
|
|
UpdatePaletteFade();
|
|
if (!gPaletteFade.active)
|
|
{
|
|
SetMainCallback2(CB2_HallOfFame);
|
|
PlayBGM(MUS_HALL_OF_FAME);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
#define tDontSaveData data[0]
|
|
#define tDisplayedMonId data[1]
|
|
#define tMonNumber data[2]
|
|
#define tFrameCount data[3]
|
|
#define tPlayerSpriteID data[4]
|
|
#define tMonSpriteId(i) data[i + 5]
|
|
|
|
void CB2_DoHallOfFameScreen(void)
|
|
{
|
|
if (!InitHallOfFameScreen())
|
|
{
|
|
u8 taskId = CreateTask(Task_Hof_InitMonData, 0);
|
|
gTasks[taskId].tDontSaveData = FALSE;
|
|
sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr));
|
|
}
|
|
}
|
|
|
|
void CB2_DoHallOfFameScreenDontSaveData(void)
|
|
{
|
|
if (!InitHallOfFameScreen())
|
|
{
|
|
u8 taskId = CreateTask(Task_Hof_InitMonData, 0);
|
|
gTasks[taskId].tDontSaveData = TRUE;
|
|
sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr));
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_InitMonData(u8 taskId)
|
|
{
|
|
u16 i, j;
|
|
|
|
gTasks[taskId].tMonNumber = 0; // valid pokes
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
u8 nick[POKEMON_NAME_LENGTH + 2];
|
|
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES))
|
|
{
|
|
sHofMonPtr->mon[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
|
|
sHofMonPtr->mon[i].tid = GetMonData(&gPlayerParty[i], MON_DATA_OT_ID);
|
|
sHofMonPtr->mon[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY);
|
|
sHofMonPtr->mon[i].lvl = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
|
|
GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nick);
|
|
for (j = 0; j < POKEMON_NAME_LENGTH; j++)
|
|
{
|
|
sHofMonPtr->mon[i].nick[j] = nick[j];
|
|
}
|
|
gTasks[taskId].tMonNumber++;
|
|
}
|
|
else
|
|
{
|
|
sHofMonPtr->mon[i].species = SPECIES_NONE;
|
|
sHofMonPtr->mon[i].tid = 0;
|
|
sHofMonPtr->mon[i].personality = 0;
|
|
sHofMonPtr->mon[i].lvl = 0;
|
|
sHofMonPtr->mon[i].nick[0] = EOS;
|
|
}
|
|
}
|
|
|
|
sHofFadePalettes = 0;
|
|
gTasks[taskId].tDisplayedMonId = 0;
|
|
gTasks[taskId].tPlayerSpriteID = SPRITE_NONE;
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE;
|
|
}
|
|
|
|
if (gTasks[taskId].tDontSaveData)
|
|
gTasks[taskId].func = Task_Hof_SetMonDisplayTask;
|
|
else
|
|
gTasks[taskId].func = Task_Hof_InitTeamSaveData;
|
|
}
|
|
|
|
static void Task_Hof_InitTeamSaveData(u8 taskId)
|
|
{
|
|
u16 i;
|
|
struct HallofFameTeam* lastSavedTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
|
|
|
|
if (!gHasHallOfFameRecords)
|
|
{
|
|
memset(gDecompressionBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS);
|
|
}
|
|
else
|
|
{
|
|
if (LoadGameSave(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK)
|
|
memset(gDecompressionBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS);
|
|
}
|
|
|
|
for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++)
|
|
{
|
|
if (lastSavedTeam->mon[0].species == SPECIES_NONE)
|
|
break;
|
|
}
|
|
if (i >= HALL_OF_FAME_MAX_TEAMS)
|
|
{
|
|
struct HallofFameTeam *afterTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
|
|
struct HallofFameTeam *beforeTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
|
|
afterTeam++;
|
|
for (i = 0; i < HALL_OF_FAME_MAX_TEAMS - 1; i++, beforeTeam++, afterTeam++)
|
|
{
|
|
*beforeTeam = *afterTeam;
|
|
}
|
|
lastSavedTeam--;
|
|
}
|
|
*lastSavedTeam = *sHofMonPtr;
|
|
|
|
DrawDialogueFrame(0, FALSE);
|
|
AddTextPrinterParameterized2(0, FONT_NORMAL, gText_SavingDontTurnOffPower, 0, NULL, 2, 1, 3);
|
|
CopyWindowToVram(0, COPYWIN_FULL);
|
|
gTasks[taskId].func = Task_Hof_TrySaveData;
|
|
}
|
|
|
|
static void Task_Hof_TrySaveData(u8 taskId)
|
|
{
|
|
gGameContinueCallback = CB2_DoHallOfFameScreenDontSaveData;
|
|
if (TrySavingData(SAVE_HALL_OF_FAME) == SAVE_STATUS_ERROR && gDamagedSaveSectors != 0)
|
|
{
|
|
UnsetBgTilemapBuffer(1);
|
|
UnsetBgTilemapBuffer(3);
|
|
FreeAllWindowBuffers();
|
|
|
|
TRY_FREE_AND_SET_NULL(sHofGfxPtr);
|
|
TRY_FREE_AND_SET_NULL(sHofMonPtr);
|
|
|
|
DestroyTask(taskId);
|
|
}
|
|
else
|
|
{
|
|
PlaySE(SE_SAVE);
|
|
gTasks[taskId].func = Task_Hof_WaitToDisplayMon;
|
|
gTasks[taskId].tFrameCount = 32;
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_WaitToDisplayMon(u8 taskId)
|
|
{
|
|
if (gTasks[taskId].tFrameCount)
|
|
gTasks[taskId].tFrameCount--;
|
|
else
|
|
gTasks[taskId].func = Task_Hof_SetMonDisplayTask;
|
|
}
|
|
|
|
static void Task_Hof_SetMonDisplayTask(u8 taskId)
|
|
{
|
|
gTasks[taskId].func = Task_Hof_DisplayMon;
|
|
}
|
|
|
|
#define tDestinationX data[1]
|
|
#define tDestinationY data[2]
|
|
#define tSpecies data[7]
|
|
|
|
static void Task_Hof_DisplayMon(u8 taskId)
|
|
{
|
|
u8 spriteId;
|
|
s16 startX, startY, destX, destY;
|
|
|
|
u16 currMonId = gTasks[taskId].tDisplayedMonId;
|
|
struct HallofFameMon* currMon = &sHofMonPtr->mon[currMonId];
|
|
|
|
if (gTasks[taskId].tMonNumber > PARTY_SIZE / 2)
|
|
{
|
|
startX = sHallOfFame_MonFullTeamPositions[currMonId][0];
|
|
startY = sHallOfFame_MonFullTeamPositions[currMonId][1];
|
|
destX = sHallOfFame_MonFullTeamPositions[currMonId][2];
|
|
destY = sHallOfFame_MonFullTeamPositions[currMonId][3];
|
|
}
|
|
else
|
|
{
|
|
startX = sHallOfFame_MonHalfTeamPositions[currMonId][0];
|
|
startY = sHallOfFame_MonHalfTeamPositions[currMonId][1];
|
|
destX = sHallOfFame_MonHalfTeamPositions[currMonId][2];
|
|
destY = sHallOfFame_MonHalfTeamPositions[currMonId][3];
|
|
}
|
|
|
|
if (currMon->species == SPECIES_EGG)
|
|
destY += 10;
|
|
|
|
spriteId = CreateMonPicSprite_Affine(currMon->species, currMon->tid, currMon->personality, MON_PIC_AFFINE_FRONT, startX, startY, currMonId, TAG_NONE);
|
|
gSprites[spriteId].tDestinationX = destX;
|
|
gSprites[spriteId].tDestinationY = destY;
|
|
gSprites[spriteId].data[0] = 0;
|
|
gSprites[spriteId].tSpecies = currMon->species;
|
|
gSprites[spriteId].callback = SpriteCB_GetOnScreenAndAnimate;
|
|
gTasks[taskId].tMonSpriteId(currMonId) = spriteId;
|
|
ClearDialogWindowAndFrame(0, TRUE);
|
|
gTasks[taskId].func = Task_Hof_PrintMonInfoAfterAnimating;
|
|
}
|
|
|
|
static void Task_Hof_PrintMonInfoAfterAnimating(u8 taskId)
|
|
{
|
|
u16 currMonId = gTasks[taskId].tDisplayedMonId;
|
|
struct HallofFameMon* currMon = &sHofMonPtr->mon[currMonId];
|
|
struct Sprite *monSprite = &gSprites[gTasks[taskId].tMonSpriteId(currMonId)];
|
|
|
|
if (monSprite->callback == SpriteCallbackDummy)
|
|
{
|
|
monSprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
|
HallOfFame_PrintMonInfo(currMon, 0, 14);
|
|
gTasks[taskId].tFrameCount = 120;
|
|
gTasks[taskId].func = Task_Hof_TryDisplayAnotherMon;
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_TryDisplayAnotherMon(u8 taskId)
|
|
{
|
|
u16 currPokeID = gTasks[taskId].tDisplayedMonId;
|
|
struct HallofFameMon* currMon = &sHofMonPtr->mon[currPokeID];
|
|
|
|
if (gTasks[taskId].tFrameCount != 0)
|
|
{
|
|
gTasks[taskId].tFrameCount--;
|
|
}
|
|
else
|
|
{
|
|
sHofFadePalettes |= (0x10000 << gSprites[gTasks[taskId].tMonSpriteId(currPokeID)].oam.paletteNum);
|
|
if (gTasks[taskId].tDisplayedMonId < PARTY_SIZE - 1 && currMon[1].species != SPECIES_NONE) // there is another pokemon to display
|
|
{
|
|
gTasks[taskId].tDisplayedMonId++;
|
|
BeginNormalPaletteFade(sHofFadePalettes, 0, 12, 12, RGB(16, 29, 24));
|
|
gSprites[gTasks[taskId].tMonSpriteId(currPokeID)].oam.priority = 1;
|
|
gTasks[taskId].func = Task_Hof_DisplayMon;
|
|
}
|
|
else
|
|
{
|
|
gTasks[taskId].func = Task_Hof_PaletteFadeAndPrintWelcomeText;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_PaletteFadeAndPrintWelcomeText(u8 taskId)
|
|
{
|
|
u16 i;
|
|
|
|
BeginNormalPaletteFade(PALETTES_OBJECTS, 0, 0, 0, RGB_BLACK);
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (gTasks[taskId].tMonSpriteId(i) != SPRITE_NONE)
|
|
gSprites[gTasks[taskId].tMonSpriteId(i)].oam.priority = 0;
|
|
}
|
|
|
|
HallOfFame_PrintWelcomeText(0, 15);
|
|
PlaySE(SE_APPLAUSE);
|
|
gTasks[taskId].tFrameCount = 400;
|
|
gTasks[taskId].func = Task_Hof_DoConfetti;
|
|
}
|
|
|
|
static void Task_Hof_DoConfetti(u8 taskId)
|
|
{
|
|
if (gTasks[taskId].tFrameCount != 0)
|
|
{
|
|
gTasks[taskId].tFrameCount--;
|
|
|
|
// Create new confetti every 4th frame for the first 290 frames
|
|
// For the last 110 frames wait for the existing confetti to fall offscreen
|
|
if ((gTasks[taskId].tFrameCount & 3) == 0 && gTasks[taskId].tFrameCount > 110)
|
|
CreateHofConfettiSprite();
|
|
}
|
|
else
|
|
{
|
|
u16 i;
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (gTasks[taskId].tMonSpriteId(i) != SPRITE_NONE)
|
|
gSprites[gTasks[taskId].tMonSpriteId(i)].oam.priority = 1;
|
|
}
|
|
BeginNormalPaletteFade(sHofFadePalettes, 0, 12, 12, RGB(16, 29, 24));
|
|
FillWindowPixelBuffer(0, PIXEL_FILL(0));
|
|
CopyWindowToVram(0, COPYWIN_FULL);
|
|
gTasks[taskId].tFrameCount = 7;
|
|
gTasks[taskId].func = Task_Hof_WaitToDisplayPlayer;
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_WaitToDisplayPlayer(u8 taskId)
|
|
{
|
|
if (gTasks[taskId].tFrameCount >= 16)
|
|
{
|
|
gTasks[taskId].func = Task_Hof_DisplayPlayer;
|
|
}
|
|
else
|
|
{
|
|
gTasks[taskId].tFrameCount++;
|
|
SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].tFrameCount * 256);
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_DisplayPlayer(u8 taskId)
|
|
{
|
|
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
|
|
ShowBg(0);
|
|
ShowBg(1);
|
|
ShowBg(3);
|
|
gTasks[taskId].tPlayerSpriteID = CreateTrainerPicSprite(PlayerGenderToFrontTrainerPicId_Debug(gSaveBlock2Ptr->playerGender, TRUE), 1, 120, 72, 6, TAG_NONE);
|
|
AddWindow(&sHof_WindowTemplate);
|
|
LoadWindowGfx(1, gSaveBlock2Ptr->optionsWindowFrameType, 0x21D, 0xD0);
|
|
LoadPalette(GetTextWindowPalette(1), 0xE0, 0x20);
|
|
gTasks[taskId].tFrameCount = 120;
|
|
gTasks[taskId].func = Task_Hof_WaitAndPrintPlayerInfo;
|
|
}
|
|
|
|
static void Task_Hof_WaitAndPrintPlayerInfo(u8 taskId)
|
|
{
|
|
if (gTasks[taskId].tFrameCount != 0)
|
|
{
|
|
gTasks[taskId].tFrameCount--;
|
|
}
|
|
else if (gSprites[gTasks[taskId].tPlayerSpriteID].x != 192)
|
|
{
|
|
gSprites[gTasks[taskId].tPlayerSpriteID].x++;
|
|
}
|
|
else
|
|
{
|
|
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20);
|
|
HallOfFame_PrintPlayerInfo(1, 2);
|
|
DrawDialogueFrame(0, FALSE);
|
|
AddTextPrinterParameterized2(0, FONT_NORMAL, gText_LeagueChamp, 0, NULL, 2, 1, 3);
|
|
CopyWindowToVram(0, COPYWIN_FULL);
|
|
gTasks[taskId].func = Task_Hof_ExitOnKeyPressed;
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_ExitOnKeyPressed(u8 taskId)
|
|
{
|
|
if (JOY_NEW(A_BUTTON))
|
|
{
|
|
FadeOutBGM(4);
|
|
gTasks[taskId].func = Task_Hof_HandlePaletteOnExit;
|
|
}
|
|
}
|
|
|
|
static void Task_Hof_HandlePaletteOnExit(u8 taskId)
|
|
{
|
|
CpuCopy16(gPlttBufferFaded, gPlttBufferUnfaded, 0x400);
|
|
BeginNormalPaletteFade(PALETTES_ALL, 8, 0, 0x10, RGB_BLACK);
|
|
gTasks[taskId].func = Task_Hof_HandleExit;
|
|
}
|
|
|
|
static void Task_Hof_HandleExit(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
u8 spriteId = gTasks[taskId].tMonSpriteId(i);
|
|
if (spriteId != SPRITE_NONE)
|
|
{
|
|
FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
|
|
FreeAndDestroyMonPicSprite(spriteId);
|
|
}
|
|
}
|
|
|
|
FreeAndDestroyTrainerPicSprite(gTasks[taskId].tPlayerSpriteID);
|
|
HideBg(0);
|
|
HideBg(1);
|
|
HideBg(3);
|
|
FreeAllWindowBuffers();
|
|
UnsetBgTilemapBuffer(1);
|
|
UnsetBgTilemapBuffer(3);
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
|
DestroyTask(taskId);
|
|
|
|
TRY_FREE_AND_SET_NULL(sHofGfxPtr);
|
|
TRY_FREE_AND_SET_NULL(sHofMonPtr);
|
|
|
|
StartCredits();
|
|
}
|
|
}
|
|
|
|
static void StartCredits(void)
|
|
{
|
|
SetMainCallback2(CB2_StartCreditsSequence);
|
|
}
|
|
|
|
#undef tDontSaveData
|
|
#undef tDisplayedPoke
|
|
#undef tMonNumber
|
|
#undef tFrameCount
|
|
#undef tPlayerSpriteID
|
|
#undef tMonSpriteId
|
|
|
|
#define tCurrTeamNo data[0]
|
|
#define tCurrPageNo data[1]
|
|
#define tCurrMonId data[2]
|
|
#define tMonNo data[4]
|
|
#define tMonSpriteId(i) data[i + 5]
|
|
|
|
void CB2_DoHallOfFamePC(void)
|
|
{
|
|
switch (gMain.state)
|
|
{
|
|
case 0:
|
|
default:
|
|
SetVBlankCallback(NULL);
|
|
ClearVramOamPltt_LoadHofPal();
|
|
sHofGfxPtr = AllocZeroed(sizeof(*sHofGfxPtr));
|
|
gMain.state = 1;
|
|
break;
|
|
case 1:
|
|
LoadHofGfx();
|
|
gMain.state++;
|
|
break;
|
|
case 2:
|
|
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
|
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
|
|
SetGpuReg(REG_OFFSET_BLDY, 0);
|
|
InitHofBgs();
|
|
gMain.state++;
|
|
break;
|
|
case 3:
|
|
if (!LoadHofBgs())
|
|
{
|
|
struct HallofFameTeam *fameTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
|
|
fameTeam->mon[0] = sDummyFameMon;
|
|
ComputerScreenOpenEffect(0, 0, 0);
|
|
SetVBlankCallback(VBlankCB_HallOfFame);
|
|
gMain.state++;
|
|
}
|
|
break;
|
|
case 4:
|
|
RunTasks();
|
|
AnimateSprites();
|
|
BuildOamBuffer();
|
|
UpdatePaletteFade();
|
|
if (!IsComputerScreenOpenEffectActive())
|
|
gMain.state++;
|
|
break;
|
|
case 5:
|
|
{
|
|
u8 taskId, i;
|
|
|
|
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
|
|
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 7));
|
|
SetGpuReg(REG_OFFSET_BLDY, 0);
|
|
taskId = CreateTask(Task_HofPC_CopySaveData, 0);
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE;
|
|
}
|
|
|
|
sHofMonPtr = AllocZeroed(SECTOR_SIZE * NUM_HOF_SECTORS);
|
|
SetMainCallback2(CB2_HallOfFame);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void Task_HofPC_CopySaveData(u8 taskId)
|
|
{
|
|
HofPCTopBar_AddWindow(0, 30, 0, 12, 0x226);
|
|
if (LoadGameSave(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK)
|
|
{
|
|
gTasks[taskId].func = Task_HofPC_PrintDataIsCorrupted;
|
|
}
|
|
else
|
|
{
|
|
u16 i;
|
|
struct HallofFameTeam* savedTeams;
|
|
|
|
CpuCopy16(gDecompressionBuffer, sHofMonPtr, SECTOR_SIZE * NUM_HOF_SECTORS);
|
|
savedTeams = sHofMonPtr;
|
|
for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++)
|
|
{
|
|
if (savedTeams->mon[0].species == SPECIES_NONE)
|
|
break;
|
|
}
|
|
|
|
if (i < HALL_OF_FAME_MAX_TEAMS)
|
|
gTasks[taskId].tCurrTeamNo = i - 1;
|
|
else
|
|
gTasks[taskId].tCurrTeamNo = HALL_OF_FAME_MAX_TEAMS - 1;
|
|
|
|
gTasks[taskId].tCurrPageNo = GetGameStat(GAME_STAT_ENTERED_HOF);
|
|
|
|
gTasks[taskId].func = Task_HofPC_DrawSpritesPrintText;
|
|
}
|
|
}
|
|
|
|
static void Task_HofPC_DrawSpritesPrintText(u8 taskId)
|
|
{
|
|
struct HallofFameTeam* savedTeams = sHofMonPtr;
|
|
struct HallofFameMon* currMon;
|
|
u16 i;
|
|
|
|
for (i = 0; i < gTasks[taskId].tCurrTeamNo; i++)
|
|
savedTeams++;
|
|
|
|
currMon = &savedTeams->mon[0];
|
|
sHofFadePalettes = 0;
|
|
gTasks[taskId].tCurrMonId = 0;
|
|
gTasks[taskId].tMonNo = 0;
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++, currMon++)
|
|
{
|
|
if (currMon->species != 0)
|
|
gTasks[taskId].tMonNo++;
|
|
}
|
|
|
|
currMon = &savedTeams->mon[0];
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++, currMon++)
|
|
{
|
|
if (currMon->species != 0)
|
|
{
|
|
u16 spriteId;
|
|
s16 posX, posY;
|
|
|
|
if (gTasks[taskId].tMonNo > PARTY_SIZE / 2)
|
|
{
|
|
posX = sHallOfFame_MonFullTeamPositions[i][2];
|
|
posY = sHallOfFame_MonFullTeamPositions[i][3];
|
|
}
|
|
else
|
|
{
|
|
posX = sHallOfFame_MonHalfTeamPositions[i][2];
|
|
posY = sHallOfFame_MonHalfTeamPositions[i][3];
|
|
}
|
|
|
|
if (currMon->species == SPECIES_EGG)
|
|
posY += 10;
|
|
|
|
spriteId = CreateMonPicSprite_HandleDeoxys(currMon->species, currMon->tid, currMon->personality, 1, posX, posY, i, TAG_NONE);
|
|
gSprites[spriteId].oam.priority = 1;
|
|
gTasks[taskId].tMonSpriteId(i) = spriteId;
|
|
}
|
|
else
|
|
{
|
|
gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE;
|
|
}
|
|
}
|
|
|
|
BlendPalettes(PALETTES_OBJECTS, 0xC, RGB(16, 29, 24));
|
|
|
|
ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tCurrPageNo, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
|
StringExpandPlaceholders(gStringVar4, gText_HOFNumber);
|
|
|
|
if (gTasks[taskId].tCurrTeamNo <= 0)
|
|
HofPCTopBar_PrintPair(gStringVar4, gText_PickCancel, FALSE, 0, TRUE);
|
|
else
|
|
HofPCTopBar_PrintPair(gStringVar4, gText_PickNextCancel, FALSE, 0, TRUE);
|
|
|
|
gTasks[taskId].func = Task_HofPC_PrintMonInfo;
|
|
}
|
|
|
|
static void Task_HofPC_PrintMonInfo(u8 taskId)
|
|
{
|
|
struct HallofFameTeam* savedTeams = sHofMonPtr;
|
|
struct HallofFameMon* currMon;
|
|
u16 i;
|
|
u16 currMonID;
|
|
|
|
for (i = 0; i < gTasks[taskId].tCurrTeamNo; i++)
|
|
savedTeams++;
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
u16 spriteId = gTasks[taskId].tMonSpriteId(i);
|
|
if (spriteId != SPRITE_NONE)
|
|
gSprites[spriteId].oam.priority = 1;
|
|
}
|
|
|
|
currMonID = gTasks[taskId].tMonSpriteId(gTasks[taskId].tCurrMonId);
|
|
gSprites[currMonID].oam.priority = 0;
|
|
sHofFadePalettes = (0x10000 << gSprites[currMonID].oam.paletteNum) ^ PALETTES_OBJECTS;
|
|
BlendPalettesUnfaded(sHofFadePalettes, 0xC, RGB(16, 29, 24));
|
|
|
|
currMon = &savedTeams->mon[gTasks[taskId].tCurrMonId];
|
|
if (currMon->species != SPECIES_EGG)
|
|
{
|
|
StopCryAndClearCrySongs();
|
|
PlayCry_Normal(currMon->species, 0);
|
|
}
|
|
HallOfFame_PrintMonInfo(currMon, 0, 14);
|
|
|
|
gTasks[taskId].func = Task_HofPC_HandleInput;
|
|
}
|
|
|
|
static void Task_HofPC_HandleInput(u8 taskId)
|
|
{
|
|
u16 i;
|
|
|
|
if (JOY_NEW(A_BUTTON))
|
|
{
|
|
if (gTasks[taskId].tCurrTeamNo != 0) // prepare another team to view
|
|
{
|
|
gTasks[taskId].tCurrTeamNo--;
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
u8 spriteId = gTasks[taskId].tMonSpriteId(i);
|
|
if (spriteId != SPRITE_NONE)
|
|
{
|
|
FreeAndDestroyMonPicSprite(spriteId);
|
|
gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE;
|
|
}
|
|
}
|
|
if (gTasks[taskId].tCurrPageNo != 0)
|
|
gTasks[taskId].tCurrPageNo--;
|
|
gTasks[taskId].func = Task_HofPC_DrawSpritesPrintText;
|
|
}
|
|
else // no more teams to view, turn off hall of fame PC
|
|
{
|
|
if (IsCryPlayingOrClearCrySongs())
|
|
{
|
|
StopCryAndClearCrySongs();
|
|
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
|
|
}
|
|
gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
|
|
}
|
|
}
|
|
else if (JOY_NEW(B_BUTTON)) // turn off hall of fame PC
|
|
{
|
|
if (IsCryPlayingOrClearCrySongs())
|
|
{
|
|
StopCryAndClearCrySongs();
|
|
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
|
|
}
|
|
gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
|
|
}
|
|
else if (JOY_NEW(DPAD_UP) && gTasks[taskId].tCurrMonId != 0) // change mon -1
|
|
{
|
|
gTasks[taskId].tCurrMonId--;
|
|
gTasks[taskId].func = Task_HofPC_PrintMonInfo;
|
|
}
|
|
else if (JOY_NEW(DPAD_DOWN) && gTasks[taskId].tCurrMonId < gTasks[taskId].tMonNo - 1) // change mon +1
|
|
{
|
|
gTasks[taskId].tCurrMonId++;
|
|
gTasks[taskId].func = Task_HofPC_PrintMonInfo;
|
|
}
|
|
}
|
|
|
|
static void Task_HofPC_HandlePaletteOnExit(u8 taskId)
|
|
{
|
|
struct HallofFameTeam* fameTeam;
|
|
|
|
CpuCopy16(gPlttBufferFaded, gPlttBufferUnfaded, 0x400);
|
|
fameTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
|
|
fameTeam->mon[0] = sDummyFameMon;
|
|
ComputerScreenCloseEffect(0, 0, 0);
|
|
gTasks[taskId].func = Task_HofPC_HandleExit;
|
|
}
|
|
|
|
static void Task_HofPC_HandleExit(u8 taskId)
|
|
{
|
|
if (!IsComputerScreenCloseEffectActive())
|
|
{
|
|
u8 i;
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
u16 spriteId = gTasks[taskId].tMonSpriteId(i);
|
|
if (spriteId != SPRITE_NONE)
|
|
{
|
|
FreeAndDestroyMonPicSprite(spriteId);
|
|
gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE;
|
|
}
|
|
}
|
|
|
|
HideBg(0);
|
|
HideBg(1);
|
|
HideBg(3);
|
|
HofPCTopBar_RemoveWindow();
|
|
FreeAllWindowBuffers();
|
|
UnsetBgTilemapBuffer(1);
|
|
UnsetBgTilemapBuffer(3);
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
|
DestroyTask(taskId);
|
|
|
|
TRY_FREE_AND_SET_NULL(sHofGfxPtr);
|
|
TRY_FREE_AND_SET_NULL(sHofMonPtr);
|
|
|
|
ReturnFromHallOfFamePC();
|
|
}
|
|
}
|
|
|
|
static void Task_HofPC_PrintDataIsCorrupted(u8 taskId)
|
|
{
|
|
HofPCTopBar_Print(gText_AButtonExit, 8, TRUE);
|
|
DrawDialogueFrame(0, FALSE);
|
|
AddTextPrinterParameterized2(0, FONT_NORMAL, gText_HOFCorrupted, 0, NULL, 2, 1, 3);
|
|
CopyWindowToVram(0, COPYWIN_FULL);
|
|
gTasks[taskId].func = Task_HofPC_ExitOnButtonPress;
|
|
}
|
|
|
|
static void Task_HofPC_ExitOnButtonPress(u8 taskId)
|
|
{
|
|
if (JOY_NEW(A_BUTTON))
|
|
gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
|
|
}
|
|
|
|
#undef tCurrTeamNo
|
|
#undef tCurrPageNo
|
|
#undef tCurrMonId
|
|
#undef tMonNo
|
|
#undef tMonSpriteId
|
|
|
|
static void HallOfFame_PrintWelcomeText(u8 unusedPossiblyWindowId, u8 unused2)
|
|
{
|
|
FillWindowPixelBuffer(0, PIXEL_FILL(0));
|
|
PutWindowTilemap(0);
|
|
AddTextPrinterParameterized3(0, FONT_NORMAL, GetStringCenterAlignXOffset(FONT_NORMAL, gText_WelcomeToHOF, 0xD0), 1, sMonInfoTextColors, 0, gText_WelcomeToHOF);
|
|
CopyWindowToVram(0, COPYWIN_FULL);
|
|
}
|
|
|
|
static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u8 unused2)
|
|
{
|
|
u8 text[30];
|
|
u8 *stringPtr;
|
|
s32 dexNumber;
|
|
s32 width;
|
|
|
|
FillWindowPixelBuffer(0, PIXEL_FILL(0));
|
|
PutWindowTilemap(0);
|
|
|
|
// dex number
|
|
if (currMon->species != SPECIES_EGG)
|
|
{
|
|
stringPtr = StringCopy(text, gText_Number);
|
|
dexNumber = SpeciesToPokedexNum(currMon->species);
|
|
if (dexNumber != 0xFFFF)
|
|
{
|
|
stringPtr[0] = (dexNumber / 100) + CHAR_0;
|
|
stringPtr++;
|
|
dexNumber %= 100;
|
|
stringPtr[0] = (dexNumber / 10) + CHAR_0;
|
|
stringPtr++;
|
|
stringPtr[0] = (dexNumber % 10) + CHAR_0;
|
|
stringPtr++;
|
|
}
|
|
else
|
|
{
|
|
*(stringPtr)++ = CHAR_QUESTION_MARK;
|
|
*(stringPtr)++ = CHAR_QUESTION_MARK;
|
|
*(stringPtr)++ = CHAR_QUESTION_MARK;
|
|
}
|
|
stringPtr[0] = EOS;
|
|
AddTextPrinterParameterized3(0, FONT_NORMAL, 0x10, 1, sMonInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
}
|
|
|
|
// nick, species names, gender and level
|
|
memcpy(text, currMon->nick, POKEMON_NAME_LENGTH);
|
|
text[POKEMON_NAME_LENGTH] = EOS;
|
|
if (currMon->species == SPECIES_EGG)
|
|
{
|
|
width = GetStringCenterAlignXOffset(FONT_NORMAL, text, 0xD0);
|
|
AddTextPrinterParameterized3(0, FONT_NORMAL, width, 1, sMonInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
CopyWindowToVram(0, COPYWIN_FULL);
|
|
}
|
|
else
|
|
{
|
|
width = GetStringRightAlignXOffset(FONT_NORMAL, text, 0x80);
|
|
AddTextPrinterParameterized3(0, FONT_NORMAL, width, 1, sMonInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
|
|
text[0] = CHAR_SLASH;
|
|
stringPtr = StringCopy(text + 1, gSpeciesNames[currMon->species]);
|
|
|
|
if (currMon->species != SPECIES_NIDORAN_M && currMon->species != SPECIES_NIDORAN_F)
|
|
{
|
|
switch (GetGenderFromSpeciesAndPersonality(currMon->species, currMon->personality))
|
|
{
|
|
case MON_MALE:
|
|
stringPtr[0] = CHAR_MALE;
|
|
stringPtr++;
|
|
break;
|
|
case MON_FEMALE:
|
|
stringPtr[0] = CHAR_FEMALE;
|
|
stringPtr++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
stringPtr[0] = EOS;
|
|
AddTextPrinterParameterized3(0, FONT_NORMAL, 0x80, 1, sMonInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
|
|
stringPtr = StringCopy(text, gText_Level);
|
|
ConvertIntToDecimalStringN(stringPtr, currMon->lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
|
|
AddTextPrinterParameterized3(0, FONT_NORMAL, 0x24, 0x11, sMonInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
|
|
stringPtr = StringCopy(text, gText_IDNumber);
|
|
ConvertIntToDecimalStringN(stringPtr, (u16)(currMon->tid), STR_CONV_MODE_LEADING_ZEROS, 5);
|
|
AddTextPrinterParameterized3(0, FONT_NORMAL, 0x68, 0x11, sMonInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
|
|
CopyWindowToVram(0, COPYWIN_FULL);
|
|
}
|
|
}
|
|
|
|
static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2)
|
|
{
|
|
u8 text[20];
|
|
u32 width;
|
|
u16 trainerId;
|
|
|
|
FillWindowPixelBuffer(1, PIXEL_FILL(1));
|
|
PutWindowTilemap(1);
|
|
DrawStdFrameWithCustomTileAndPalette(1, FALSE, 0x21D, 0xD);
|
|
AddTextPrinterParameterized3(1, FONT_NORMAL, 0, 1, sPlayerInfoTextColors, TEXT_SKIP_DRAW, gText_Name);
|
|
|
|
width = GetStringRightAlignXOffset(FONT_NORMAL, gSaveBlock2Ptr->playerName, 0x70);
|
|
AddTextPrinterParameterized3(1, FONT_NORMAL, width, 1, sPlayerInfoTextColors, TEXT_SKIP_DRAW, gSaveBlock2Ptr->playerName);
|
|
|
|
trainerId = (gSaveBlock2Ptr->playerTrainerId[0]) | (gSaveBlock2Ptr->playerTrainerId[1] << 8);
|
|
AddTextPrinterParameterized3(1, FONT_NORMAL, 0, 0x11, sPlayerInfoTextColors, 0, gText_IDNumber);
|
|
text[0] = (trainerId % 100000) / 10000 + CHAR_0;
|
|
text[1] = (trainerId % 10000) / 1000 + CHAR_0;
|
|
text[2] = (trainerId % 1000) / 100 + CHAR_0;
|
|
text[3] = (trainerId % 100) / 10 + CHAR_0;
|
|
text[4] = (trainerId % 10) / 1 + CHAR_0;
|
|
text[5] = EOS;
|
|
width = GetStringRightAlignXOffset(FONT_NORMAL, text, 0x70);
|
|
AddTextPrinterParameterized3(1, FONT_NORMAL, width, 0x11, sPlayerInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
|
|
AddTextPrinterParameterized3(1, FONT_NORMAL, 0, 0x21, sPlayerInfoTextColors, TEXT_SKIP_DRAW, gText_Time);
|
|
text[0] = (gSaveBlock2Ptr->playTimeHours / 100) + CHAR_0;
|
|
text[1] = (gSaveBlock2Ptr->playTimeHours % 100) / 10 + CHAR_0;
|
|
text[2] = (gSaveBlock2Ptr->playTimeHours % 10) + CHAR_0;
|
|
|
|
if (text[0] == CHAR_0)
|
|
text[0] = CHAR_SPACE;
|
|
if (text[0] == CHAR_SPACE && text[1] == CHAR_0)
|
|
text[8] = CHAR_SPACE;
|
|
|
|
text[3] = CHAR_COLON;
|
|
text[4] = (gSaveBlock2Ptr->playTimeMinutes % 100) / 10 + CHAR_0;
|
|
text[5] = (gSaveBlock2Ptr->playTimeMinutes % 10) + CHAR_0;
|
|
text[6] = EOS;
|
|
|
|
width = GetStringRightAlignXOffset(FONT_NORMAL, text, 0x70);
|
|
AddTextPrinterParameterized3(1, FONT_NORMAL, width, 0x21, sPlayerInfoTextColors, TEXT_SKIP_DRAW, text);
|
|
|
|
CopyWindowToVram(1, COPYWIN_FULL);
|
|
}
|
|
|
|
static void ClearVramOamPltt_LoadHofPal(void)
|
|
{
|
|
u32 vramOffset, oamOffset, plttOffset;
|
|
u32 vramSize, oamSize, plttSize;
|
|
|
|
vramOffset = (VRAM);
|
|
vramSize = VRAM_SIZE;
|
|
while (TRUE)
|
|
{
|
|
DmaFill16(3, 0, vramOffset, 0x1000);
|
|
vramOffset += 0x1000;
|
|
vramSize -= 0x1000;
|
|
if (vramSize <= 0x1000)
|
|
{
|
|
DmaFill16(3, 0, vramOffset, vramSize);
|
|
break;
|
|
}
|
|
}
|
|
|
|
oamOffset = OAM;
|
|
oamSize = OAM_SIZE;
|
|
DmaFill32(3, 0, oamOffset, oamSize);
|
|
|
|
plttOffset = PLTT;
|
|
plttSize = PLTT_SIZE;
|
|
DmaFill16(3, 0, plttOffset, plttSize);
|
|
|
|
ResetPaletteFade();
|
|
LoadPalette(sHallOfFame_Pal, 0, 0x20);
|
|
}
|
|
|
|
static void LoadHofGfx(void)
|
|
{
|
|
ScanlineEffect_Stop();
|
|
ResetTasks();
|
|
ResetSpriteData();
|
|
ResetTempTileDataBuffers();
|
|
ResetAllPicSprites();
|
|
FreeAllSpritePalettes();
|
|
gReservedSpritePaletteCount = 8;
|
|
LoadCompressedSpriteSheet(sSpriteSheet_Confetti);
|
|
LoadCompressedSpritePalette(sSpritePalette_Confetti);
|
|
}
|
|
|
|
static void InitHofBgs(void)
|
|
{
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
|
InitBgsFromTemplates(0, sHof_BgTemplates, ARRAY_COUNT(sHof_BgTemplates));
|
|
SetBgTilemapBuffer(1, sHofGfxPtr->tilemap1);
|
|
SetBgTilemapBuffer(3, sHofGfxPtr->tilemap2);
|
|
ChangeBgX(0, 0, BG_COORD_SET);
|
|
ChangeBgY(0, 0, BG_COORD_SET);
|
|
ChangeBgX(1, 0, BG_COORD_SET);
|
|
ChangeBgY(1, 0, BG_COORD_SET);
|
|
ChangeBgX(3, 0, BG_COORD_SET);
|
|
ChangeBgY(3, 0, BG_COORD_SET);
|
|
}
|
|
|
|
static bool8 LoadHofBgs(void)
|
|
{
|
|
switch (sHofGfxPtr->state)
|
|
{
|
|
case 0:
|
|
DecompressAndCopyTileDataToVram(1, sHallOfFame_Gfx, 0, 0, 0);
|
|
break;
|
|
case 1:
|
|
if (FreeTempTileDataBuffersIfPossible())
|
|
return TRUE;
|
|
break;
|
|
case 2:
|
|
FillBgTilemapBufferRect_Palette0(1, 1, 0, 0, 0x20, 2);
|
|
FillBgTilemapBufferRect_Palette0(1, 0, 0, 3, 0x20, 0xB);
|
|
FillBgTilemapBufferRect_Palette0(1, 1, 0, 0xE, 0x20, 6);
|
|
FillBgTilemapBufferRect_Palette0(3, 2, 0, 0, 0x20, 0x20);
|
|
|
|
CopyBgTilemapBufferToVram(1);
|
|
CopyBgTilemapBufferToVram(3);
|
|
break;
|
|
case 3:
|
|
InitStandardTextBoxWindows();
|
|
InitTextBoxGfxAndPrinters();
|
|
break;
|
|
case 4:
|
|
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
|
|
ShowBg(0);
|
|
ShowBg(1);
|
|
ShowBg(3);
|
|
sHofGfxPtr->state = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
sHofGfxPtr->state++;
|
|
return TRUE;
|
|
}
|
|
|
|
static void SpriteCB_GetOnScreenAndAnimate(struct Sprite *sprite)
|
|
{
|
|
if (sprite->x != sprite->tDestinationX
|
|
|| sprite->y != sprite->tDestinationY)
|
|
{
|
|
if (sprite->x < sprite->tDestinationX)
|
|
sprite->x += 15;
|
|
if (sprite->x > sprite->tDestinationX)
|
|
sprite->x -= 15;
|
|
|
|
if (sprite->y < sprite->tDestinationY)
|
|
sprite->y += 10;
|
|
if (sprite->y > sprite->tDestinationY)
|
|
sprite->y -= 10;
|
|
}
|
|
else
|
|
{
|
|
s16 species = sprite->tSpecies;
|
|
|
|
if (species == SPECIES_EGG)
|
|
DoMonFrontSpriteAnimation(sprite, species, TRUE, 3);
|
|
else
|
|
DoMonFrontSpriteAnimation(sprite, species, FALSE, 3);
|
|
}
|
|
}
|
|
|
|
#undef tDestinationX
|
|
#undef tDestinationY
|
|
#undef tSpecies
|
|
|
|
#define sSineIdx data[0]
|
|
#define sExtraY data[1]
|
|
|
|
static void SpriteCB_HofConfetti(struct Sprite* sprite)
|
|
{
|
|
if (sprite->y2 > 120)
|
|
{
|
|
DestroySprite(sprite);
|
|
}
|
|
else
|
|
{
|
|
u16 rand;
|
|
u8 sineIdx;
|
|
|
|
sprite->y2++;
|
|
sprite->y2 += sprite->sExtraY;
|
|
|
|
sineIdx = sprite->sSineIdx;
|
|
rand = (Random() % 4) + 8;
|
|
sprite->x2 = rand * gSineTable[sineIdx] / 256;
|
|
|
|
sprite->sSineIdx += 4;
|
|
}
|
|
}
|
|
|
|
static bool8 CreateHofConfettiSprite(void)
|
|
{
|
|
u8 spriteID;
|
|
struct Sprite* sprite;
|
|
|
|
s16 posX = Random() % DISPLAY_WIDTH;
|
|
s16 posY = -(Random() % 8);
|
|
|
|
spriteID = CreateSprite(&sSpriteTemplate_HofConfetti, posX, posY, 0);
|
|
sprite = &gSprites[spriteID];
|
|
|
|
StartSpriteAnim(sprite, Random() % ARRAY_COUNT(sAnims_Confetti));
|
|
|
|
// 1/4 confetti sprites move an extra Y coord each frame
|
|
if (Random() & 3)
|
|
sprite->sExtraY = 0;
|
|
else
|
|
sprite->sExtraY = 1;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// The below confetti functions are used when a Battle Dome tourney is won
|
|
// For the Hall of Fame confetti see Task_Hof_DoConfetti
|
|
// The end result is essentially the same, just a very different way of handling it
|
|
#define tState data[0]
|
|
#define tTimer data[1]
|
|
#define tConfettiCount data[15]
|
|
|
|
// Indexes into the data array of the struct ConfettiUtil
|
|
#define CONFETTI_SINE_IDX 0
|
|
#define CONFETTI_EXTRA_Y 1
|
|
#define CONFETTI_TASK_ID 7
|
|
|
|
void DoDomeConfetti(void)
|
|
{
|
|
u8 taskId;
|
|
|
|
gSpecialVar_0x8004 = 180;
|
|
taskId = CreateTask(Task_DoDomeConfetti, 0);
|
|
if (taskId != TASK_NONE)
|
|
{
|
|
gTasks[taskId].tTimer = gSpecialVar_0x8004;
|
|
gSpecialVar_0x8005 = taskId;
|
|
}
|
|
}
|
|
|
|
static void StopDomeConfetti(void)
|
|
{
|
|
u8 taskId;
|
|
|
|
if ((taskId = FindTaskIdByFunc(Task_DoDomeConfetti)) != TASK_NONE)
|
|
DestroyTask(taskId);
|
|
|
|
ConfettiUtil_Free();
|
|
FreeSpriteTilesByTag(TAG_CONFETTI);
|
|
FreeSpritePaletteByTag(TAG_CONFETTI);
|
|
}
|
|
|
|
static void UpdateDomeConfetti(struct ConfettiUtil *util)
|
|
{
|
|
if (util->yDelta > 110)
|
|
{
|
|
// Destroy confetti after it falls far enough
|
|
gTasks[util->data[CONFETTI_TASK_ID]].tConfettiCount--;
|
|
ConfettiUtil_Remove(util->id);
|
|
}
|
|
else
|
|
{
|
|
// Move confetti down
|
|
u8 sineIdx;
|
|
s32 rand;
|
|
|
|
util->yDelta++;
|
|
util->yDelta += util->data[CONFETTI_EXTRA_Y];
|
|
|
|
sineIdx = util->data[CONFETTI_SINE_IDX];
|
|
rand = Random();
|
|
rand &= 3;
|
|
rand += 8;
|
|
util->xDelta = (rand) * ((gSineTable[sineIdx])) / 256;
|
|
|
|
util->data[CONFETTI_SINE_IDX] += 4;
|
|
}
|
|
}
|
|
|
|
static void Task_DoDomeConfetti(u8 taskId)
|
|
{
|
|
u32 id = 0;
|
|
u16 *data = gTasks[taskId].data;
|
|
|
|
switch (tState)
|
|
{
|
|
case 0:
|
|
if (!ConfettiUtil_Init(64))
|
|
{
|
|
// Init failed
|
|
DestroyTask(taskId);
|
|
gSpecialVar_0x8004 = 0;
|
|
gSpecialVar_0x8005 = 0xFFFF;
|
|
}
|
|
LoadCompressedSpriteSheet(sSpriteSheet_Confetti);
|
|
LoadCompressedSpritePalette(sSpritePalette_Confetti);
|
|
tState++;
|
|
break;
|
|
case 1:
|
|
if (tTimer != 0 && tTimer % 3 == 0)
|
|
{
|
|
// Create new confetti every 3 frames
|
|
id = ConfettiUtil_AddNew(&sOamData_Confetti,
|
|
TAG_CONFETTI,
|
|
TAG_CONFETTI,
|
|
Random() % DISPLAY_WIDTH,
|
|
-(Random() % 8),
|
|
Random() % ARRAY_COUNT(sAnims_Confetti),
|
|
id);
|
|
if (id != 0xFF)
|
|
{
|
|
ConfettiUtil_SetCallback(id, UpdateDomeConfetti);
|
|
|
|
// 1/4 of the confetti move an extra y coord every frame
|
|
if ((Random() % 4) == 0)
|
|
ConfettiUtil_SetData(id, CONFETTI_EXTRA_Y, 1);
|
|
|
|
ConfettiUtil_SetData(id, CONFETTI_TASK_ID, taskId);
|
|
tConfettiCount++;
|
|
}
|
|
}
|
|
|
|
ConfettiUtil_Update();
|
|
if (tTimer != 0)
|
|
tTimer--;
|
|
else if (tConfettiCount == 0)
|
|
tState = 0xFF;
|
|
break;
|
|
case 0xFF:
|
|
StopDomeConfetti();
|
|
gSpecialVar_0x8004 = 0;
|
|
gSpecialVar_0x8005 = 0xFFFF;
|
|
break;
|
|
}
|
|
}
|