#include "global.h" #include "gba/m4a_internal.h" #include "intro.h" #include "data2.h" #include "decompress.h" #include "hall_of_fame.h" #include "intro_credits_graphics.h" #include "libgncmultiboot.h" #include "link.h" #include "m4a.h" #include "main.h" #include "new_game.h" #include "palette.h" #include "random.h" #include "save.h" #include "constants/songs.h" #include "sound.h" #include "constants/species.h" #include "task.h" #include "title_screen.h" #include "trig.h" #include "scanline_effect.h" // define register constants for the inline asm asm(".include \"constants/gba_constants.inc\"\n"); struct IntroCreditsSpriteMetadata { u8 animNum:4; u8 shape:2; u8 size:2; u8 x; u8 y; u8 subpriority; u16 xOff; }; const u16 gUnknown_084121FC[] = INCBIN_U16("graphics/intro/intro2_grass.gbapal"); const u16 gUnknown_0841221C[] = INCBIN_U16("graphics/intro/intro2_grass_afternoon.gbapal"); const u16 gUnknown_0841223C[] = INCBIN_U16("graphics/intro/intro2_grass_night.gbapal"); const u8 gUnknown_0841225C[] = INCBIN_U8("graphics/intro/intro2_grass.4bpp.lz"); const u8 gUnknown_084126DC[] = INCBIN_U8("graphics/intro/intro2_grass_map.bin.lz"); const u16 gUnknown_08412818[] = INCBIN_U16("graphics/intro/8412818.gbapal"); const u16 gUnknown_08412878[] = INCBIN_U16("graphics/intro/8412878.gbapal"); const u8 gUnknown_084128D8[] = INCBIN_U8("graphics/intro/intro2_bgclouds.4bpp.lz"); const u8 gUnknown_08412EB4[] = INCBIN_U8("graphics/intro/intro2_bgclouds_map.bin.lz"); const u16 gUnknown_08413184[] = INCBIN_U16("graphics/intro/intro2_bgclouds.gbapal"); const u16 gUnknown_084131A4[] = INCBIN_U16("graphics/intro/intro2_bgclouds_afternoon.gbapal"); const u8 gUnknown_084131C4[] = INCBIN_U8("graphics/intro/intro2_bgclouds2.4bpp.lz"); const u16 gUnknown_08413300[] = INCBIN_U16("graphics/intro/intro2_bgtrees2.gbapal"); const u16 gUnknown_08413320[] = INCBIN_U16("graphics/intro/intro2_bgtrees2_afternoon.gbapal"); const u8 gUnknown_08413340[] = INCBIN_U8("graphics/intro/intro2_bgtrees.4bpp.lz"); const u8 gUnknown_084139C8[] = INCBIN_U8("graphics/intro/intro2_bgtrees_map.bin.lz"); const u16 gUnknown_08413CCC[] = INCBIN_U16("graphics/intro/intro2_bgtrees.gbapal"); const u8 gIntro2TreeTiles[] = INCBIN_U8("graphics/intro/intro2_bgtreessmall.4bpp.lz"); const u16 gUnknown_08413E38[] = INCBIN_U16("graphics/intro/8413E38.gbapal"); const u8 gUnknown_08413E78[] = INCBIN_U8("graphics/intro/intro2_bgnight.4bpp.lz"); // only used in credits, coupled with intro because bicycle sequence const u16 gUnknown_08414064[] = INCBIN_U16("graphics/intro/intro2_bgnight.gbapal"); const u8 gUnknown_08414084[] = INCBIN_U8("graphics/intro/intro2_bgnight_map.bin.lz"); const u8 gIntro2NightTiles[] = INCBIN_U8("graphics/intro/intro2_night.4bpp.lz"); const u16 gIntro2BrendanPalette[] = INCBIN_U16("graphics/intro/intro2_brendan.gbapal"); const u8 gIntro2BrendanTiles[] = INCBIN_U8("graphics/intro/intro2_brendan.4bpp.lz"); const u16 gIntro2MayPalette[] = INCBIN_U16("graphics/intro/intro2_may.gbapal"); const u16 gUnknown_08414F90[0xF0] = {0}; const u8 gIntro2MayTiles[] = INCBIN_U8("graphics/intro/intro2_may.4bpp.lz"); const u8 gIntro2BicycleTiles[] = INCBIN_U8("graphics/intro/intro2_bicycle.4bpp.lz"); const u16 gIntro2LatiosPalette[] = INCBIN_U16("graphics/intro/intro2_latios.gbapal"); const u8 gIntro2LatiosTiles[] = INCBIN_U8("graphics/intro/intro2_latios.4bpp.lz"); const u16 gIntro2LatiasPalette[] = INCBIN_U16("graphics/intro/intro2_latias.gbapal"); const u8 gIntro2LatiasTiles[] = INCBIN_U8("graphics/intro/intro2_latias.4bpp.lz"); void sub_814910C(struct Sprite *sprite); void nullsub_82(struct Sprite *sprite); void sub_81492A0(struct Sprite *sprite); void nullsub_83(struct Sprite *sprite); const struct SpriteTemplate gSpriteTemplate_8416B3C = { 2000, 0xFFFF, &gDummyOamData, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, sub_814910C }; const struct CompressedSpriteSheet gUnknown_08416B54[] = { { gUnknown_084131C4, 0x400, 2000 }, {} }; const union AnimCmd gSpriteAnim_8416B64[] = { ANIMCMD_FRAME( 0, 30), ANIMCMD_END }; const union AnimCmd gSpriteAnim_8416B6C[] = { ANIMCMD_FRAME(16, 30), ANIMCMD_END }; const union AnimCmd gSpriteAnim_8416B74[] = { ANIMCMD_FRAME(20, 30), ANIMCMD_END }; const union AnimCmd gSpriteAnim_8416B7C[] = { ANIMCMD_FRAME(22, 30), ANIMCMD_END }; const union AnimCmd *const gSpriteAnimTable_8416B84[] = { gSpriteAnim_8416B64, gSpriteAnim_8416B6C, gSpriteAnim_8416B74, gSpriteAnim_8416B7C }; const struct IntroCreditsSpriteMetadata gUnknown_08416B94[] = { { 0, ST_OAM_SQUARE, 2, 72, 32, 100, 0xc00 }, { 0, ST_OAM_SQUARE, 2, 158, 32, 100, 0xc00 }, { 1, ST_OAM_SQUARE, 1, 192, 40, 101, 0x800 }, { 1, ST_OAM_SQUARE, 1, 56, 40, 101, 0x800 }, { 2, ST_OAM_H_RECTANGLE, 0, 100, 44, 102, 0x400 }, { 2, ST_OAM_H_RECTANGLE, 0, 152, 44, 102, 0x400 }, { 3, ST_OAM_H_RECTANGLE, 0, 8, 46, 103, 0x100 }, { 3, ST_OAM_H_RECTANGLE, 0, 56, 46, 103, 0x100 }, { 3, ST_OAM_H_RECTANGLE, 0, 240, 46, 103, 0x100 }, }; const struct CompressedSpriteSheet gUnknown_08416BDC[] = { { gIntro2TreeTiles, 0x400, 2000 }, {} }; const union AnimCmd gSpriteAnim_8416BEC[] = { ANIMCMD_FRAME( 0, 30), ANIMCMD_END }; const union AnimCmd gSpriteAnim_8416BF4[] = { ANIMCMD_FRAME(16, 30), ANIMCMD_END }; const union AnimCmd gSpriteAnim_8416BFC[] = { ANIMCMD_FRAME(24, 30), ANIMCMD_END }; const union AnimCmd *const gSpriteAnimTable_8416C04[] = { gSpriteAnim_8416BEC, gSpriteAnim_8416BF4, gSpriteAnim_8416BFC }; const struct IntroCreditsSpriteMetadata gUnknown_08416C10[] = { { 0, ST_OAM_SQUARE, 2, 16, 88, 100, 0x2000 }, { 0, ST_OAM_SQUARE, 2, 80, 88, 100, 0x2000 }, { 0, ST_OAM_SQUARE, 2, 144, 88, 100, 0x2000 }, { 0, ST_OAM_SQUARE, 2, 208, 88, 100, 0x2000 }, { 1, ST_OAM_V_RECTANGLE, 2, 40, 88, 101, 0x1000 }, { 1, ST_OAM_V_RECTANGLE, 2, 104, 88, 101, 0x1000 }, { 1, ST_OAM_V_RECTANGLE, 2, 168, 88, 101, 0x1000 }, { 1, ST_OAM_V_RECTANGLE, 2, 232, 88, 101, 0x1000 }, { 2, ST_OAM_V_RECTANGLE, 2, 56, 88, 102, 0x800 }, { 2, ST_OAM_V_RECTANGLE, 2, 120, 88, 102, 0x800 }, { 2, ST_OAM_V_RECTANGLE, 2, 184, 88, 102, 0x800 }, { 2, ST_OAM_V_RECTANGLE, 2, 248, 88, 102, 0x800 }, }; const struct CompressedSpriteSheet gUnknown_08416C70[] = { { gIntro2NightTiles, 0x400, 2000 }, {} }; const union AnimCmd gSpriteAnim_8416C80[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_END }; const union AnimCmd *const gSpriteAnimTable_8416C88[] = { gSpriteAnim_8416C80 }; const struct IntroCreditsSpriteMetadata gUnknown_08416C8C[] = { { 0, ST_OAM_SQUARE, 2, 24, 88, 100, 0x1000 }, { 0, ST_OAM_SQUARE, 2, 64, 88, 100, 0x1000 }, { 0, ST_OAM_SQUARE, 2, 104, 88, 100, 0x1000 }, { 0, ST_OAM_SQUARE, 2, 144, 88, 100, 0x1000 }, { 0, ST_OAM_SQUARE, 2, 184, 88, 100, 0x1000 }, { 0, ST_OAM_SQUARE, 2, 224, 88, 100, 0x1000 }, }; const struct OamData gOamData_8416CBC = { .y = 160, .shape = ST_OAM_SQUARE, .size = 3, .priority = 1 }; const union AnimCmd gSpriteAnim_8416CC4[] = { ANIMCMD_FRAME( 0, 8), ANIMCMD_FRAME( 64, 8), ANIMCMD_FRAME(128, 8), ANIMCMD_FRAME(192, 8), ANIMCMD_JUMP(0) }; const union AnimCmd *const gSpriteAnimTable_8416CD8[] = { gSpriteAnim_8416CC4 }; const struct SpriteTemplate gSpriteTemplate_8416CDC = { 1002, 1002, &gOamData_8416CBC, gSpriteAnimTable_8416CD8, NULL, gDummySpriteAffineAnimTable, nullsub_82 }; const struct SpriteTemplate gSpriteTemplate_8416CF4 = { 1003, 1003, &gOamData_8416CBC, gSpriteAnimTable_8416CD8, NULL, gDummySpriteAffineAnimTable, nullsub_82 }; const struct OamData gOamData_8416D0C = { .y = 160, .shape = ST_OAM_H_RECTANGLE, .size = 3, .priority = 1 }; const union AnimCmd gSpriteAnim_8416D14[] = { ANIMCMD_FRAME( 0, 8), ANIMCMD_FRAME( 32, 8), ANIMCMD_FRAME( 64, 8), ANIMCMD_FRAME( 96, 8), ANIMCMD_JUMP(0) }; const union AnimCmd *const gSpriteAnimTable_8416D28[] = { gSpriteAnim_8416D14 }; const struct SpriteTemplate gSpriteTemplate_Brendan = { 1001, 1002, &gOamData_8416D0C, gSpriteAnimTable_8416D28, NULL, gDummySpriteAffineAnimTable, sub_81492A0 }; const struct SpriteTemplate gSpriteTemplate_May = { 1001, 1003, &gOamData_8416D0C, gSpriteAnimTable_8416D28, NULL, gDummySpriteAffineAnimTable, sub_81492A0 }; const struct OamData gOamData_8416D5C = { .y = 160, .shape = ST_OAM_SQUARE, .size = 3, .priority = 1 }; const union AnimCmd gSpriteAnim_8416D64[] = { ANIMCMD_FRAME( 0, 16), ANIMCMD_END }; const union AnimCmd gSpriteAnim_8416D6C[] = { ANIMCMD_FRAME( 64, 16), ANIMCMD_END }; const union AnimCmd *const gSpriteAnimTable_8416D74[] = { gSpriteAnim_8416D64, gSpriteAnim_8416D6C }; const struct SpriteTemplate gSpriteTemplate_8416D7C = { 1004, 1004, &gOamData_8416D5C, gSpriteAnimTable_8416D74, NULL, gDummySpriteAffineAnimTable, nullsub_83 }; const struct SpriteTemplate gSpriteTemplate_8416D94 = { 1005, 1005, &gOamData_8416D5C, gSpriteAnimTable_8416D74, NULL, gDummySpriteAffineAnimTable, nullsub_83 }; const struct CompressedSpriteSheet gIntro2BrendanSpriteSheet[] = { { gIntro2BrendanTiles, 0x3800, 1002 }, {} }; const struct CompressedSpriteSheet gIntro2MaySpriteSheet[] = { { gIntro2MayTiles, 0x3800, 1003 }, {} }; const struct CompressedSpriteSheet gIntro2BicycleSpriteSheet[] = { { gIntro2BicycleTiles, 0x1000, 1001 }, {} }; const struct CompressedSpriteSheet gIntro2LatiosSpriteSheet[] = { { gIntro2LatiosTiles, 0x1000, 1004 }, {} }; const struct CompressedSpriteSheet gIntro2LatiasSpriteSheet[] = { { gIntro2LatiasTiles, 0x1000, 1005 }, {} }; const struct SpritePalette gIntro2SpritePalettes[] = { {gIntro2BrendanPalette, 1002}, {gIntro2MayPalette, 1003}, {gIntro2LatiosPalette, 1004}, {gIntro2LatiasPalette, 1005}, {} }; const struct CompressedSpriteSheet gUnknown_08416E24[] = { { gIntro2BrendanTiles, 0x2000, 1002}, {} }; const struct CompressedSpriteSheet gUnknown_08416E34[] = { { gIntro2MayTiles, 0x2000, 1003}, {} }; EWRAM_DATA u16 gUnknown_02039358 = 0; EWRAM_DATA s16 gUnknown_0203935A = 0; EWRAM_DATA s16 gIntroCredits_MovingSceneryState = 0; extern u8 gReservedSpritePaletteCount; void sub_8149248(); void sub_8149264(); void load_intro_part2_graphics(u8 a) { LZ77UnCompVram(&gUnknown_0841225C, (void *)(VRAM + 0x4000)); LZ77UnCompVram(&gUnknown_084126DC, (void *)(VRAM + 0x7800)); LoadPalette(&gUnknown_084121FC, 240, 32); switch (a) { case 0: default: LZ77UnCompVram(&gUnknown_084128D8, (void *)(VRAM)); LZ77UnCompVram(&gUnknown_08412EB4, (void *)(VRAM + 0x3000)); LoadPalette(&gUnknown_08412818, 0, 96); LoadCompressedObjectPic(gUnknown_08416B54); LoadPalette(&gUnknown_08413184, 256, 32); sub_8149248(); break; case 1: LZ77UnCompVram(&gUnknown_08413340, (void *)(VRAM)); LZ77UnCompVram(&gUnknown_084139C8, (void *)(VRAM + 0x3000)); LoadPalette(&gUnknown_08413300, 0, 32); LoadCompressedObjectPic(gUnknown_08416BDC); LoadPalette(&gUnknown_08413CCC, 256, 32); sub_8149264(); break; } gIntroCredits_MovingSceneryState = 0; gReservedSpritePaletteCount = 8; } void sub_8148C78(u8 a) { if (a == 1) { REG_BG3CNT = 0x603; REG_BG2CNT = 0x702; REG_BG1CNT = 0xF05; REG_DISPCNT = 0x1E40; } else { REG_BG3CNT = 0x603; REG_BG2CNT = 0x702; REG_BG1CNT = 0xF05; REG_DISPCNT = 0x1E40; } } void sub_8149280(); void sub_8148CB0(u8 a) { LZ77UnCompVram(&gUnknown_0841225C, (void *)(VRAM + 0x4000)); LZ77UnCompVram(&gUnknown_084126DC, (void *)(VRAM + 0x7800)); switch (a) { case 0: default: LoadPalette(&gUnknown_084121FC, 240, 32); LZ77UnCompVram(&gUnknown_084128D8, (void *)(VRAM)); LZ77UnCompVram(&gUnknown_08412EB4, (void *)(VRAM + 0x3000)); LoadPalette(&gUnknown_08412818, 0, 96); LoadCompressedObjectPic(gUnknown_08416B54); LZ77UnCompVram(&gUnknown_084131C4, (void *)(VRAM + 0x10000)); LoadPalette(&gUnknown_08413184, 256, 32); sub_8149248(); break; case 1: LoadPalette(&gUnknown_0841221C, 240, 32); LZ77UnCompVram(&gUnknown_084128D8, (void *)(VRAM)); LZ77UnCompVram(&gUnknown_08412EB4, (void *)(VRAM + 0x3000)); LoadPalette(&gUnknown_08412878, 0, 96); LoadCompressedObjectPic(gUnknown_08416B54); LZ77UnCompVram(&gUnknown_084131C4, (void *)(VRAM + 0x10000)); LoadPalette(&gUnknown_084131A4, 256, 32); sub_8149248(); break; case 2: case 3: LoadPalette(&gUnknown_0841221C, 240, 32); LZ77UnCompVram(&gUnknown_08413340, (void *)(VRAM)); LZ77UnCompVram(&gUnknown_084139C8, (void *)(VRAM + 0x3000)); LoadPalette(&gUnknown_08413320, 0, 32); LoadCompressedObjectPic(gUnknown_08416BDC); LoadPalette(&gUnknown_08413320, 256, 32); sub_8149264(); break; case 4: LoadPalette(&gUnknown_0841223C, 240, 32); LZ77UnCompVram(&gUnknown_08413E78, (void *)(VRAM)); LZ77UnCompVram(&gUnknown_08414084, (void *)(VRAM + 0x3000)); LoadPalette(&gUnknown_08413E38, 0, 64); LoadCompressedObjectPic(gUnknown_08416C70); LoadPalette(&gUnknown_08414064, 256, 32); sub_8149280(); break; } gReservedSpritePaletteCount = 8; gIntroCredits_MovingSceneryState = 0; } void sub_8148E90(u8 a) { REG_BG3CNT = 0x603; REG_BG2CNT = 0x702; REG_BG1CNT = 0xF05; REG_DISPCNT = 0x1F40; } u8 sub_8148EC0(u8 a, u16 b, u16 c, u16 d) { u8 taskId = CreateTask(&sub_8148F3C, 0); gTasks[taskId].data[0] = a; gTasks[taskId].data[1] = b; gTasks[taskId].data[2] = 0; gTasks[taskId].data[3] = 0; gTasks[taskId].data[4] = c; gTasks[taskId].data[5] = 0; gTasks[taskId].data[6] = 0; gTasks[taskId].data[7] = d; gTasks[taskId].data[8] = 8; gTasks[taskId].data[9] = 0; sub_8148F3C(taskId); return taskId; } void sub_8148F3C(u8 taskId) { s16 deltaBG1HOFS; s16 deltaBG2HOFS; s16 deltaBG3HOFS; s32 r2; deltaBG1HOFS = gTasks[taskId].data[1]; if (deltaBG1HOFS != 0) { r2 = (gTasks[taskId].data[2] << 16) + (u16)gTasks[taskId].data[3]; r2 -= 16 * (u16)deltaBG1HOFS; gTasks[taskId].data[2] = r2 >> 16; gTasks[taskId].data[3] = r2; REG_BG1HOFS = gTasks[taskId].data[2]; REG_BG1VOFS = gUnknown_02039358 + gUnknown_0203935A; } deltaBG2HOFS = gTasks[taskId].data[4]; if (deltaBG2HOFS != 0) { r2 = (gTasks[taskId].data[5] << 16) + (u16)gTasks[taskId].data[6]; r2 -= 16 * (u16)deltaBG2HOFS; gTasks[taskId].data[5] = r2 >> 16; gTasks[taskId].data[6] = r2; REG_BG2HOFS = gTasks[taskId].data[5]; if (gTasks[taskId].data[0] != 0) REG_BG2VOFS = gUnknown_02039358 + gUnknown_0203935A; else REG_BG2VOFS = gUnknown_02039358; } deltaBG3HOFS = gTasks[taskId].data[7]; if (deltaBG3HOFS != 0) { r2 = (gTasks[taskId].data[8] << 16) + (u16)gTasks[taskId].data[9]; r2 -= 16 * (u16)deltaBG3HOFS; gTasks[taskId].data[8] = r2 >> 16; gTasks[taskId].data[9] = r2; REG_BG3HOFS = gTasks[taskId].data[8]; REG_BG3VOFS = gUnknown_02039358; } } void CycleSceneryPalette(u8 mode) { u16 x; u16 y; switch (mode) { case 0: default: /* stuff */ if (gMain.vblankCounter1 & 3 || gPaletteFade.active) break; if (gMain.vblankCounter1 & 4) { x = gPlttBufferUnfaded[9]; y = gPlttBufferUnfaded[10]; } else { x = gPlttBufferUnfaded[10]; y = gPlttBufferUnfaded[9]; } LoadPalette(&x, 9, 2); LoadPalette(&y, 10, 2); break; case 2: if (gMain.vblankCounter1 & 3 || gPaletteFade.active) break; if (gMain.vblankCounter1 & 4) { x = 0x3D27; y = 0x295; } else { x = 0x31C; y = 0x3D27; } LoadPalette(&x, 12, 2); LoadPalette(&y, 13, 2); break; case 1: break; } } void sub_814910C(struct Sprite *sprite) { if (gIntroCredits_MovingSceneryState) { DestroySprite(sprite); } else { s32 var = ((sprite->x << 16) | (u16)sprite->data[2]) + (u16)sprite->data[1]; sprite->x = var >> 16; sprite->data[2] = var; if (sprite->x > 255) sprite->x = 0xFFE0; if (sprite->data[0]) { sprite->y2 = -(gUnknown_02039358 + gUnknown_0203935A); } else { sprite->y2 = -gUnknown_02039358; } } } void sub_8149174(u8 a, const struct IntroCreditsSpriteMetadata *b, const union AnimCmd *const *c, u8 d) { u8 i; for(i = 0; i < d; i++) { u8 sprite = CreateSprite(&gSpriteTemplate_8416B3C, b[i].x, b[i].y, b[i].subpriority); CalcCenterToCornerVec(&gSprites[sprite], b[i].shape, b[i].size, 0); gSprites[sprite].oam.priority = 3; gSprites[sprite].oam.shape = b[i].shape; gSprites[sprite].oam.size = b[i].size; gSprites[sprite].oam.paletteNum = 0; gSprites[sprite].anims = c; StartSpriteAnim(&gSprites[sprite], b[i].animNum); gSprites[sprite].data[0] = a; gSprites[sprite].data[1] = b[i].xOff; gSprites[sprite].data[2] = 0; } } void sub_8149248() { sub_8149174(0, gUnknown_08416B94, gSpriteAnimTable_8416B84, 9); } void sub_8149264() { sub_8149174(1, gUnknown_08416C10, gSpriteAnimTable_8416C04, 12); } void sub_8149280() { sub_8149174(1, gUnknown_08416C8C, gSpriteAnimTable_8416C88, 6); } void nullsub_82(struct Sprite *sprite) { } void sub_81492A0(struct Sprite* sprite) { sprite->invisible = gSprites[sprite->data[0]].invisible; sprite->x = gSprites[sprite->data[0]].x; sprite->y = gSprites[sprite->data[0]].y + 8; sprite->x2 = gSprites[sprite->data[0]].x2; sprite->y2 = gSprites[sprite->data[0]].y2; } u8 intro_create_brendan_sprite(s16 a, s16 b) { u8 sprite = CreateSprite(&gSpriteTemplate_8416CDC, a, b, 0); u8 brendan = CreateSprite(&gSpriteTemplate_Brendan, a, b + 8, 1); gSprites[brendan].data[0] = sprite; return sprite; } u8 intro_create_may_sprite(s16 a, s16 b) { u8 sprite = CreateSprite(&gSpriteTemplate_8416CF4, a, b, 0); u8 may = CreateSprite(&gSpriteTemplate_May, a, b + 8, 1); gSprites[may].data[0] = sprite; return sprite; } void nullsub_83(struct Sprite *sprite) { } void sub_81493C4(struct Sprite* sprite) { sprite->invisible = gSprites[sprite->data[0]].invisible; sprite->y = gSprites[sprite->data[0]].y; sprite->x2 = gSprites[sprite->data[0]].x2; sprite->y2 = gSprites[sprite->data[0]].y2; } u8 intro_create_latios_sprite(s16 a, s16 b) { u8 sprite = CreateSprite(&gSpriteTemplate_8416D7C, a - 32, b, 2); u8 latios = CreateSprite(&gSpriteTemplate_8416D7C, a + 32, b, 2); gSprites[latios].data[0] = sprite; StartSpriteAnim(&gSprites[latios], 1); gSprites[latios].callback = &sub_81493C4; return sprite; } u8 intro_create_latias_sprite(s16 a, s16 b) { u8 sprite = CreateSprite(&gSpriteTemplate_8416D94, a - 32, b, 2); u8 latios = CreateSprite(&gSpriteTemplate_8416D94, a + 32, b, 2); gSprites[latios].data[0] = sprite; StartSpriteAnim(&gSprites[latios], 1); gSprites[latios].callback = &sub_81493C4; return sprite; }