pokeemerald/src/credits.c

1616 lines
45 KiB
C
Raw Normal View History

2018-02-17 10:55:32 +01:00
#include "global.h"
#include "palette.h"
#include "main.h"
#include "task.h"
#include "bg.h"
#include "malloc.h"
2018-02-17 10:55:32 +01:00
#include "window.h"
#include "text.h"
#include "menu.h"
#include "international_string_util.h"
#include "constants/songs.h"
#include "gpu_regs.h"
#include "m4a.h"
#include "constants/rgb.h"
2018-08-19 01:06:10 +02:00
#include "trainer_pokemon_sprites.h"
2018-02-17 10:55:32 +01:00
#include "starter_choose.h"
#include "decompress.h"
#include "intro_credits_graphics.h"
#include "sound.h"
#include "trig.h"
#include "graphics.h"
#include "pokedex.h"
#include "event_data.h"
#include "random.h"
#define COLOR_DARK_GREEN RGB(7, 11, 6)
#define COLOR_LIGHT_GREEN RGB(13, 20, 12)
2021-03-29 05:56:42 +02:00
#define TAG_MON_BG 1001
// Positions for the Pokémon images
enum {
POS_LEFT,
POS_CENTER,
POS_RIGHT,
};
#define tPlayerSpriteId data[5]
#define tRivalSpriteId data[6]
2018-02-17 10:55:32 +01:00
enum
{
TDA_0 = 0,
TDA_TASK_C_ID = 1,
TDA_TASK_E_ID = 2,
TDA_TASK_D_ID = 3,
TDA_4 = 4,
TDA_PLAYER_CYCLIST = 5,
TDA_RIVAL_CYCLIST = 6,
TDA_7 = 7, // Has something to do with the bike scene
TDA_11 = 11, // Gets set depending on whether the bike or the grass scene should be shown
TDA_12 = 12,
TDA_13 = 13,
TDA_14 = 14,
TDA_TASK_B_ID = 15,
// Appears to be responsible for text
TDB_0 = 0,
TDB_TASK_A_ID = 1,
TDB_CURRENT_PAGE = 2,
TDB_3 = 3,
TDC_0 = 0,
TDC_1 = 1,
TDC_2 = 2,
TDC_3 = 3,
TDC_4 = 4,
TDC_5 = 5,
TDD_STATE = 0,
TDD_TASK_A_ID = 1,
TDD_2 = 2,
TDD_3 = 3,
TDE_0 = 0,
TDE_1 = 1,
TDE_TASK_A_ID = 2,
};
2019-11-04 17:38:09 +01:00
#define NUM_MON_SLIDES 71
2019-11-03 06:33:46 +01:00
struct CreditsData
{
2019-11-04 17:38:09 +01:00
u16 monToShow[NUM_MON_SLIDES]; // List of Pokemon species ids that will show during the credits
2019-11-03 06:33:46 +01:00
u16 imgCounter; //how many mon images have been shown
u16 nextImgPos; //if the next image spawns left/center/right
2019-11-04 17:38:09 +01:00
u16 currShownMon; //index into monToShow
u16 numMonToShow; //number of pokemon to show, always NUM_MON_SLIDES after determine function
u16 caughtMonIds[NATIONAL_DEX_COUNT]; //temporary location to hold a condensed array of all caught pokemon
u16 numCaughtMon; //count of filled spaces in caughtMonIds
u16 unused[7];
2018-02-17 10:55:32 +01:00
};
struct CreditsEntry
{
2021-03-29 05:56:42 +02:00
u8 unk; // Never read
2019-08-17 19:32:26 +02:00
bool8 isTitle;
2018-02-17 10:55:32 +01:00
const u8 *text;
};
2021-03-29 05:56:42 +02:00
static EWRAM_DATA s16 sUnkVar = 0; // Never read, only set to 0
static EWRAM_DATA u16 sSavedTaskId = 0;
2018-02-17 10:55:32 +01:00
EWRAM_DATA bool8 gHasHallOfFameRecords = 0;
2021-03-29 05:56:42 +02:00
static EWRAM_DATA bool8 sUsedSpeedUp = 0; // Never read
2019-11-03 06:33:46 +01:00
static EWRAM_DATA struct CreditsData *sCreditsData = {0};
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
static const u16 sCredits_Pal[] = INCBIN_U16("graphics/credits/credits.gbapal");
static const u32 sCreditsCopyrightEnd_Gfx[] = INCBIN_U32("graphics/credits/the_end_copyright.4bpp.lz");
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
static void SpriteCB_CreditsMonBg(struct Sprite *);
static void Task_WaitPaletteFade(u8);
static void Task_ProgressCreditTasks(u8);
static void sub_8175808(u8);
static void c2_080C9BFC(u8);
static void Task_CreditsLoadGrassScene(u8);
static void sub_81758A4(u8);
static void Task_CreditsTheEnd1(u8);
static void Task_CreditsTheEnd2(u8);
static void Task_CreditsTheEnd3(u8);
static void Task_CreditsTheEnd4(u8);
static void Task_CreditsTheEnd5(u8);
static void Task_CreditsTheEnd6(u8);
static void Task_CreditsSoftReset(u8);
static void ResetGpuAndVram(void);
static void sub_8175DA0(u8);
static u8 CheckChangeScene(u8, u8);
static void sub_81760FC(u8);
static void sub_817651C(u8);
static void sub_817624C(u8);
static bool8 sub_8176AB0(u8 data, u8);
static void ResetCreditsTasks(u8);
static void LoadTheEndScreen(u16, u16, u16);
static void DrawTheEnd(u16, u16);
static void SpriteCB_PlayerCyclist(struct Sprite *);
static void SpriteCB_RivalCyclist(struct Sprite *);
static u8 CreateCreditsMonSprite(u16, s16, s16, u16);
static void DeterminePokemonToShow(void);
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
static const u8 sTheEnd_LetterMap_T[] =
2018-02-17 10:55:32 +01:00
{
0, 1, 0,
0xFF, 1, 0xFF,
0xFF, 1, 0xFF,
0xFF, 1, 0xFF,
0xFF, 1, 0xFF,
};
2021-03-29 05:56:42 +02:00
static const u8 sTheEnd_LetterMap_H[] =
2018-02-17 10:55:32 +01:00
{
1, 0xFF, 1,
1, 0xFF, 1,
1, 2, 1,
1, 0xFF, 1,
1, 0xFF, 1,
};
2021-03-29 05:56:42 +02:00
static const u8 sTheEnd_LetterMap_E[] =
2018-02-17 10:55:32 +01:00
{
1, 0, 0,
1, 0xFF, 0xFF,
1, 2, 2,
1, 0xFF, 0xFF,
1, 0x80, 0x80,
};
2021-03-29 05:56:42 +02:00
static const u8 sTheEnd_LetterMap_N[] =
2018-02-17 10:55:32 +01:00
{
1, 3, 1,
1, 4, 1,
1, 5, 1,
1, 0xC4, 1,
1, 0xC3, 1,
};
2021-03-29 05:56:42 +02:00
static const u8 sTheEnd_LetterMap_D[] =
2018-02-17 10:55:32 +01:00
{
1, 6, 7,
1, 8, 9,
1, 0xFF, 1,
1, 0x88, 0x89,
1, 0x86, 0x87,
};
2021-03-29 05:56:42 +02:00
#include "data/credits.h"
2018-02-17 10:55:32 +01:00
2019-08-17 18:01:38 +02:00
static const struct BgTemplate sBackgroundTemplates[] =
2018-02-17 10:55:32 +01:00
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 28,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
};
2019-08-17 18:01:38 +02:00
static const struct WindowTemplate sWindowTemplates[] =
2018-02-17 10:55:32 +01:00
{
2018-09-02 18:53:52 +02:00
{
2018-10-27 00:53:07 +02:00
.bg = 0,
2018-09-02 18:53:52 +02:00
.tilemapLeft = 0,
.tilemapTop = 9,
.width = 30,
.height = 12,
.paletteNum = 8,
.baseBlock = 1
},
2018-02-17 10:55:32 +01:00
DUMMY_WIN_TEMPLATE,
};
2019-11-03 06:33:46 +01:00
static const u8 sMonSpritePos[][2] =
2018-02-17 10:55:32 +01:00
{
{104, 36},
{120, 36},
{136, 36},
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_Player_Slow[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(64, 8),
ANIMCMD_FRAME(128, 8),
ANIMCMD_FRAME(192, 8),
ANIMCMD_JUMP(0),
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_Player_Fast[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_FRAME(128, 4),
ANIMCMD_FRAME(192, 4),
ANIMCMD_JUMP(0),
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_Player_LookBack[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(256, 4),
ANIMCMD_FRAME(320, 4),
ANIMCMD_FRAME(384, 4),
ANIMCMD_END,
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_Player_LookForward[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(384, 30),
ANIMCMD_FRAME(320, 30),
ANIMCMD_FRAME(256, 30),
ANIMCMD_FRAME(256, 30),
ANIMCMD_END,
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd *const sAnims_Player[] =
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
sAnim_Player_Slow,
sAnim_Player_Fast,
sAnim_Player_LookBack,
sAnim_Player_LookForward,
2018-02-17 10:55:32 +01:00
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_Rival_Slow[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(64, 8),
ANIMCMD_FRAME(128, 8),
ANIMCMD_FRAME(192, 8),
ANIMCMD_JUMP(0),
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_Rival_Fast[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(64, 4),
ANIMCMD_FRAME(128, 4),
ANIMCMD_FRAME(192, 4),
ANIMCMD_JUMP(0),
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_Rival_Still[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_END,
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd *const sAnims_Rival[] =
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
sAnim_Rival_Slow,
sAnim_Rival_Fast,
sAnim_Rival_Still,
2018-02-17 10:55:32 +01:00
};
2021-03-29 15:38:19 +02:00
#define MONBG_OFFSET (MON_PIC_SIZE * 3)
2021-03-29 05:56:42 +02:00
static const struct SpriteSheet sSpriteSheet_MonBg[] = {
{ gDecompressionBuffer, MONBG_OFFSET, TAG_MON_BG },
{},
2018-02-17 10:55:32 +01:00
};
2021-03-29 05:56:42 +02:00
static const struct SpritePalette sSpritePalette_MonBg[] = {
{ (const u16 *)&gDecompressionBuffer[MONBG_OFFSET], TAG_MON_BG },
{},
2018-02-17 10:55:32 +01:00
};
2021-03-29 05:56:42 +02:00
static const struct OamData sOamData_MonBg =
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
.y = DISPLAY_HEIGHT,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2018-02-17 10:55:32 +01:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(64x64),
2018-02-17 10:55:32 +01:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(64x64),
2018-02-17 10:55:32 +01:00
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0,
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_MonBg_Yellow[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_END,
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_MonBg_Red[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(64, 8),
ANIMCMD_END,
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd sAnim_MonBg_Blue[] =
2018-02-17 10:55:32 +01:00
{
ANIMCMD_FRAME(128, 8),
ANIMCMD_END,
};
2021-03-29 05:56:42 +02:00
static const union AnimCmd *const sAnims_MonBg[] =
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
[POS_LEFT] = sAnim_MonBg_Yellow,
[POS_CENTER] = sAnim_MonBg_Red,
[POS_RIGHT] = sAnim_MonBg_Blue,
2018-02-17 10:55:32 +01:00
};
2021-03-29 05:56:42 +02:00
static const struct SpriteTemplate sSpriteTemplate_CreditsMonBg =
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
.tileTag = TAG_MON_BG,
.paletteTag = TAG_MON_BG,
.oam = &sOamData_MonBg,
.anims = sAnims_MonBg,
2018-02-17 10:55:32 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2021-03-29 05:56:42 +02:00
.callback = SpriteCB_CreditsMonBg,
2018-02-17 10:55:32 +01:00
};
2021-03-29 05:56:42 +02:00
static void VBlankCB_Credits(void)
2018-02-17 10:55:32 +01:00
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
2021-03-29 05:56:42 +02:00
static void CB2_Credits(void)
2018-02-17 10:55:32 +01:00
{
RunTasks();
AnimateSprites();
2018-10-27 00:53:07 +02:00
2020-09-05 03:11:55 +02:00
if ((JOY_HELD(B_BUTTON))
2021-03-29 05:56:42 +02:00
&& gHasHallOfFameRecords
&& gTasks[sSavedTaskId].func == Task_ProgressCreditTasks)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
// Speed up credits
VBlankCB_Credits();
2018-02-17 10:55:32 +01:00
RunTasks();
AnimateSprites();
2021-03-29 05:56:42 +02:00
sUsedSpeedUp = TRUE;
2018-02-17 10:55:32 +01:00
}
BuildOamBuffer();
UpdatePaletteFade();
}
static void InitCreditsBgsAndWindows(void)
2018-02-17 10:55:32 +01:00
{
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sBackgroundTemplates, ARRAY_COUNT(sBackgroundTemplates));
2020-08-24 00:50:57 +02:00
SetBgTilemapBuffer(0, AllocZeroed(BG_SCREEN_SIZE));
2021-03-29 05:56:42 +02:00
LoadPalette(sCredits_Pal, 0x80, 64);
2019-08-17 18:01:38 +02:00
InitWindows(sWindowTemplates);
2018-02-17 10:55:32 +01:00
DeactivateAllTextPrinters();
PutWindowTilemap(0);
CopyWindowToVram(0, 3);
ShowBg(0);
}
static void sub_81755A4(void)
{
void *ptr;
FreeAllWindowBuffers();
ptr = GetBgTilemapBuffer(0);
if (ptr)
Free(ptr);
}
2019-08-17 19:32:26 +02:00
static void PrintCreditsText(const u8 *string, u8 y, bool8 isTitle)
2018-02-17 10:55:32 +01:00
{
u8 x;
u8 color[3];
2018-10-27 00:53:07 +02:00
2021-03-29 05:56:42 +02:00
color[0] = TEXT_COLOR_TRANSPARENT;
2018-10-27 00:53:07 +02:00
2019-08-17 19:32:26 +02:00
if (isTitle == TRUE)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
color[1] = TEXT_COLOR_LIGHT_GREY;
color[2] = TEXT_COLOR_RED;
2018-02-17 10:55:32 +01:00
}
else
{
2021-03-29 05:56:42 +02:00
color[1] = TEXT_COLOR_WHITE;
color[2] = TEXT_COLOR_DARK_GREY;
2018-02-17 10:55:32 +01:00
}
2018-10-27 00:53:07 +02:00
2021-03-29 05:56:42 +02:00
x = GetStringCenterAlignXOffsetWithLetterSpacing(1, string, DISPLAY_WIDTH, 1);
AddTextPrinterParameterized4(0, 1, x, y, 1, 0, color, -1, string);
2018-02-17 10:55:32 +01:00
}
2019-08-17 18:01:38 +02:00
void CB2_StartCreditsSequence(void)
2018-02-17 10:55:32 +01:00
{
u8 taskIdA;
s16 taskIdC;
u8 taskIdB;
2019-08-17 18:01:38 +02:00
ResetGpuAndVram();
2018-02-17 10:55:32 +01:00
SetVBlankCallback(NULL);
InitHeap(gHeap, HEAP_SIZE);
ResetPaletteFade();
ResetTasks();
InitCreditsBgsAndWindows();
2018-02-17 10:55:32 +01:00
2019-08-17 18:01:38 +02:00
taskIdA = CreateTask(Task_WaitPaletteFade, 0);
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].data[TDA_4] = 0;
gTasks[taskIdA].data[TDA_7] = 0;
gTasks[taskIdA].data[TDA_11] = 0;
gTasks[taskIdA].data[TDA_13] = 1;
while (TRUE)
{
if (sub_8176AB0(0, taskIdA))
break;
}
taskIdC = gTasks[taskIdA].data[TDA_TASK_C_ID];
gTasks[taskIdC].data[TDC_0] = 40;
SetGpuReg(REG_OFFSET_BG0VOFS, 0xFFFC);
2018-10-27 00:53:07 +02:00
2018-02-17 10:55:32 +01:00
taskIdB = CreateTask(sub_8175DA0, 0);
gTasks[taskIdB].data[TDB_TASK_A_ID] = taskIdA;
gTasks[taskIdA].data[TDA_TASK_B_ID] = taskIdB;
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
2018-02-17 10:55:32 +01:00
EnableInterrupts(INTR_FLAG_VBLANK);
2021-03-29 05:56:42 +02:00
SetVBlankCallback(VBlankCB_Credits);
2020-08-21 00:02:00 +02:00
m4aSongNumStart(MUS_CREDITS);
2021-03-29 05:56:42 +02:00
SetMainCallback2(CB2_Credits);
sUsedSpeedUp = FALSE;
2019-11-03 06:33:46 +01:00
sCreditsData = AllocZeroed(sizeof(struct CreditsData));
2018-02-17 10:55:32 +01:00
2019-11-03 06:33:46 +01:00
DeterminePokemonToShow();
2018-02-17 10:55:32 +01:00
2019-11-03 06:33:46 +01:00
sCreditsData->imgCounter = 0;
2021-03-29 05:56:42 +02:00
sCreditsData->nextImgPos = POS_LEFT;
2019-11-04 17:38:09 +01:00
sCreditsData->currShownMon = 0;
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
sSavedTaskId = taskIdA;
2018-02-17 10:55:32 +01:00
}
2019-08-17 18:01:38 +02:00
static void Task_WaitPaletteFade(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
if (!gPaletteFade.active)
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_ProgressCreditTasks;
2018-02-17 10:55:32 +01:00
}
2019-08-17 18:01:38 +02:00
static void Task_ProgressCreditTasks(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
u16 data1;
if (gTasks[taskIdA].data[TDA_4])
{
s16 taskIdC;
taskIdC = gTasks[taskIdA].data[TDA_TASK_C_ID];
gTasks[taskIdC].data[TDC_0] = 30;
gTasks[taskIdA].data[TDA_12] = 0x100;
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_CreditsTheEnd1;
2018-02-17 10:55:32 +01:00
return;
}
2021-03-29 05:56:42 +02:00
sUnkVar = 0;
2018-02-17 10:55:32 +01:00
data1 = gTasks[taskIdA].data[TDA_11];
if (gTasks[taskIdA].data[TDA_11] == 1)
{
gTasks[taskIdA].data[TDA_13] = data1;
gTasks[taskIdA].data[TDA_11] = 0;
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].func = sub_8175808;
}
else if (gTasks[taskIdA].data[TDA_11] == 2)
{
gTasks[taskIdA].data[TDA_13] = data1;
gTasks[taskIdA].data[TDA_11] = 0;
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].func = sub_81758A4;
}
}
static void sub_8175808(u8 taskIdA)
{
if (!gPaletteFade.active)
{
SetGpuReg(REG_OFFSET_DISPCNT, 0);
2019-08-17 18:01:38 +02:00
ResetCreditsTasks(taskIdA);
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].func = c2_080C9BFC;
}
}
static void c2_080C9BFC(u8 taskIdA)
{
SetVBlankCallback(NULL);
if (sub_8176AB0(gTasks[taskIdA].data[TDA_7], taskIdA))
{
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
2018-02-17 10:55:32 +01:00
EnableInterrupts(INTR_FLAG_VBLANK);
2021-03-29 05:56:42 +02:00
SetVBlankCallback(VBlankCB_Credits);
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_WaitPaletteFade;
2018-02-17 10:55:32 +01:00
}
}
static void sub_81758A4(u8 taskIdA)
{
if (!gPaletteFade.active)
{
SetGpuReg(REG_OFFSET_DISPCNT, 0);
2019-08-17 18:01:38 +02:00
ResetCreditsTasks(taskIdA);
gTasks[taskIdA].func = Task_CreditsLoadGrassScene;
2018-02-17 10:55:32 +01:00
}
}
2019-08-17 18:01:38 +02:00
static void Task_CreditsLoadGrassScene(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
switch (gMain.state)
{
default:
case 0:
{
u16 i;
u16 *temp;
ResetSpriteData();
2018-08-19 01:06:10 +02:00
ResetAllPicSprites();
2018-02-17 10:55:32 +01:00
FreeAllSpritePalettes();
gReservedSpritePaletteCount = 8;
2018-10-21 09:24:57 +02:00
LZ77UnCompVram(gBirchHelpGfx, (void *)VRAM);
LZ77UnCompVram(gBirchGrassTilemap, (void *)(BG_SCREEN_ADDR(7)));
2018-02-17 10:55:32 +01:00
LoadPalette(gBirchBagGrassPal[0] + 1, 1, 31 * 2);
2021-03-29 15:38:19 +02:00
for (i = 0; i < MON_PIC_SIZE; i++)
2018-02-17 10:55:32 +01:00
gDecompressionBuffer[i] = 0x11;
2021-03-29 15:38:19 +02:00
for (i = 0; i < MON_PIC_SIZE; i++)
(gDecompressionBuffer + MON_PIC_SIZE)[i] = 0x22;
for (i = 0; i < MON_PIC_SIZE; i++)
(gDecompressionBuffer + MON_PIC_SIZE * 2)[i] = 0x33;
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
temp = (u16 *)(&gDecompressionBuffer[MONBG_OFFSET]);
2018-02-17 10:55:32 +01:00
temp[0] = RGB_BLACK;
temp[1] = RGB(31, 31, 20); // light yellow
temp[2] = RGB(31, 20, 20); // light red
temp[3] = RGB(20, 20, 31); // light blue
2021-03-29 05:56:42 +02:00
LoadSpriteSheet(sSpriteSheet_MonBg);
LoadSpritePalette(sSpritePalette_MonBg);
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
gMain.state++;
2018-02-17 10:55:32 +01:00
break;
}
case 1:
gTasks[taskIdA].data[TDA_TASK_D_ID] = CreateTask(sub_81760FC, 0);
gTasks[gTasks[taskIdA].data[TDA_TASK_D_ID]].data[TDD_STATE] = 1;
gTasks[gTasks[taskIdA].data[TDA_TASK_D_ID]].data[TDD_TASK_A_ID] = taskIdA;
gTasks[gTasks[taskIdA].data[TDA_TASK_D_ID]].data[TDD_2] = gTasks[taskIdA].data[TDA_7];
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
2018-02-17 10:55:32 +01:00
SetGpuReg(REG_OFFSET_BG3HOFS, 0);
SetGpuReg(REG_OFFSET_BG3VOFS, 32);
SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_PRIORITY(3)
| BGCNT_CHARBASE(0)
| BGCNT_SCREENBASE(7)
| BGCNT_16COLOR
| BGCNT_TXT256x256);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
| DISPCNT_OBJ_1D_MAP
| DISPCNT_BG0_ON
| DISPCNT_BG3_ON
| DISPCNT_OBJ_ON);
gMain.state = 0;
2021-03-29 05:56:42 +02:00
gIntroCredits_MovingSceneryState = INTROCRED_SCENERY_NORMAL;
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_WaitPaletteFade;
2018-02-17 10:55:32 +01:00
break;
}
}
2019-08-17 18:01:38 +02:00
static void Task_CreditsTheEnd1(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
if (gTasks[taskIdA].data[TDA_12])
{
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].data[TDA_12]--;
2018-02-17 10:55:32 +01:00
return;
}
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 12, 0, 16, RGB_BLACK);
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_CreditsTheEnd2;
2018-02-17 10:55:32 +01:00
}
2019-08-17 18:01:38 +02:00
static void Task_CreditsTheEnd2(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
if (!gPaletteFade.active)
{
2019-08-17 18:01:38 +02:00
ResetCreditsTasks(taskIdA);
gTasks[taskIdA].func = Task_CreditsTheEnd3;
2018-02-17 10:55:32 +01:00
}
}
2021-03-29 05:56:42 +02:00
#define tDelay data[0]
2019-08-17 18:01:38 +02:00
static void Task_CreditsTheEnd3(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
2019-08-17 18:01:38 +02:00
ResetGpuAndVram();
2018-02-17 10:55:32 +01:00
ResetPaletteFade();
2019-08-17 18:01:38 +02:00
LoadTheEndScreen(0, 0x3800, 0);
2018-02-17 10:55:32 +01:00
ResetSpriteData();
FreeAllSpritePalettes();
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 8, 16, 0, RGB_BLACK);
2018-02-17 10:55:32 +01:00
SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0)
| BGCNT_CHARBASE(0)
| BGCNT_SCREENBASE(7)
| BGCNT_16COLOR
| BGCNT_TXT256x256);
EnableInterrupts(INTR_FLAG_VBLANK);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
| DISPCNT_OBJ_1D_MAP
| DISPCNT_BG0_ON);
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tDelay = 235; //set this to 215 to actually show "THE END" in time to the last song beat
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_CreditsTheEnd4;
2018-02-17 10:55:32 +01:00
}
2019-08-17 18:01:38 +02:00
static void Task_CreditsTheEnd4(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
if (gTasks[taskIdA].tDelay)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tDelay--;
2018-02-17 10:55:32 +01:00
return;
}
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 6, 0, 16, RGB_BLACK);
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_CreditsTheEnd5;
2018-02-17 10:55:32 +01:00
}
2019-08-17 18:01:38 +02:00
static void Task_CreditsTheEnd5(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
if (!gPaletteFade.active)
{
2021-03-29 05:56:42 +02:00
DrawTheEnd(0x3800, 0);
2018-02-17 10:55:32 +01:00
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0, RGB_BLACK);
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tDelay = 7200;
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_CreditsTheEnd6;
2018-02-17 10:55:32 +01:00
}
}
2019-08-17 18:01:38 +02:00
static void Task_CreditsTheEnd6(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
if (!gPaletteFade.active)
{
2021-03-29 05:56:42 +02:00
if (gTasks[taskIdA].tDelay == 0 || gMain.newKeys)
2018-02-17 10:55:32 +01:00
{
FadeOutBGM(4);
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 8, 0, 16, RGB_WHITEALPHA);
2019-08-17 18:01:38 +02:00
gTasks[taskIdA].func = Task_CreditsSoftReset;
2018-02-17 10:55:32 +01:00
return;
}
2021-03-29 05:56:42 +02:00
if (gTasks[taskIdA].tDelay == 7144)
2018-02-17 10:55:32 +01:00
FadeOutBGM(8);
2021-03-29 05:56:42 +02:00
if (gTasks[taskIdA].tDelay == 6840)
2018-02-17 10:55:32 +01:00
m4aSongNumStart(MUS_END);
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tDelay--;
2018-02-17 10:55:32 +01:00
}
}
2021-03-29 05:56:42 +02:00
#undef tDelay
2019-08-17 18:01:38 +02:00
static void Task_CreditsSoftReset(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
if (!gPaletteFade.active)
2021-03-29 05:56:42 +02:00
SoftReset(RESET_ALL);
2018-02-17 10:55:32 +01:00
}
2019-08-17 18:01:38 +02:00
static void ResetGpuAndVram(void)
2018-02-17 10:55:32 +01:00
{
SetGpuReg(REG_OFFSET_DISPCNT, 0);
SetGpuReg(REG_OFFSET_BG3HOFS, 0);
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuReg(REG_OFFSET_BG2HOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 0);
SetGpuReg(REG_OFFSET_BG1HOFS, 0);
SetGpuReg(REG_OFFSET_BG1VOFS, 0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE);
DmaFill32(3, 0, (void *)OAM, OAM_SIZE);
DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2);
}
static void sub_8175DA0(u8 taskIdB)
{
int i;
switch (gTasks[taskIdB].data[TDB_0])
{
case 0:
case 6:
case 7:
case 8:
case 9:
default:
if (!gPaletteFade.active)
{
gTasks[taskIdB].data[TDB_0] = 1;
gTasks[taskIdB].data[TDB_3] = 0x48;
gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_14] = 0;
2021-03-29 05:56:42 +02:00
sUnkVar = 0;
2018-02-17 10:55:32 +01:00
}
return;
case 1:
if (gTasks[taskIdB].data[TDB_3] != 0)
{
2021-03-29 05:56:42 +02:00
gTasks[taskIdB].data[TDB_3]--;
2018-02-17 10:55:32 +01:00
return;
}
2021-03-29 05:56:42 +02:00
gTasks[taskIdB].data[TDB_0]++;
2018-02-17 10:55:32 +01:00
return;
case 2:
2019-08-17 18:01:38 +02:00
if (gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].func == Task_ProgressCreditTasks)
2018-02-17 10:55:32 +01:00
{
if (gTasks[taskIdB].data[TDB_CURRENT_PAGE] < PAGE_COUNT)
{
2021-03-29 05:56:42 +02:00
for (i = 0; i < ENTRIES_PER_PAGE; i++)
2019-08-17 18:01:38 +02:00
PrintCreditsText(
2021-03-29 05:56:42 +02:00
sCreditsEntryPointerTable[gTasks[taskIdB].data[TDB_CURRENT_PAGE]][i]->text,
2019-08-17 18:01:38 +02:00
5 + i * 16,
2021-03-29 05:56:42 +02:00
sCreditsEntryPointerTable[gTasks[taskIdB].data[TDB_CURRENT_PAGE]][i]->isTitle);
2018-10-27 00:53:07 +02:00
2018-02-17 10:55:32 +01:00
CopyWindowToVram(0, 2);
2018-10-27 00:53:07 +02:00
2021-03-29 05:56:42 +02:00
gTasks[taskIdB].data[TDB_CURRENT_PAGE]++;
gTasks[taskIdB].data[TDB_0]++;
2018-02-17 10:55:32 +01:00
gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_14] = 1;
if (gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_13] == 1)
BeginNormalPaletteFade(0x00000300, 0, 16, 0, COLOR_LIGHT_GREEN);
else
BeginNormalPaletteFade(0x00000300, 0, 16, 0, COLOR_DARK_GREEN);
return;
}
gTasks[taskIdB].data[TDB_0] = 10;
return;
}
gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_14] = 0;
return;
case 3:
if (!gPaletteFade.active)
{
gTasks[taskIdB].data[TDB_3] = 0x73;
2021-03-29 05:56:42 +02:00
gTasks[taskIdB].data[TDB_0]++;
2018-02-17 10:55:32 +01:00
}
return;
case 4:
if (gTasks[taskIdB].data[TDB_3] != 0)
{
2021-03-29 05:56:42 +02:00
gTasks[taskIdB].data[TDB_3]--;
2018-02-17 10:55:32 +01:00
return;
}
2019-08-17 18:01:38 +02:00
if (CheckChangeScene((u8)gTasks[taskIdB].data[TDB_CURRENT_PAGE], (u8)gTasks[taskIdB].data[TDB_TASK_A_ID]))
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
gTasks[taskIdB].data[TDB_0]++;
2018-02-17 10:55:32 +01:00
return;
}
2021-03-29 05:56:42 +02:00
gTasks[taskIdB].data[TDB_0]++;
2018-02-17 10:55:32 +01:00
if (gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_13] == 1)
BeginNormalPaletteFade(0x00000300, 0, 0, 16, COLOR_LIGHT_GREEN);
else
BeginNormalPaletteFade(0x00000300, 0, 0, 16, COLOR_DARK_GREEN);
return;
case 5:
if (!gPaletteFade.active)
{
FillWindowPixelBuffer(0, PIXEL_FILL(0));
2018-02-17 10:55:32 +01:00
CopyWindowToVram(0, 2);
gTasks[taskIdB].data[TDB_0] = 2;
}
return;
case 10:
gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_4] = 1;
DestroyTask(taskIdB);
sub_81755A4();
2019-11-03 06:33:46 +01:00
FREE_AND_SET_NULL(sCreditsData);
2018-02-17 10:55:32 +01:00
return;
}
}
2019-08-17 18:01:38 +02:00
static u8 CheckChangeScene(u8 page, u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
// Starts with bike + ocean + morning
if (page == 6)
{
2021-03-29 05:56:42 +02:00
// Pokémon interlude
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].data[TDA_11] = 2;
}
if (page == 12)
{
// Bike + ocean + sunset
gTasks[taskIdA].data[TDA_7] = 1;
gTasks[taskIdA].data[TDA_11] = 1;
}
if (page == 18)
{
2021-03-29 05:56:42 +02:00
// Pokémon interlude
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].data[TDA_11] = 2;
}
if (page == 24)
{
// Bike + forest + sunset
gTasks[taskIdA].data[TDA_7] = 2;
gTasks[taskIdA].data[TDA_11] = 1;
}
if (page == 30)
{
2021-03-29 05:56:42 +02:00
// Pokémon interlude
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].data[TDA_11] = 2;
}
if (page == 36)
{
// Bike + forest + sunset
gTasks[taskIdA].data[TDA_7] = 3;
gTasks[taskIdA].data[TDA_11] = 1;
}
if (page == 42)
{
2021-03-29 05:56:42 +02:00
// Pokémon interlude
2018-02-17 10:55:32 +01:00
gTasks[taskIdA].data[TDA_11] = 2;
}
if (page == 48)
{
// Bike + town + night
gTasks[taskIdA].data[TDA_7] = 4;
gTasks[taskIdA].data[TDA_11] = 1;
}
if (gTasks[taskIdA].data[TDA_11] != 0)
{
// Returns true if changed?
return TRUE;
}
return FALSE;
}
static void sub_81760FC(u8 taskIdD)
{
u8 r2;
switch (gTasks[taskIdD].data[TDD_STATE])
{
case 0:
break;
case 1:
2021-03-29 05:56:42 +02:00
if (sCreditsData->nextImgPos == POS_LEFT && gTasks[gTasks[taskIdD].data[TDD_TASK_A_ID]].data[TDA_14] == 0)
2018-02-17 10:55:32 +01:00
break;
gTasks[taskIdD].data[TDD_STATE]++;
break;
case 2:
2019-11-04 17:38:09 +01:00
if (sCreditsData->imgCounter == NUM_MON_SLIDES || gTasks[gTasks[taskIdD].data[TDD_TASK_A_ID]].func != Task_ProgressCreditTasks)
2018-02-17 10:55:32 +01:00
break;
2021-03-29 05:56:42 +02:00
r2 = CreateCreditsMonSprite(sCreditsData->monToShow[sCreditsData->currShownMon],
sMonSpritePos[sCreditsData->nextImgPos][0],
sMonSpritePos[sCreditsData->nextImgPos][1],
sCreditsData->nextImgPos);
2019-11-04 17:38:09 +01:00
if (sCreditsData->currShownMon < sCreditsData->numMonToShow - 1)
2018-02-17 10:55:32 +01:00
{
2019-11-04 17:38:09 +01:00
sCreditsData->currShownMon++;
2018-02-17 10:55:32 +01:00
gSprites[r2].data[3] = 50;
}
else
{
2019-11-04 17:38:09 +01:00
sCreditsData->currShownMon = 0;
2018-02-17 10:55:32 +01:00
gSprites[r2].data[3] = 512;
}
2019-11-03 06:33:46 +01:00
sCreditsData->imgCounter++;
2021-03-29 05:56:42 +02:00
if (sCreditsData->nextImgPos == POS_RIGHT)
sCreditsData->nextImgPos = POS_LEFT;
2018-02-17 10:55:32 +01:00
else
2019-11-03 06:33:46 +01:00
sCreditsData->nextImgPos++;
2021-03-29 05:56:42 +02:00
2018-02-17 10:55:32 +01:00
gTasks[taskIdD].data[TDD_3] = 50;
gTasks[taskIdD].data[TDD_STATE]++;
break;
case 3:
if (gTasks[taskIdD].data[TDD_3] != 0)
gTasks[taskIdD].data[TDD_3]--;
else
gTasks[taskIdD].data[TDD_STATE] = 1;
break;
}
}
static void sub_817624C(u8 taskIdC)
{
switch (gTasks[taskIdC].data[TDC_0])
{
case 0:
gIntroCredits_MovingSceneryVOffset = Sin((gTasks[taskIdC].data[TDC_5] >> 1) & 0x7F, 12);
2018-02-17 10:55:32 +01:00
gTasks[taskIdC].data[TDC_5]++;
break;
case 1:
if (gIntroCredits_MovingSceneryVOffset != 0)
2018-02-17 10:55:32 +01:00
{
gIntroCredits_MovingSceneryVOffset = Sin((gTasks[taskIdC].data[TDC_5] >> 1) & 0x7F, 12);
2018-02-17 10:55:32 +01:00
gTasks[taskIdC].data[TDC_5]++;
}
else
{
gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 2;
gTasks[taskIdC].data[TDC_5] = 0;
gTasks[taskIdC].data[TDC_0]++;
}
break;
case 2:
if (gTasks[taskIdC].data[TDC_5] < 64)
{
gTasks[taskIdC].data[TDC_5]++;
gIntroCredits_MovingSceneryVOffset = Sin(gTasks[taskIdC].data[TDC_5] & 0x7F, 20);
2018-02-17 10:55:32 +01:00
}
else
{
gTasks[taskIdC].data[TDC_0]++;
}
break;
case 3:
gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 3;
gSprites[gTasks[taskIdC].data[TDC_3]].data[0] = 1;
gTasks[taskIdC].data[TDC_4] = 120;
gTasks[taskIdC].data[TDC_0]++;
break;
case 4:
if (gTasks[taskIdC].data[TDC_4] != 0)
{
gTasks[taskIdC].data[TDC_4]--;
}
else
{
gTasks[taskIdC].data[TDC_5] = 64;
gTasks[taskIdC].data[TDC_0]++;
}
break;
case 5:
if (gTasks[taskIdC].data[TDC_5] > 0)
{
gTasks[taskIdC].data[TDC_5]--;
gIntroCredits_MovingSceneryVOffset = Sin(gTasks[taskIdC].data[TDC_5] & 0x7F, 20);
2018-02-17 10:55:32 +01:00
}
else
{
gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 1;
gTasks[taskIdC].data[TDC_0]++;
}
break;
case 6:
gTasks[taskIdC].data[TDC_0] = 50;
break;
case 10:
gSprites[gTasks[taskIdC].data[TDC_3]].data[0] = 2;
gTasks[taskIdC].data[TDC_0] = 50;
break;
case 20:
gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 4;
gTasks[taskIdC].data[TDC_0] = 50;
break;
case 30:
gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 5;
gSprites[gTasks[taskIdC].data[TDC_3]].data[0] = 3;
gTasks[taskIdC].data[TDC_0] = 50;
break;
case 50:
gTasks[taskIdC].data[TDC_0] = 0;
break;
}
}
static void sub_817651C(u8 taskIdE)
{
s16 taskIdC;
switch (gTasks[taskIdE].data[TDE_0])
{
default:
case 0:
if (gTasks[taskIdE].data[TDE_1] != 0x7FFF)
{
if (gTasks[gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_B_ID]].data[TDB_CURRENT_PAGE] == 2)
{
gTasks[gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_C_ID]].data[TDC_0] = 20;
gTasks[taskIdE].data[TDE_1] = 0x7FFF;
}
}
CycleSceneryPalette(0);
2018-02-17 10:55:32 +01:00
break;
case 1:
CycleSceneryPalette(0);
2018-02-17 10:55:32 +01:00
break;
case 2:
if (gTasks[taskIdE].data[TDE_1] != 0x7FFF)
{
taskIdC = gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_C_ID];
// Floor to multiple of 128
if ((gTasks[taskIdC].data[TDC_5] & -128) == 640)
{
gTasks[taskIdC].data[TDC_0] = 1;
gTasks[taskIdE].data[TDE_1] = 0x7FFF;
}
}
CycleSceneryPalette(1);
2018-02-17 10:55:32 +01:00
break;
case 3:
if (gTasks[taskIdE].data[TDE_1] != 0x7FFF)
{
if (gTasks[taskIdE].data[TDE_1] == 0x248)
{
gTasks[gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_C_ID]].data[TDC_0] = 10;
gTasks[taskIdE].data[TDE_1] = 0x7FFF;
}
else
{
2021-03-29 05:56:42 +02:00
gTasks[taskIdE].data[TDE_1]++;
2018-02-17 10:55:32 +01:00
}
}
CycleSceneryPalette(1);
2018-02-17 10:55:32 +01:00
break;
case 4:
CycleSceneryPalette(2);
2018-02-17 10:55:32 +01:00
break;
}
}
2021-03-29 05:56:42 +02:00
static void InitCreditsSceneGfx(u8 scene, u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
switch (scene)
2018-02-17 10:55:32 +01:00
{
case 0:
2021-03-29 05:56:42 +02:00
gSprites[gTasks[taskIdA].tPlayerSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tRivalSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.x = 272;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.x = 272;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tPlayerSpriteId].data[0] = 0;
gSprites[gTasks[taskIdA].tRivalSpriteId].data[0] = 0;
gTasks[taskIdA].data[TDA_0] = CreateBicycleBgAnimationTask(0, 0x2000, 0x20, 8);
2018-02-17 10:55:32 +01:00
break;
case 1:
2021-03-29 05:56:42 +02:00
gSprites[gTasks[taskIdA].tPlayerSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tRivalSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.x = 120;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.x = 272;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tPlayerSpriteId].data[0] = 0;
gSprites[gTasks[taskIdA].tRivalSpriteId].data[0] = 0;
gTasks[taskIdA].data[TDA_0] = CreateBicycleBgAnimationTask(0, 0x2000, 0x20, 8);
2018-02-17 10:55:32 +01:00
break;
case 2:
2021-03-29 05:56:42 +02:00
gSprites[gTasks[taskIdA].tPlayerSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tRivalSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.x = 120;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.x = 272;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tPlayerSpriteId].data[0] = 0;
gSprites[gTasks[taskIdA].tRivalSpriteId].data[0] = 0;
gTasks[taskIdA].data[TDA_0] = CreateBicycleBgAnimationTask(1, 0x2000, 0x200, 8);
2018-02-17 10:55:32 +01:00
break;
case 3:
2021-03-29 05:56:42 +02:00
gSprites[gTasks[taskIdA].tPlayerSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tRivalSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.x = 120;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.x = -32;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tPlayerSpriteId].data[0] = 0;
gSprites[gTasks[taskIdA].tRivalSpriteId].data[0] = 0;
gTasks[taskIdA].data[TDA_0] = CreateBicycleBgAnimationTask(1, 0x2000, 0x200, 8);
2018-02-17 10:55:32 +01:00
break;
case 4:
2021-03-29 05:56:42 +02:00
gSprites[gTasks[taskIdA].tPlayerSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tRivalSpriteId].invisible = FALSE;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.x = 88;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.x = 152;
gSprites[gTasks[taskIdA].tPlayerSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tRivalSpriteId].pos1.y = 46;
gSprites[gTasks[taskIdA].tPlayerSpriteId].data[0] = 0;
gSprites[gTasks[taskIdA].tRivalSpriteId].data[0] = 0;
gTasks[taskIdA].data[TDA_0] = CreateBicycleBgAnimationTask(2, 0x2000, 0x200, 8);
2018-02-17 10:55:32 +01:00
break;
}
gTasks[taskIdA].data[TDA_TASK_E_ID] = CreateTask(sub_817651C, 0);
gTasks[gTasks[taskIdA].data[TDA_TASK_E_ID]].data[TDE_0] = scene;
2018-02-17 10:55:32 +01:00
gTasks[gTasks[taskIdA].data[TDA_TASK_E_ID]].data[TDE_1] = 0;
gTasks[gTasks[taskIdA].data[TDA_TASK_E_ID]].data[TDE_TASK_A_ID] = taskIdA;
gTasks[taskIdA].data[TDA_TASK_C_ID] = CreateTask(sub_817624C, 0);
gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_0] = 0;
gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_1] = taskIdA;
2021-03-29 05:56:42 +02:00
gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_2] = gTasks[taskIdA].tPlayerSpriteId;
gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_3] = gTasks[taskIdA].tRivalSpriteId;
2018-02-17 10:55:32 +01:00
gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_4] = 0;
if (scene == 2)
2018-02-17 10:55:32 +01:00
gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_5] = 0x45;
}
static bool8 sub_8176AB0(u8 scene, u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
u8 spriteId;
switch (gMain.state)
{
default:
case 0:
SetGpuReg(REG_OFFSET_DISPCNT, 0);
SetGpuReg(REG_OFFSET_BG3HOFS, 8);
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuReg(REG_OFFSET_BG2HOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 0);
SetGpuReg(REG_OFFSET_BG1HOFS, 0);
SetGpuReg(REG_OFFSET_BG1VOFS, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
ResetSpriteData();
FreeAllSpritePalettes();
gMain.state = 1;
break;
case 1:
gIntroCredits_MovingSceneryVBase = 34;
gIntroCredits_MovingSceneryVOffset = 0;
LoadCreditsSceneGraphics(scene);
2021-03-29 05:56:42 +02:00
gMain.state++;
2018-02-17 10:55:32 +01:00
break;
case 2:
if (gSaveBlock2Ptr->playerGender == MALE)
{
LoadCompressedSpriteSheet(gSpriteSheet_CreditsBrendan);
LoadCompressedSpriteSheet(gSpriteSheet_CreditsRivalMay);
LoadCompressedSpriteSheet(gSpriteSheet_CreditsBicycle);
LoadSpritePalettes(gSpritePalettes_Credits);
2018-02-17 10:55:32 +01:00
spriteId = CreateIntroBrendanSprite(120, 46);
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tPlayerSpriteId = spriteId;
gSprites[spriteId].callback = SpriteCB_PlayerCyclist;
gSprites[spriteId].anims = sAnims_Player;
2018-02-17 10:55:32 +01:00
spriteId = CreateIntroMaySprite(272, 46);
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tRivalSpriteId = spriteId;
gSprites[spriteId].callback = SpriteCB_RivalCyclist;
gSprites[spriteId].anims = sAnims_Rival;
2018-02-17 10:55:32 +01:00
}
else
{
LoadCompressedSpriteSheet(gSpriteSheet_CreditsMay);
LoadCompressedSpriteSheet(gSpriteSheet_CreditsRivalBrendan);
LoadCompressedSpriteSheet(gSpriteSheet_CreditsBicycle);
LoadSpritePalettes(gSpritePalettes_Credits);
2018-02-17 10:55:32 +01:00
spriteId = CreateIntroMaySprite(120, 46);
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tPlayerSpriteId = spriteId;
gSprites[spriteId].callback = SpriteCB_PlayerCyclist;
gSprites[spriteId].anims = sAnims_Player;
2018-02-17 10:55:32 +01:00
spriteId = CreateIntroBrendanSprite(272, 46);
2021-03-29 05:56:42 +02:00
gTasks[taskIdA].tRivalSpriteId = spriteId;
gSprites[spriteId].callback = SpriteCB_RivalCyclist;
gSprites[spriteId].anims = sAnims_Rival;
2018-02-17 10:55:32 +01:00
};
2021-03-29 05:56:42 +02:00
gMain.state++;
2018-02-17 10:55:32 +01:00
break;
case 3:
2021-03-29 05:56:42 +02:00
InitCreditsSceneGfx(scene, taskIdA);
SetCreditsSceneBgCnt(scene);
2018-02-17 10:55:32 +01:00
gMain.state = 0;
return TRUE;
}
return FALSE;
}
2019-08-17 18:01:38 +02:00
static void ResetCreditsTasks(u8 taskIdA)
2018-02-17 10:55:32 +01:00
{
if (gTasks[taskIdA].data[TDA_0] != 0)
{
DestroyTask(gTasks[taskIdA].data[TDA_0]);
gTasks[taskIdA].data[TDA_0] = 0;
}
if (gTasks[taskIdA].data[TDA_TASK_C_ID] != 0)
{
DestroyTask(gTasks[taskIdA].data[TDA_TASK_C_ID]);
gTasks[taskIdA].data[TDA_TASK_C_ID] = 0;
}
if (gTasks[taskIdA].data[TDA_TASK_E_ID] != 0)
{
DestroyTask(gTasks[taskIdA].data[TDA_TASK_E_ID]);
gTasks[taskIdA].data[TDA_TASK_E_ID] = 0;
}
if (gTasks[taskIdA].data[TDA_TASK_D_ID] != 0)
{
DestroyTask(gTasks[taskIdA].data[TDA_TASK_D_ID]);
gTasks[taskIdA].data[TDA_TASK_D_ID] = 0;
}
gIntroCredits_MovingSceneryState = INTROCRED_SCENERY_DESTROY;
2018-02-17 10:55:32 +01:00
}
2021-03-29 05:56:42 +02:00
static void LoadTheEndScreen(u16 arg0, u16 arg1, u16 palOffset)
2018-02-17 10:55:32 +01:00
{
u16 baseTile;
u16 i;
LZ77UnCompVram(sCreditsCopyrightEnd_Gfx, (void *)(VRAM + arg0));
2021-03-29 05:56:42 +02:00
LoadPalette(gIntroCopyright_Pal, palOffset, sizeof(gIntroCopyright_Pal));
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
baseTile = (palOffset / 16) << 12;
2018-02-17 10:55:32 +01:00
for (i = 0; i < 32 * 32; i++)
((u16 *) (VRAM + arg1))[i] = baseTile + 1;
}
2021-03-29 05:56:42 +02:00
static u16 GetLetterMapTile(u8 baseTiles)
2018-02-17 10:55:32 +01:00
{
u16 out = (baseTiles & 0x3F) + 80;
2018-02-17 10:55:32 +01:00
if (baseTiles == 0xFF)
2018-02-17 10:55:32 +01:00
return 1;
if (baseTiles & (1 << 7))
2018-02-17 10:55:32 +01:00
out |= 1 << 11;
if (baseTiles & (1 << 6))
2018-02-17 10:55:32 +01:00
out |= 1 << 10;
return out;
}
2021-03-29 05:56:42 +02:00
static void DrawLetterMapTiles(const u8 baseTiles[], u8 baseX, u8 baseY, u16 offset, u16 palette)
2018-02-17 10:55:32 +01:00
{
u8 y, x;
const u16 tileOffset = (palette / 16) << 12;
for (y = 0; y < 5; y++)
{
for (x = 0; x < 3; x++)
2021-03-29 05:56:42 +02:00
((u16 *) (VRAM + offset + (baseY + y) * 64))[baseX + x] = tileOffset + GetLetterMapTile(baseTiles[y * 3 + x]);
2018-02-17 10:55:32 +01:00
}
}
2021-03-29 05:56:42 +02:00
static void DrawTheEnd(u16 offset, u16 palette)
2018-02-17 10:55:32 +01:00
{
u16 pos;
u16 baseTile = (palette / 16) << 12;
for (pos = 0; pos < 32 * 32; pos++)
2021-03-29 05:56:42 +02:00
((u16 *) (VRAM + offset))[pos] = baseTile + 1;
DrawLetterMapTiles(sTheEnd_LetterMap_T, 3, 7, offset, palette);
DrawLetterMapTiles(sTheEnd_LetterMap_H, 7, 7, offset, palette);
DrawLetterMapTiles(sTheEnd_LetterMap_E, 11, 7, offset, palette);
DrawLetterMapTiles(sTheEnd_LetterMap_E, 16, 7, offset, palette);
DrawLetterMapTiles(sTheEnd_LetterMap_N, 20, 7, offset, palette);
DrawLetterMapTiles(sTheEnd_LetterMap_D, 24, 7, offset, palette);
2018-02-17 10:55:32 +01:00
}
2021-03-29 05:56:42 +02:00
#define sState data[0]
static void SpriteCB_PlayerCyclist(struct Sprite *sprite)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
if (gIntroCredits_MovingSceneryState != INTROCRED_SCENERY_NORMAL)
2018-02-17 10:55:32 +01:00
{
DestroySprite(sprite);
return;
}
2021-03-29 05:56:42 +02:00
switch (sprite->sState)
2018-02-17 10:55:32 +01:00
{
case 0:
StartSpriteAnimIfDifferent(sprite, 0);
break;
case 1:
StartSpriteAnimIfDifferent(sprite, 1);
if (sprite->pos1.x > -32)
2021-03-29 05:56:42 +02:00
sprite->pos1.x--;
2018-02-17 10:55:32 +01:00
break;
case 2:
StartSpriteAnimIfDifferent(sprite, 2);
break;
case 3:
StartSpriteAnimIfDifferent(sprite, 3);
break;
case 4:
StartSpriteAnimIfDifferent(sprite, 0);
if (sprite->pos1.x > 120)
2021-03-29 05:56:42 +02:00
sprite->pos1.x--;
2018-02-17 10:55:32 +01:00
break;
case 5:
StartSpriteAnimIfDifferent(sprite, 0);
if (sprite->pos1.x > -32)
2021-03-29 05:56:42 +02:00
sprite->pos1.x--;
2018-02-17 10:55:32 +01:00
break;
}
}
2021-03-29 05:56:42 +02:00
static void SpriteCB_RivalCyclist(struct Sprite *sprite)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
if (gIntroCredits_MovingSceneryState != INTROCRED_SCENERY_NORMAL)
2018-02-17 10:55:32 +01:00
{
DestroySprite(sprite);
return;
}
2021-03-29 05:56:42 +02:00
switch (sprite->sState)
2018-02-17 10:55:32 +01:00
{
case 0:
sprite->pos2.y = 0;
StartSpriteAnimIfDifferent(sprite, 0);
break;
case 1:
if (sprite->pos1.x > 200)
StartSpriteAnimIfDifferent(sprite, 1);
else
StartSpriteAnimIfDifferent(sprite, 2);
if (sprite->pos1.x > -32)
sprite->pos1.x -= 2;
sprite->pos2.y = -gIntroCredits_MovingSceneryVOffset;
2018-02-17 10:55:32 +01:00
break;
case 2:
2021-03-29 05:56:42 +02:00
sprite->data[7]++;
2018-02-17 10:55:32 +01:00
StartSpriteAnimIfDifferent(sprite, 0);
if ((sprite->data[7] & 3) == 0)
2021-03-29 05:56:42 +02:00
sprite->pos1.x++;
2018-02-17 10:55:32 +01:00
break;
case 3:
StartSpriteAnimIfDifferent(sprite, 0);
if (sprite->pos1.x > -32)
2021-03-29 05:56:42 +02:00
sprite->pos1.x--;
2018-02-17 10:55:32 +01:00
break;
}
}
2021-03-29 05:56:42 +02:00
#define sPosition data[1]
#define sSpriteId data[6]
static void SpriteCB_CreditsMon(struct Sprite *sprite)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
if (gIntroCredits_MovingSceneryState != INTROCRED_SCENERY_NORMAL)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
FreeAndDestroyMonPicSprite(sprite->sSpriteId);
2018-02-17 10:55:32 +01:00
return;
}
2021-03-29 05:56:42 +02:00
sprite->data[7]++;
switch (sprite->sState)
2018-02-17 10:55:32 +01:00
{
case 0:
default:
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
2018-02-17 10:55:32 +01:00
sprite->oam.matrixNum = sprite->data[1];
sprite->data[2] = 16;
SetOamMatrix(sprite->data[1], 0x10000 / sprite->data[2], 0, 0, 0x10000 / sprite->data[2]);
sprite->invisible = FALSE;
2021-03-29 05:56:42 +02:00
sprite->sState = 1;
2018-02-17 10:55:32 +01:00
break;
case 1:
if (sprite->data[2] < 256)
{
sprite->data[2] += 8;
SetOamMatrix(sprite->data[1], 0x10000 / sprite->data[2], 0, 0, 0x10000 / sprite->data[2]);
}
else
{
2021-03-29 05:56:42 +02:00
sprite->sState++;
2018-02-17 10:55:32 +01:00
}
2021-03-29 05:56:42 +02:00
switch (sprite->sPosition)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
case POS_LEFT + 1:
2018-02-17 10:55:32 +01:00
if ((sprite->data[7] & 3) == 0)
2021-03-29 05:56:42 +02:00
sprite->pos1.y++;
2018-02-17 10:55:32 +01:00
sprite->pos1.x -= 2;
break;
2021-03-29 05:56:42 +02:00
case POS_CENTER + 1:
2018-02-17 10:55:32 +01:00
break;
2021-03-29 05:56:42 +02:00
case POS_RIGHT + 1:
2018-02-17 10:55:32 +01:00
if ((sprite->data[7] & 3) == 0)
2021-03-29 05:56:42 +02:00
sprite->pos1.y++;
2018-02-17 10:55:32 +01:00
sprite->pos1.x += 2;
break;
}
break;
case 2:
if (sprite->data[3] != 0)
{
2021-03-29 05:56:42 +02:00
sprite->data[3]--;
2018-02-17 10:55:32 +01:00
}
else
{
2018-12-26 13:43:07 +01:00
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3);
2018-12-26 14:03:48 +01:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
2018-02-17 10:55:32 +01:00
sprite->data[3] = 16;
2021-03-29 05:56:42 +02:00
sprite->sState++;
2018-02-17 10:55:32 +01:00
}
break;
case 3:
if (sprite->data[3] != 0)
{
int data3;
2021-03-29 05:56:42 +02:00
sprite->data[3]--;
2018-02-17 10:55:32 +01:00
data3 = 16 - sprite->data[3];
SetGpuReg(REG_OFFSET_BLDALPHA, (data3 << 8) + sprite->data[3]);
}
else
{
sprite->invisible = TRUE;
2021-03-29 05:56:42 +02:00
sprite->sState = 9;
2018-02-17 10:55:32 +01:00
}
break;
case 9:
2021-03-29 05:56:42 +02:00
sprite->sState++;
2018-02-17 10:55:32 +01:00
break;
case 10:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
2018-08-19 01:06:10 +02:00
FreeAndDestroyMonPicSprite(sprite->data[6]);
2018-02-17 10:55:32 +01:00
break;
}
}
2021-03-29 05:56:42 +02:00
#define sMonSpriteId data[0]
static u8 CreateCreditsMonSprite(u16 nationalDexNum, s16 x, s16 y, u16 position)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
u8 monSpriteId;
u8 bgSpriteId;
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
monSpriteId = CreateMonSpriteFromNationalDexNumber(nationalDexNum, x, y, position);
gSprites[monSpriteId].oam.priority = 1;
gSprites[monSpriteId].sPosition = position + 1;
gSprites[monSpriteId].invisible = TRUE;
gSprites[monSpriteId].callback = SpriteCB_CreditsMon;
gSprites[monSpriteId].sSpriteId = monSpriteId;
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
bgSpriteId = CreateSprite(&sSpriteTemplate_CreditsMonBg, gSprites[monSpriteId].pos1.x, gSprites[monSpriteId].pos1.y, 1);
gSprites[bgSpriteId].sMonSpriteId = monSpriteId;
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
StartSpriteAnimIfDifferent(&gSprites[bgSpriteId], position);
2018-02-17 10:55:32 +01:00
2021-03-29 05:56:42 +02:00
return monSpriteId;
2018-02-17 10:55:32 +01:00
}
2021-03-29 05:56:42 +02:00
static void SpriteCB_CreditsMonBg(struct Sprite *sprite)
2018-02-17 10:55:32 +01:00
{
2021-03-29 05:56:42 +02:00
if (gSprites[sprite->sMonSpriteId].data[0] == 10
|| gIntroCredits_MovingSceneryState != INTROCRED_SCENERY_NORMAL)
2018-02-17 10:55:32 +01:00
{
DestroySprite(sprite);
return;
}
2021-03-29 05:56:42 +02:00
// Copy sprite data from the associated Pokémon
sprite->invisible = gSprites[sprite->sMonSpriteId].invisible;
sprite->oam.objMode = gSprites[sprite->sMonSpriteId].oam.objMode;
sprite->oam.affineMode = gSprites[sprite->sMonSpriteId].oam.affineMode;
sprite->oam.matrixNum = gSprites[sprite->sMonSpriteId].oam.matrixNum;
sprite->pos1.x = gSprites[sprite->sMonSpriteId].pos1.x;
sprite->pos1.y = gSprites[sprite->sMonSpriteId].pos1.y;
2018-02-17 10:55:32 +01:00
}
2019-11-03 06:33:46 +01:00
static void DeterminePokemonToShow(void)
2018-02-17 10:55:32 +01:00
{
u16 starter = SpeciesToNationalPokedexNum(GetStarterPokemon(VarGet(VAR_STARTER_MON)));
2018-02-17 10:55:32 +01:00
u16 page;
u16 dexNum;
u16 j;
2019-11-03 06:33:46 +01:00
// Go through the Pokedex, and anything that has gotten caught we put into our massive array.
// This basically packs all of the caught pokemon into the front of the array
for (dexNum = 1, j = 0; dexNum < NATIONAL_DEX_COUNT; dexNum++)
2018-02-17 10:55:32 +01:00
{
if (GetSetPokedexFlag(dexNum, FLAG_GET_CAUGHT))
2018-02-17 10:55:32 +01:00
{
2019-11-04 17:38:09 +01:00
sCreditsData->caughtMonIds[j] = dexNum;
2018-02-17 10:55:32 +01:00
j++;
}
}
2019-11-03 06:33:46 +01:00
// Fill the rest of the array with zeroes
for (dexNum = j; dexNum < NATIONAL_DEX_COUNT; dexNum++)
sCreditsData->caughtMonIds[dexNum] = NATIONAL_DEX_NONE;
2018-02-17 10:55:32 +01:00
2019-11-04 17:38:09 +01:00
// Cap the number of pokemon we care about to NUM_MON_SLIDES, the max we show in the credits scene (-1 for the starter)
sCreditsData->numCaughtMon = j;
if (sCreditsData->numCaughtMon < NUM_MON_SLIDES)
sCreditsData->numMonToShow = j;
2018-02-17 10:55:32 +01:00
else
2019-11-04 17:38:09 +01:00
sCreditsData->numMonToShow = NUM_MON_SLIDES;
2018-02-17 10:55:32 +01:00
2019-11-03 06:33:46 +01:00
// Loop through our list of caught pokemon and select randomly from it to fill the images to show
2018-02-17 10:55:32 +01:00
j = 0;
do
{
2019-11-03 06:33:46 +01:00
// Select a random mon, insert into array
2019-11-04 17:38:09 +01:00
page = Random() % sCreditsData->numCaughtMon;
sCreditsData->monToShow[j] = sCreditsData->caughtMonIds[page];
2019-11-03 06:33:46 +01:00
// Remove the select mon from the array, and condense array entries
2018-02-17 10:55:32 +01:00
j++;
2019-11-04 17:38:09 +01:00
sCreditsData->caughtMonIds[page] = 0;
sCreditsData->numCaughtMon--;
if (page != sCreditsData->numCaughtMon)
2018-02-17 10:55:32 +01:00
{
2019-11-03 06:33:46 +01:00
// Instead of looping through and moving everything down, just take from the end. Order doesn't matter after all.
2019-11-04 17:38:09 +01:00
sCreditsData->caughtMonIds[page] = sCreditsData->caughtMonIds[sCreditsData->numCaughtMon];
sCreditsData->caughtMonIds[sCreditsData->numCaughtMon] = 0;
2018-02-17 10:55:32 +01:00
}
}
2019-11-04 17:38:09 +01:00
while (sCreditsData->numCaughtMon != 0 && j < NUM_MON_SLIDES);
2018-02-17 10:55:32 +01:00
2019-11-03 06:33:46 +01:00
// If we don't have enough pokemon in the dex to fill everything, copy the selected mon into the end of the array, so it loops
2019-11-04 17:38:09 +01:00
if (sCreditsData->numMonToShow < NUM_MON_SLIDES)
2018-02-17 10:55:32 +01:00
{
2019-11-04 17:38:09 +01:00
for (j = sCreditsData->numMonToShow, page = 0; j < NUM_MON_SLIDES; j++)
2018-02-17 10:55:32 +01:00
{
2019-11-04 17:38:09 +01:00
sCreditsData->monToShow[j] = sCreditsData->monToShow[page];
2018-02-17 10:55:32 +01:00
page++;
2019-11-04 17:38:09 +01:00
if (page == sCreditsData->numMonToShow)
2018-02-17 10:55:32 +01:00
page = 0;
}
2019-11-03 06:33:46 +01:00
// Ensure the last pokemon is our starter
sCreditsData->monToShow[NUM_MON_SLIDES - 1] = starter;
2018-02-17 10:55:32 +01:00
}
else
{
2019-11-03 06:33:46 +01:00
// Check to see if our starter has already appeared in this list, break if it has
2019-11-04 17:38:09 +01:00
for (dexNum = 0; sCreditsData->monToShow[dexNum] != starter && dexNum < NUM_MON_SLIDES; dexNum++);
2018-02-17 10:55:32 +01:00
2019-11-03 06:33:46 +01:00
// If it has, swap it with the last pokemon, to ensure our starter is the last image
2019-11-04 17:38:09 +01:00
if (dexNum < sCreditsData->numMonToShow - 1)
2018-02-17 10:55:32 +01:00
{
2019-11-04 17:38:09 +01:00
sCreditsData->monToShow[dexNum] = sCreditsData->monToShow[NUM_MON_SLIDES-1];
sCreditsData->monToShow[NUM_MON_SLIDES - 1] = starter;
2018-02-17 10:55:32 +01:00
}
else
{
2019-11-03 06:33:46 +01:00
// Ensure the last pokemon is our starter
sCreditsData->monToShow[NUM_MON_SLIDES - 1] = starter;
2018-02-17 10:55:32 +01:00
}
}
2019-11-04 17:38:09 +01:00
sCreditsData->numMonToShow = NUM_MON_SLIDES;
2018-02-17 10:55:32 +01:00
}