#include "global.h" #include "constants/battle.h" #include "battle.h" #include "battle_anim.h" #include "battle_anim_80CA710.h" #include "data2.h" #include "ewram.h" #include "main.h" #include "rom_8077ABC.h" #include "scanline_effect.h" #include "task.h" #include "trig.h" extern u16 gBattleTypeFlags; extern u16 gIntroSlideFlags; extern u8 gBattleMonForms[]; extern void sub_800FE20(struct Sprite *); static void BattleIntroTask_ScrollScenery(u8); static void BattleIntroTask_FadeScenery(u8); static void BattleIntroTask_ScrollAndFadeScenery(u8); static void BattleIntroTask_80E4C34(u8); static const TaskFunc sBattleIntroTaskFuncs[] = { BattleIntroTask_ScrollScenery, BattleIntroTask_ScrollScenery, BattleIntroTask_FadeScenery, BattleIntroTask_FadeScenery, BattleIntroTask_FadeScenery, BattleIntroTask_ScrollScenery, BattleIntroTask_ScrollScenery, BattleIntroTask_ScrollScenery, BattleIntroTask_ScrollAndFadeScenery, BattleIntroTask_ScrollAndFadeScenery, }; #define tState data[0] #define tBgXOffset data[2] #define tFramesUntilBg1Slide data[3] void StartBattleIntroAnim(u8 a) { u8 taskId; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { taskId = CreateTask(BattleIntroTask_80E4C34, 0); } else if ((gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) && gGameVersion != VERSION_RUBY) { a = 3; taskId = CreateTask(BattleIntroTask_FadeScenery, 0); } else { taskId = CreateTask(sBattleIntroTaskFuncs[a], 0); } gTasks[taskId].tState = 0; gTasks[taskId].data[1] = a; gTasks[taskId].tBgXOffset = 0; gTasks[taskId].tFramesUntilBg1Slide = 0; gTasks[taskId].data[4] = 0; gTasks[taskId].data[5] = 0; gTasks[taskId].data[6] = 0; } static void EndBattleIntroTask(u8 taskId) { DestroyTask(taskId); gBattle_BG1_X = 0; gBattle_BG1_Y = 0; gBattle_BG2_X = 0; gBattle_BG2_Y = 0; REG_BLDCNT = 0; REG_BLDALPHA = 0; REG_BLDY = 0; REG_WININ = 0x3F3F; REG_WINOUT = 0x3F3F; } static void BattleIntroTask_ScrollScenery(u8 taskId) { s32 i; gBattle_BG1_X += 6; switch (gTasks[taskId].tState) { case 0: if (gBattleTypeFlags & BATTLE_TYPE_LINK) { gTasks[taskId].tBgXOffset = 16; gTasks[taskId].tState++; } else { gTasks[taskId].tBgXOffset = 1; gTasks[taskId].tState++; } break; case 1: gTasks[taskId].tBgXOffset--; if (gTasks[taskId].tBgXOffset == 0) { gTasks[taskId].tState++; REG_WININ = 0x3F; } break; case 2: // Open up the window gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y if ((gBattle_WIN0V & 0xFF00) == 0x3000) { gTasks[taskId].tState++; gTasks[taskId].tBgXOffset = DISPLAY_WIDTH; gTasks[taskId].tFramesUntilBg1Slide = 32; gIntroSlideFlags &= ~1; } break; case 3: if (gTasks[taskId].tFramesUntilBg1Slide != 0) { gTasks[taskId].tFramesUntilBg1Slide--; } else { if (gTasks[taskId].data[1] == 1) { if (gBattle_BG1_Y != 0xFFB0) gBattle_BG1_Y -= 2; } else { if (gBattle_BG1_Y != 0xFFC8) gBattle_BG1_Y -= 1; } } if ((gBattle_WIN0V & 0xFF00) != 0) gBattle_WIN0V -= 1020; if (gTasks[taskId].tBgXOffset != 0) gTasks[taskId].tBgXOffset -= 2; // Slide in the top half of the BG from the left for (i = 0; i < DISPLAY_HEIGHT / 2; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset; // Slide in the bottom half of the BG from the right for (; i < DISPLAY_HEIGHT; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset; if (gTasks[taskId].tBgXOffset == 0) { gScanlineEffect.state = 3; gTasks[taskId].tState++; CpuFill32(0, (void *)(VRAM + 0xE000), 0x800); REG_BG1CNT = 0x9C00; REG_BG2CNT = 0x5E00; } break; case 4: EndBattleIntroTask(taskId); break; } } static void BattleIntroTask_FadeScenery(u8 taskId) { s32 i; switch (gTasks[taskId].data[1]) { case 2: case 4: gBattle_BG1_X += 8; break; case 3: gBattle_BG1_X += 6; break; } if (gTasks[taskId].data[1] == 4) { gBattle_BG1_Y = Cos2(gTasks[taskId].data[6]) / 512 - 8; if (gTasks[taskId].data[6] < 0xB4) gTasks[taskId].data[6] += 4; else gTasks[taskId].data[6] += 6; if (gTasks[taskId].data[6] == 0x168) gTasks[taskId].data[6] = 0; } switch (gTasks[taskId].tState) { case 0: gTasks[taskId].data[4] = 16; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { gTasks[taskId].tBgXOffset = 16; gTasks[taskId].tState++; } else { gTasks[taskId].tBgXOffset = 1; gTasks[taskId].tState++; } break; case 1: gTasks[taskId].tBgXOffset--; if (gTasks[taskId].tBgXOffset == 0) { gTasks[taskId].tState++; REG_WININ = 0x3F; } break; case 2: // Open up window gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y if ((gBattle_WIN0V & 0xFF00) == 0x3000) { gTasks[taskId].tState++; gTasks[taskId].tBgXOffset = DISPLAY_WIDTH; gTasks[taskId].tFramesUntilBg1Slide = 32; gTasks[taskId].data[5] = 1; gIntroSlideFlags &= ~1; } break; case 3: if (gTasks[taskId].tFramesUntilBg1Slide != 0) { gTasks[taskId].tFramesUntilBg1Slide--; if (gTasks[taskId].tFramesUntilBg1Slide == 0) { REG_BLDCNT = 0x1842; REG_BLDALPHA = 0xF; REG_BLDY = 0; } } else { if ((gTasks[taskId].data[4] & 0x1F) && --gTasks[taskId].data[5] == 0) { gTasks[taskId].data[4] += 255; gTasks[taskId].data[5] = 4; } } if ((gBattle_WIN0V & 0xFF00) != 0) gBattle_WIN0V -= 1020; if (gTasks[taskId].tBgXOffset != 0) gTasks[taskId].tBgXOffset -= 2; // Slide in the top half of the BG from the left for (i = 0; i < DISPLAY_HEIGHT / 2; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset; // Slide in the bottom half of the BG from the right for (; i < DISPLAY_HEIGHT; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset; if (gTasks[taskId].tBgXOffset == 0) { gScanlineEffect.state = 3; gTasks[taskId].tState++; CpuFill32(0, (void *)(VRAM + 0xE000), 0x800); REG_BG1CNT = 0x9C00; REG_BG2CNT = 0x5E00; } break; case 4: EndBattleIntroTask(taskId); break; } if (gTasks[taskId].tState != 4) REG_BLDALPHA = gTasks[taskId].data[4]; } static void BattleIntroTask_ScrollAndFadeScenery(u8 taskId) { s32 i; gBattle_BG1_X += 8; switch (gTasks[taskId].tState) { case 0: REG_BLDCNT = 0x1842; REG_BLDALPHA = 0x0808; REG_BLDY = 0; gTasks[taskId].data[4] = 0x0808; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { gTasks[taskId].tBgXOffset = 16; gTasks[taskId].tState++; } else { gTasks[taskId].tBgXOffset = 1; gTasks[taskId].tState++; } break; case 1: gTasks[taskId].tBgXOffset--; if (gTasks[taskId].tBgXOffset == 0) { gTasks[taskId].tState++; REG_WININ = 0x3F; } break; case 2: // Open up window gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y if ((gBattle_WIN0V & 0xFF00) == 0x3000) { gTasks[taskId].tState++; gTasks[taskId].tBgXOffset = DISPLAY_WIDTH; gTasks[taskId].tFramesUntilBg1Slide = 32; gTasks[taskId].data[5] = 1; gIntroSlideFlags &= ~1; } break; case 3: if (gTasks[taskId].tFramesUntilBg1Slide != 0) { gTasks[taskId].tFramesUntilBg1Slide--; } else { if ((gTasks[taskId].data[4] & 0xF) && --gTasks[taskId].data[5] == 0) { gTasks[taskId].data[4] += 255; gTasks[taskId].data[5] = 6; } } if ((gBattle_WIN0V & 0xFF00) != 0) gBattle_WIN0V -= 1020; if (gTasks[taskId].tBgXOffset != 0) gTasks[taskId].tBgXOffset -= 2; // Slide in the top half of the BG from the left for (i = 0; i < DISPLAY_HEIGHT / 2; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset; // Slide in the bottom half of the BG from the right for (; i < DISPLAY_HEIGHT; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset; if (gTasks[taskId].tBgXOffset == 0) { gScanlineEffect.state = 3; gTasks[taskId].tState++; CpuFill32(0, (void *)(VRAM + 0xE000), 0x800); REG_BG1CNT = 0x9C00; REG_BG2CNT = 0x5E00; } break; case 4: EndBattleIntroTask(taskId); break; } if (gTasks[taskId].tState != 4) REG_BLDALPHA = gTasks[taskId].data[4]; } // Seems to only be used for link battles. static void BattleIntroTask_80E4C34(u8 taskId) { s32 i; if (gTasks[taskId].tState > 1 && gTasks[taskId].data[4] == 0) { if ((gBattle_BG1_X & 0x8000) || gBattle_BG1_X < 80) // hmm... { gBattle_BG1_X += 3; gBattle_BG2_X -= 3; } else { CpuFill32(0, (void *)(VRAM + 0xE000), 0x800); CpuFill32(0, (void *)(VRAM + 0xF000), 0x800); gTasks[taskId].data[4] = 1; } } switch (gTasks[taskId].tState) { case 0: gTasks[taskId].tBgXOffset = 16; gTasks[taskId].tState++; break; case 1: gTasks[taskId].tBgXOffset--; if (gTasks[taskId].tBgXOffset == 0) { gTasks[taskId].tState++; gSprites[gBattleStruct->linkBattleVsSpriteId_V].oam.objMode = 2; gSprites[gBattleStruct->linkBattleVsSpriteId_V].callback = sub_800FE20; gSprites[gBattleStruct->linkBattleVsSpriteId_S].oam.objMode = 2; gSprites[gBattleStruct->linkBattleVsSpriteId_S].callback = sub_800FE20; REG_WININ = 0x3F; REG_WINOUT = 0x3F06; } break; case 2: // Open up window gBattle_WIN0V -= WIN_RANGE(1, 0); // decrement min Y gBattle_WIN0V += WIN_RANGE(0, 1); // increment max Y if ((gBattle_WIN0V & 0xFF00) == 0x3000) { gTasks[taskId].tState++; gTasks[taskId].tBgXOffset = DISPLAY_WIDTH; gTasks[taskId].tFramesUntilBg1Slide = 32; gIntroSlideFlags &= ~1; } break; case 3: if ((gBattle_WIN0V & 0xFF00) != 0) gBattle_WIN0V -= 1020; if (gTasks[taskId].tBgXOffset != 0) gTasks[taskId].tBgXOffset -= 2; // Slide in the top half of the BG from the left for (i = 0; i < DISPLAY_HEIGHT / 2; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = gTasks[taskId].tBgXOffset; // Slide in the bottom half of the BG from the right for (; i < DISPLAY_HEIGHT; i++) gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][i] = -gTasks[taskId].tBgXOffset; if (gTasks[taskId].tBgXOffset == 0) { gScanlineEffect.state = 3; gTasks[taskId].tState++; REG_BG1CNT = 0x9C00; REG_BG2CNT = 0x5E00; } break; case 4: EndBattleIntroTask(taskId); break; } } void unref_sub_80E4EC8(u8 a, u8 b, u8 c, u8 d) { sub_80E4EF8(a, b, c, d, 0x4000, 30, 1); } // draws some 8x8 tilemap void sub_80E4EF8(u8 left, u8 top, u8 c, u8 paletteNum, u16 e, u8 bgMap, u8 g) { u32 tileNum; s32 x; s32 y; u8 bank = GetBattlerAtPosition(c); DmaCopy16(3, gMonSpriteGfx_Sprite_ptr[c] + gBattleMonForms[bank] * 0x800, (void *)(VRAM + e), 0x800); tileNum = e / 32 - g * 512; for (y = top; y < top + 8; y++) { for (x = left; x < left + 8; x++) { *(u16 *)(VRAM + x * 2 + bgMap * 0x800 + y * 64) = tileNum | (paletteNum << 12); tileNum++; } } } void unref_sub_80E4FDC(u8 left, u8 top, u8 c, u8 form, u8 paletteNum, u16 f, u8 bgMap, u8 h) { u32 tileNum; s32 x; s32 y; DmaCopy16(3, gMonSpriteGfx_Sprite_ptr[c] + form * 0x800, (void *)(VRAM + f), 0x800); tileNum = f / 32 - h * 512; for (y = top; y < top + 8; y++) { for (x = left; x < left + 8; x++) { *(u16 *)(VRAM + x * 2 + bgMap * 0x800 + y * 64) = tileNum | (paletteNum << 12); tileNum++; } } }