#include "global.h" #include "main.h" #include "palette.h" #include "sprite.h" #include "pc_screen_effect.h" static void sub_80C603C(void); static void sub_80C6078(void); static void sub_80C60CC(struct Sprite *); static void sub_80C6130(struct Sprite *); static void HBlankIntrOn(IntrFunc); static void HBlankIntrOff(void); struct OamData gOamData_83D18D8 = { .shape = ST_OAM_H_RECTANGLE, .size = 1 }; union AnimCmd gSpriteAnim_83D18E0[] = { ANIMCMD_FRAME(0, 5), ANIMCMD_END }; const union AnimCmd *gSpriteAnimTable_83D18E8[] = { gSpriteAnim_83D18E0 }; u16 gUnknownPal_083D18EC[] = INCBIN_U16("graphics/unknown/unknown_3D18EC.gbapal"); u8 gUnknownGfx_083D190C[] = INCBIN_U8("graphics/unknown/unknown_3D190C.4bpp"); EWRAM_DATA struct PCScreenEffectStruct *gUnknown_020387EC = NULL; void sub_80C5CD4(struct PCScreenEffectStruct *unkStruct) { u16 i; struct SpriteSheet sprSheet = { gUnknownGfx_083D190C, sizeof(gUnknownGfx_083D190C), 0 }; struct SpritePalette sprPalette = { gUnknownPal_083D18EC, 0 }; struct SpriteTemplate sprTemplate = { 0, 0, &gOamData_83D18D8, gSpriteAnimTable_83D18E8, NULL, gDummySpriteAffineAnimTable, sub_80C60CC, }; sprSheet.tag = unkStruct->tileTag; sprTemplate.tileTag = unkStruct->tileTag; sprPalette.tag = unkStruct->paletteTag; sprTemplate.paletteTag = unkStruct->paletteTag; LoadSpriteSheet(&sprSheet); LoadSpritePalette(&sprPalette); unkStruct->unk0C = 1; unkStruct->unk0A = 0; unkStruct->unk08 = 0; unkStruct->selectedPalettes = ~(0x10000 << IndexOfSpritePaletteTag(unkStruct->paletteTag)) & 0xFFFF0000; if (unkStruct->unk04 == 0) unkStruct->unk04 = 16; if (unkStruct->unk06 == 0) unkStruct->unk06 = 20; gUnknown_020387EC = unkStruct; for (i = 0; i < 8; i++) { u8 spriteId = CreateSprite(&sprTemplate, 32 * i + 8, 80, 0); if (spriteId == MAX_SPRITES) break; gSprites[spriteId].data[0] = (i < 4) ? -unkStruct->unk04 : unkStruct->unk04; } REG_BLDCNT = 191; REG_BLDY = 16; } bool8 sub_80C5DCC(void) { if (gUnknown_020387EC->unk08 == 0) { BlendPalettes(gUnknown_020387EC->selectedPalettes, 16, FADE_COLOR_WHITE); HBlankIntrOn(sub_80C603C); gUnknown_020387EC->unk08++; } if (gUnknown_020387EC->unk0A < 8) return FALSE; gUnknown_020387EC->unk0C += gUnknown_020387EC->unk06; if (gUnknown_020387EC->unk0C >= 80) { gUnknown_020387EC->unk0C = 80; REG_BLDCNT = 0; REG_BLDY = 0; HBlankIntrOff(); return TRUE; } else { return FALSE; } } void sub_80C5E38(struct PCScreenEffectStruct * a0) { u16 i; u8 spriteId; struct SpriteSheet spriteSheet = { gUnknownGfx_083D190C, sizeof(gUnknownGfx_083D190C), 0 }; struct SpritePalette spritePalette = { gUnknownPal_083D18EC, 0 }; struct SpriteTemplate spriteTemplate = { 0, 0, &gOamData_83D18D8, gSpriteAnimTable_83D18E8, NULL, gDummySpriteAffineAnimTable, sub_80C6130, }; spriteSheet.tag = a0->tileTag; spriteTemplate.tileTag = a0->tileTag; spritePalette.tag = a0->paletteTag; spriteTemplate.paletteTag = a0->paletteTag; LoadSpriteSheet(&spriteSheet); LoadSpritePalette(&spritePalette); a0->unk0C = 0x50; a0->unk08 = 0; a0->unk0A = 0; a0->selectedPalettes = 0xffff0000 & ~(0x10000 << IndexOfSpritePaletteTag(a0->paletteTag)); if (a0->unk04 == 0) a0->unk04 = 16; if (a0->unk06 == 0) a0->unk06 = 20; gUnknown_020387EC = a0; for (i = 0; i < 8; i++) { if (i < 4) { spriteId = CreateSprite(&spriteTemplate, i * 32 - 0x70, 0x50, 0); if (spriteId == MAX_SPRITES) break; gSprites[spriteId].data[0] = a0->unk04; gSprites[spriteId].data[1] = 1; } else { // Fakematching spriteId = CreateSprite(&spriteTemplate, ((i << 21) + (0x80 << 16)) >> 16, 0x50, 0); if (spriteId == MAX_SPRITES) break; gSprites[spriteId].data[0] = -a0->unk04; gSprites[spriteId].data[1] = -1; } gSprites[spriteId].data[2] = i * 32 + 8; gSprites[spriteId].data[4] = 0; gSprites[spriteId].invisible = TRUE; } REG_BLDCNT = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN; REG_BLDY = 16; HBlankIntrOn(sub_80C6078); } bool8 sub_80C5F98(void) { switch (gUnknown_020387EC->unk08) { case 0: gUnknown_020387EC->unk0C -= gUnknown_020387EC->unk06; if (gUnknown_020387EC->unk0C < 2) { BlendPalettes(gUnknown_020387EC->selectedPalettes, 16, FADE_COLOR_WHITE); SetHBlankCallback(sub_80C603C); gUnknown_020387EC->unk0C = 1; gUnknown_020387EC->unk08++; } break; case 1: if (gUnknown_020387EC->unk0A == 8) { BlendPalettes(0xFFFFFFFF, 16, RGB(0, 0, 0)); gUnknown_020387EC->unk08++; } break; case 2: REG_BLDCNT = 0; REG_BLDY = 0; FreeSpriteTilesByTag(gUnknown_020387EC->tileTag); FreeSpritePaletteByTag(gUnknown_020387EC->paletteTag); HBlankIntrOff(); gUnknown_020387EC->unk08++; return TRUE; default: return TRUE; } return FALSE; } static void sub_80C603C(void) { vu16 vcount = REG_VCOUNT & 0xFF; if (vcount == 0x50) REG_BLDCNT = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_EFFECT_LIGHTEN; else REG_BLDCNT = BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN; } static void sub_80C6078(void) { vu16 vcount = REG_VCOUNT & 0xFF; if (vcount > 0x50 - gUnknown_020387EC->unk0C && vcount < 0x50 + gUnknown_020387EC->unk0C) REG_BLDY = 0; else REG_BLDY = 16; } static void sub_80C60CC(struct Sprite *sprite) { sprite->x += sprite->data[0]; if (sprite->x < -0x08 || sprite->x > 0xf8) { DestroySprite(sprite); gUnknown_020387EC->unk0A++; if (gUnknown_020387EC->unk0A == 8) { FreeSpriteTilesByTag(gUnknown_020387EC->tileTag); FreeSpritePaletteByTag(gUnknown_020387EC->paletteTag); BlendPalettes(gUnknown_020387EC->selectedPalettes, 0, FADE_COLOR_WHITE); SetHBlankCallback(sub_80C6078); } } } static void sub_80C6130(struct Sprite *sprite) { if (sprite->data[4] == 0 && gUnknown_020387EC->unk0C == 1) { sprite->x += sprite->data[0]; if (sprite->x > -0x10 && sprite->x < 0x100) sprite->invisible = FALSE; if (sprite->data[1] > 0) { if (sprite->x >= sprite->data[2]) sprite->data[4] = 1; } else { if (sprite->x <= sprite->data[2]) sprite->data[4] = 1; } if (sprite->data[4]) { gUnknown_020387EC->unk0A++; sprite->x = sprite->data[2]; } } } static void HBlankIntrOn(IntrFunc cb) { u16 imeBak; INTR_CHECK |= INTR_FLAG_HBLANK; REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; imeBak = REG_IME; REG_IME = 0; REG_IE |= INTR_FLAG_HBLANK; REG_IME = imeBak; gMain.intrCheck |= INTR_FLAG_HBLANK; SetHBlankCallback(cb); } static void HBlankIntrOff(void) { u16 imeBak; INTR_CHECK &= ~INTR_FLAG_HBLANK; REG_DISPSTAT &= ~DISPSTAT_HBLANK_INTR; imeBak = REG_IME; REG_IME = 0; REG_IE &= ~INTR_FLAG_HBLANK; REG_IME = imeBak; gMain.intrCheck &= ~INTR_FLAG_HBLANK; SetHBlankCallback(NULL); }