diff --git a/include/gba/io_reg.h b/include/gba/io_reg.h index 071a89bc5..1daa99e1d 100644 --- a/include/gba/io_reg.h +++ b/include/gba/io_reg.h @@ -553,6 +553,7 @@ #define WININ_WIN0_BG_ALL (WININ_WIN0_BG0 | WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3) #define WININ_WIN0_OBJ (1 << 4) #define WININ_WIN0_CLR (1 << 5) +#define WININ_WIN0_ALL (WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR) #define WININ_WIN1_BG0 (1 << 8) #define WININ_WIN1_BG1 (1 << 9) #define WININ_WIN1_BG2 (1 << 10) @@ -560,6 +561,7 @@ #define WININ_WIN1_BG_ALL (WININ_WIN1_BG0 | WININ_WIN1_BG1 | WININ_WIN1_BG2 | WININ_WIN1_BG3) #define WININ_WIN1_OBJ (1 << 12) #define WININ_WIN1_CLR (1 << 13) +#define WININ_WIN1_ALL (WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR) #define WINOUT_WIN01_BG0 (1 << 0) #define WINOUT_WIN01_BG1 (1 << 1) @@ -568,6 +570,7 @@ #define WINOUT_WIN01_BG_ALL (WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3) #define WINOUT_WIN01_OBJ (1 << 4) #define WINOUT_WIN01_CLR (1 << 5) +#define WINOUT_WIN01_ALL (WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR) #define WINOUT_WINOBJ_BG0 (1 << 8) #define WINOUT_WINOBJ_BG1 (1 << 9) #define WINOUT_WINOBJ_BG2 (1 << 10) @@ -575,6 +578,7 @@ #define WINOUT_WINOBJ_BG_ALL (WINOUT_WINOBJ_BG0 | WINOUT_WINOBJ_BG1 | WINOUT_WINOBJ_BG2 | WINOUT_WINOBJ_BG3) #define WINOUT_WINOBJ_OBJ (1 << 12) #define WINOUT_WINOBJ_CLR (1 << 13) +#define WINOUT_WINOBJ_ALL (WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR) #define WIN_RANGE(a, b) (((a) << 8) | (b)) #define WIN_RANGE2(a, b) ((b) | ((a) << 8)) @@ -585,9 +589,10 @@ #define BLDCNT_TGT1_BG1 (1 << 1) #define BLDCNT_TGT1_BG2 (1 << 2) #define BLDCNT_TGT1_BG3 (1 << 3) +#define BLDCNT_TGT1_BG_ALL (BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3) #define BLDCNT_TGT1_OBJ (1 << 4) #define BLDCNT_TGT1_BD (1 << 5) -#define BLDCNT_TGT1_ALL (BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD) +#define BLDCNT_TGT1_ALL (BLDCNT_TGT1_BG_ALL | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD) // Bits 6-7 select the special effect #define BLDCNT_EFFECT_NONE (0 << 6) // no special effect #define BLDCNT_EFFECT_BLEND (1 << 6) // 1st+2nd targets mixed (controlled by BLDALPHA) @@ -598,9 +603,10 @@ #define BLDCNT_TGT2_BG1 (1 << 9) #define BLDCNT_TGT2_BG2 (1 << 10) #define BLDCNT_TGT2_BG3 (1 << 11) +#define BLDCNT_TGT2_BG_ALL (BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3) #define BLDCNT_TGT2_OBJ (1 << 12) #define BLDCNT_TGT2_BD (1 << 13) -#define BLDCNT_TGT2_ALL (BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD) +#define BLDCNT_TGT2_ALL (BLDCNT_TGT2_BG_ALL | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD) // BLDALPHA #define BLDALPHA_BLEND(target1, target2) (((target2) << 8) | (target1)) diff --git a/src/rayquaza_scene.c b/src/rayquaza_scene.c index e4b6bed4d..bc7623e9f 100644 --- a/src/rayquaza_scene.c +++ b/src/rayquaza_scene.c @@ -68,8 +68,8 @@ struct RayquazaScene u16 unk; // never read u8 animId; bool8 endEarly; - s16 field_2008; - s16 field_200A; + s16 revealedLightLine; + s16 revealedLightTimer; u8 unused[12]; }; @@ -90,14 +90,14 @@ static void DuoFight_AnimateRain(void); static void DuoFight_Lightning1(void); static void DuoFight_Lightning2(void); static void DuoFight_LightningLong(void); -static void SpriteCB_DuoFightPre_Groudon(struct Sprite *sprite); -static void SpriteCB_DuoFightPre_Kyogre(struct Sprite *sprite); -static void DuoFight_SlideGroudonDown(struct Sprite *sprite); -static void DuoFight_SlideKyogreDown(struct Sprite *sprite); -static void SpriteCB_DuoFight_Groudon(struct Sprite *sprite); -static void SpriteCB_DuoFight_Kyogre(struct Sprite *sprite); static u8 CreateDuoFightGroudonSprites(void); static u8 CreateDuoFightKyogreSprites(void); +static void SpriteCB_DuoFightPre_Groudon(struct Sprite *sprite); +static void SpriteCB_DuoFightPre_Kyogre(struct Sprite *sprite); +static void SpriteCB_DuoFight_Groudon(struct Sprite *sprite); +static void SpriteCB_DuoFight_Kyogre(struct Sprite *sprite); +static void DuoFight_SlideGroudonDown(struct Sprite *sprite); +static void DuoFight_SlideKyogreDown(struct Sprite *sprite); // RAY_ANIM_TAKES_FLIGHT static void Task_RayTakesFlightAnim(u8 taskId); @@ -110,8 +110,8 @@ static void SpriteCB_TakesFlight_Smoke(struct Sprite *sprite); static void Task_RayDescendsAnim(u8 taskId); static void Task_HandleRayDescends(u8 taskId); static void Task_RayDescendsEnd(u8 taskId); -static void sub_81D874C(struct Sprite *sprite); -static u8 sub_81D86CC(void); +static u8 CreateDescendsRayquazaSprite(void); +static void SpriteCB_Descends_Rayquaza(struct Sprite *sprite); // RAY_ANIM_CHARGES static void Task_RayChargesAnim(u8 taskId); @@ -1351,7 +1351,7 @@ static void Task_SetNextAnim(u8 taskId) static void sub_81D68C8(void) { - SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_ALL); SetGpuReg(REG_OFFSET_WINOUT, 0); SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, DISPLAY_WIDTH)); SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(24, DISPLAY_HEIGHT - 24)); @@ -1361,8 +1361,8 @@ static void sub_81D68C8(void) static void sub_81D6904(void) { - SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); - SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_ALL); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_ALL); } #define tCounter data[0] @@ -2167,6 +2167,9 @@ static void Task_TakesFlight_CreateSmoke(u8 taskId) tTimer++; } +#undef tSmokeId +#undef tTimer + static void SpriteCB_TakesFlight_Smoke(struct Sprite *sprite) { if (sprite->sTimer == 0) @@ -2184,9 +2187,6 @@ static void SpriteCB_TakesFlight_Smoke(struct Sprite *sprite) sprite->sTimer &= 0xF; } -#undef tSmokeId -#undef tTimer - #undef sSmokeId #undef sTimer @@ -2217,8 +2217,8 @@ static void LoadDescendsSceneGfx(void) ResetTempTileDataBuffers(); DecompressAndCopyTileDataToVram(0, gRaySceneDescends_Light_Gfx, 0, 0, 0); DecompressAndCopyTileDataToVram(1, gRaySceneDescends_Bg_Gfx, 0, 0, 0); - while (FreeTempTileDataBuffersIfPossible()); - + while (FreeTempTileDataBuffersIfPossible()) + ; LZDecompressWram(gRaySceneDescends_Light_Tilemap, sRayScene->tilemapBuffers[0]); LZDecompressWram(gRaySceneDescends_Bg_Tilemap, sRayScene->tilemapBuffers[3]); CpuFastFill16(0, sRayScene->tilemapBuffers[2], BG_SCREEN_SIZE); @@ -2233,30 +2233,37 @@ static void LoadDescendsSceneGfx(void) LoadCompressedSpritePalette(&sSpritePal_Descends_Rayquaza); } +// Draw ray of light emerging from the clouds static void HBlankCB_RayDescends(void) { - u16 VCOUNT = GetGpuReg(REG_OFFSET_VCOUNT); - if (VCOUNT >= 24 && VCOUNT <= 135 && VCOUNT - 24 <= sRayScene->field_2008) - REG_BLDALPHA = 0xD08; + u16 vcount = GetGpuReg(REG_OFFSET_VCOUNT); + if (vcount >= 24 && vcount <= 135 && vcount - 24 <= sRayScene->revealedLightLine) + REG_BLDALPHA = 0xD08; // This line is above where light has been revealed, draw it else - REG_BLDALPHA = 0x1000; + REG_BLDALPHA = 0x1000; // Below where light has been revealed, hide it - if (VCOUNT == 0) + if (vcount == 0) { - if (sRayScene->field_2008 <= 0x1FFF) + if (sRayScene->revealedLightLine <= 0x1FFF) { - if (sRayScene->field_2008 <= 39) - sRayScene->field_2008 += 4; - else if (sRayScene->field_2008 <= 79) - sRayScene->field_2008 += 2; + // Increase the number of pixel rows of the light that have been revealed + // Gradually slows as it reaches the bottom + if (sRayScene->revealedLightLine <= 39) + sRayScene->revealedLightLine += 4; + else if (sRayScene->revealedLightLine <= 79) + sRayScene->revealedLightLine += 2; else - sRayScene->field_2008 += 1; + sRayScene->revealedLightLine += 1; } - sRayScene->field_200A++; + // Pointless + sRayScene->revealedLightTimer++; } } +#define tState data[0] +#define tTimer data[1] + static void Task_RayDescendsAnim(u8 taskId) { s16 *data = gTasks[taskId].data; @@ -2266,10 +2273,10 @@ static void Task_RayDescendsAnim(u8 taskId) SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); BlendPalettes(-1, 0x10, 0); SetVBlankCallback(VBlankCB_RayquazaScene); - sRayScene->field_2008 = 0; - sRayScene->field_200A = 0; - data[0] = 0; - data[1] = 0; + sRayScene->revealedLightLine = 0; + sRayScene->revealedLightTimer = 0; + tState = 0; + tTimer = 0; data[2] = 0; data[3] = 0; data[4] = 0x1000; @@ -2279,56 +2286,61 @@ static void Task_RayDescendsAnim(u8 taskId) static void Task_HandleRayDescends(u8 taskId) { s16 *data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { case 0: - if (data[1] == 8) + // Delay, then fade in + if (tTimer == 8) { BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); - data[1] = 0; - data[0]++; + tTimer = 0; + tState++; } else { - data[1]++; + tTimer++; } break; case 1: if (!gPaletteFade.active) { - if (data[1] == 10) + // Delay, then start ray of light + if (tTimer == 10) { - data[1] = 0; - data[0]++; + tTimer = 0; + tState++; SetHBlankCallback(HBlankCB_RayDescends); EnableInterrupts(INTR_FLAG_HBLANK | INTR_FLAG_VBLANK); } else { - data[1]++; + tTimer++; } } break; case 2: - if (data[1] == 80) + // Delay, then start Rayquaza emerging from clouds + if (tTimer == 80) { - data[1] = 0; - data[0]++; - sub_81D86CC(); + tTimer = 0; + tState++; + CreateDescendsRayquazaSprite(); } else { - data[1]++; + tTimer++; } break; case 3: - if (++data[1] == 368) + // Wait while Rayquaza descends + if (++tTimer == 368) { - data[1] = 0; - data[0]++; + tTimer = 0; + tState++; } break; case 4: + // Fade out BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK); gTasks[taskId].func = Task_RayDescendsEnd; break; @@ -2347,71 +2359,84 @@ static void Task_RayDescendsEnd(u8 taskId) } } -static u8 sub_81D86CC(void) +#define sTailSpriteId data[0] +#define sTimer data[2] +#define sXMovePeriod data[3] +#define sYMovePeriod data[4] + +static u8 CreateDescendsRayquazaSprite(void) { u8 spriteId = CreateSprite(&sSpriteTemplate_Descends_Rayquaza, 160, 0, 0); s16 *data = gSprites[spriteId].data; - data[0] = CreateSprite(&sSpriteTemplate_Descends_RayquazaTail, 184, -48, 0); - gSprites[spriteId].callback = sub_81D874C; + sTailSpriteId = CreateSprite(&sSpriteTemplate_Descends_RayquazaTail, 184, -48, 0); + gSprites[spriteId].callback = SpriteCB_Descends_Rayquaza; gSprites[spriteId].oam.priority = 3; - gSprites[data[0]].oam.priority = 3; + gSprites[sTailSpriteId].oam.priority = 3; return spriteId; } -static void sub_81D874C(struct Sprite *sprite) +static void SpriteCB_Descends_Rayquaza(struct Sprite *sprite) { s16 *data = sprite->data; - s16 counter = data[2]; - if (counter == 0) + s16 frame = sTimer; + + // Updates to Rayquaza's coords occur more frequently + // as time goes on (it accelerates as it emerges) + if (frame == 0) { - data[3] = 12; - data[4] = 8; + sXMovePeriod = 12; + sYMovePeriod = 8; } - else if (counter == 256) + else if (frame == 256) { - data[3] = 9; - data[4] = 7; + sXMovePeriod = 9; + sYMovePeriod = 7; } - else if (counter == 268) + else if (frame == 268) { - data[3] = 8; - data[4] = 6; + sXMovePeriod = 8; + sYMovePeriod = 6; } - else if (counter == 280) + else if (frame == 280) { - data[3] = 7; - data[4] = 5; + sXMovePeriod = 7; + sYMovePeriod = 5; } - else if (counter == 292) + else if (frame == 292) { - data[3] = 6; - data[4] = 4; + sXMovePeriod = 6; + sYMovePeriod = 4; } - else if (counter == 304) + else if (frame == 304) { - data[3] = 5; - data[4] = 3; + sXMovePeriod = 5; + sYMovePeriod = 3; } - else if (counter == 320) + else if (frame == 320) { - data[3] = 4; - data[4] = 2; + sXMovePeriod = 4; + sYMovePeriod = 2; } - if (data[2] % data[3] == 0) + if (sTimer % sXMovePeriod == 0) { sprite->pos2.x--; - gSprites[data[0]].pos2.x--; + gSprites[sTailSpriteId].pos2.x--; } - if (data[2] % data[4] == 0) + if (sTimer % sYMovePeriod == 0) { sprite->pos2.y++; - gSprites[data[0]].pos2.y++; + gSprites[sTailSpriteId].pos2.y++; } - data[2]++; + sTimer++; } +#undef sTailSpriteId +#undef sTimer +#undef sXMovePeriod +#undef sYMovePeriod + static void InitChargesSceneBgs(void) { ResetVramOamAndBgCntRegs();