mirror of
https://github.com/pret/pokepinballrs.git
synced 2026-04-26 00:37:22 -05:00
* kickback naming, catch state enum * sound renaming through 98 * initial block * pre split comments * launcher clarity, board designations * split out save_and_restore file * board indicator file split, board setup named * rename debug, split off center_capture_hole * checkpoint * pointer carving
This commit is contained in:
parent
77c628e0ee
commit
e78163d87a
1617
data/rom_1.s
1617
data/rom_1.s
File diff suppressed because it is too large
Load Diff
416
data/rom_2.s
416
data/rom_2.s
|
|
@ -4206,7 +4206,7 @@ gHatchPieceMatrixNums:: @ 0x086AE318
|
|||
gOneUpSpritePalette:: @ 0x086AE324
|
||||
.incbin "baserom.gba", 0x6AE324, 0x20
|
||||
|
||||
gSapphirePondAnimFramesets:: @ 0x086AE344
|
||||
gSpoinkAnimFrameset:: @ 0x086AE344
|
||||
.incbin "baserom.gba", 0x6AE344, 0x50
|
||||
|
||||
gTravelEventAnimData:: @ 0x086AE394
|
||||
|
|
@ -4535,112 +4535,436 @@ gRubySlingshotAnimIndices:: @ 0x086B08CA
|
|||
.incbin "baserom.gba", 0x6B08CA, 0xA
|
||||
|
||||
gRubySlingshotTilePointers:: @ 0x086B08D4
|
||||
.incbin "baserom.gba", 0x6B08D4, 0x78
|
||||
@ Arranged into 2(sides) sets of 3 sets of 5.
|
||||
@ Third set of 5 is the destination address.
|
||||
.4byte gUnknown_082647F0, gUnknown_08264BF0, gUnknown_08264FF0, gUnknown_082653F0, gUnknown_08265810
|
||||
.4byte gUnknown_08264850, gUnknown_08264C50, gUnknown_08265050, gUnknown_08265450, gUnknown_08265870
|
||||
.4byte 0x0600DA00, 0x0600DA20, 0x0600DA60, 0x0600DAC0, 0x0600DB20
|
||||
|
||||
.4byte gUnknown_082648F0, gUnknown_08264CD0, gUnknown_082650B0, gUnknown_082654B0, gUnknown_082658B0
|
||||
.4byte gUnknown_08264950, gUnknown_08264D30, gUnknown_08265110, gUnknown_08265510, gUnknown_08265910
|
||||
.4byte 0x0600DB60, 0x0600DB80, 0x0600DBC0, 0x0600DC20, 0x0600DC80
|
||||
|
||||
gShopItemTilePointers:: @ 0x086B094C
|
||||
.incbin "baserom.gba", 0x6B094C, 0x24
|
||||
@ Arranged into 3 sets of 3.
|
||||
@ Third set is the destination address.
|
||||
.4byte gUnknown_08262BB0, gUnknown_08262FB0, gUnknown_08263430
|
||||
.4byte gUnknown_08262C70, gUnknown_08263070, gUnknown_082634F0
|
||||
.4byte 0x0600D860, 0x0600D920, 0x0600D9E0
|
||||
|
||||
gRubyProgressDigitTilePointers:: @ 0x086B0970
|
||||
.incbin "baserom.gba", 0x6B0970, 0x58
|
||||
@ 11 sets of 2.
|
||||
@ Eleventh has the destination address.
|
||||
.4byte gUnknown_08262790, gUnknown_082628D0
|
||||
.4byte gUnknown_082627B0, gUnknown_082628F0
|
||||
.4byte gUnknown_082627D0, gUnknown_08262910
|
||||
.4byte gUnknown_082627F0, gUnknown_08262930
|
||||
.4byte gUnknown_08262810, gUnknown_08262950
|
||||
.4byte gUnknown_08262830, gUnknown_08262970
|
||||
.4byte gUnknown_08262850, gUnknown_08262990
|
||||
.4byte gUnknown_08262870, gUnknown_082629B0
|
||||
.4byte gUnknown_08262890, gUnknown_082629D0
|
||||
.4byte gUnknown_082628B0, gUnknown_082629F0
|
||||
.4byte 0x0600D820, 0x0600D840
|
||||
|
||||
gRubyTrapIndicatorTilePointers:: @ 0x086B09C8
|
||||
.incbin "baserom.gba", 0x6B09C8, 0x20
|
||||
@ 4 sets of 2
|
||||
@ fourth set has destination address
|
||||
.4byte gUnknown_0825FF30, gUnknown_08260330
|
||||
.4byte gUnknown_0825FF70, gUnknown_08260370
|
||||
.4byte gUnknown_0825FFB0, gUnknown_082603B0
|
||||
.4byte 0x060081C0, 0x060085C0
|
||||
|
||||
gRubyCatchLightTilePointers:: @ 0x086B09E8
|
||||
.incbin "baserom.gba", 0x6B09E8, 0xA8
|
||||
@ 3 sets of 7 sets of 2
|
||||
@ seventh set has destination address
|
||||
.4byte gUnknown_0825FAB0, gUnknown_0825FEB0
|
||||
.4byte gUnknown_0825FAF0, gUnknown_0825FEF0
|
||||
.4byte gUnknown_0825FFF0, gUnknown_082603F0
|
||||
.4byte gUnknown_08260030, gUnknown_08260430
|
||||
.4byte gUnknown_08260170, gUnknown_08260570
|
||||
.4byte gUnknown_082601B0, gUnknown_082605B0
|
||||
.4byte 0x0600A180, 0x0600A580
|
||||
|
||||
.4byte gUnknown_0825FAB0, gUnknown_0825FEB0
|
||||
.4byte gUnknown_0825FAF0, gUnknown_0825FEF0
|
||||
.4byte gUnknown_08260070, gUnknown_08260470
|
||||
.4byte gUnknown_082600B0, gUnknown_082604B0
|
||||
.4byte gUnknown_082601F0, gUnknown_082605F0
|
||||
.4byte gUnknown_08260230, gUnknown_08260630
|
||||
.4byte 0x0600A1C0, 0x0600A5C0
|
||||
|
||||
.4byte gUnknown_0825FAB0, gUnknown_0825FEB0
|
||||
.4byte gUnknown_0825FAF0, gUnknown_0825FEF0
|
||||
.4byte gUnknown_082600F0, gUnknown_082604F0
|
||||
.4byte gUnknown_08260130, gUnknown_08260530
|
||||
.4byte gUnknown_08260270, gUnknown_08260670
|
||||
.4byte gUnknown_082602B0, gUnknown_082606B0
|
||||
.4byte 0x0600A200, 0x0600A600
|
||||
|
||||
gRubyModeTimerTilePointers:: @ 0x086B0A90
|
||||
.incbin "baserom.gba", 0x6B0A90, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_08260770, gUnknown_08260B70, gUnknown_08260F90, gUnknown_082613F0
|
||||
.4byte gUnknown_08260870, gUnknown_08260C70, gUnknown_08261090, gUnknown_082614F0
|
||||
.4byte 0x0600AD80, 0x0600B180, 0x0600B5A0, 0x0600BA00
|
||||
|
||||
gRubyCatchArrowTilePointers:: @ 0x086B0AC0
|
||||
.incbin "baserom.gba", 0x6B0AC0, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_08261770, gUnknown_08261B70, gUnknown_08261F70, gUnknown_08262370
|
||||
.4byte gUnknown_082617F0, gUnknown_08261BF0, gUnknown_08261FF0, gUnknown_082623F0
|
||||
.4byte 0x0600B960, 0x0600BD60, 0x0600C160, 0x0600C560
|
||||
|
||||
gRubyEvoArrowTilePointers:: @ 0x086B0AF0
|
||||
.incbin "baserom.gba", 0x6B0AF0, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_082619B0, gUnknown_08261D70, gUnknown_08262170, gUnknown_08262570
|
||||
.4byte gUnknown_08261A30, gUnknown_08261DF0, gUnknown_082621F0, gUnknown_082625F0
|
||||
.4byte 0x0600B620, 0x0600B9E0, 0x0600BDE0, 0x0600C1E0
|
||||
|
||||
gRubyRouletteSlotTilePointers:: @ 0x086B0B20
|
||||
.incbin "baserom.gba", 0x6B0B20, 0x50
|
||||
@ 5 sets of 4
|
||||
@ fifth set has the destination address
|
||||
.4byte gUnknown_08263910, gUnknown_08263D10, gUnknown_08264110, gUnknown_08264510
|
||||
.4byte gUnknown_082639B0, gUnknown_08263DB0, gUnknown_082641B0, gUnknown_082645B0
|
||||
.4byte gUnknown_082637D0, gUnknown_08263BD0, gUnknown_08263FD0, gUnknown_082643D0
|
||||
.4byte gUnknown_08263870, gUnknown_08263C70, gUnknown_08264070, gUnknown_08264470
|
||||
.4byte 0x0600C620, 0x0600CA20, 0x0600CE20, 0x0600D220
|
||||
|
||||
gRubyBallPowerUpLightTilePointers:: @ 0x086B0B70
|
||||
.incbin "baserom.gba", 0x6B0B70, 0x24
|
||||
@ 3 sets of 3
|
||||
@ third value has the destination address
|
||||
.4byte gUnknown_0825F730, gUnknown_0825F770, 0x060085C0
|
||||
.4byte gUnknown_0825F7B0, gUnknown_0825F7F0, 0x06008600
|
||||
.4byte gUnknown_0825F830, gUnknown_0825F870, 0x06008660
|
||||
|
||||
gRubyCatchProgressArrowTilePointers:: @ 0x086B0B94
|
||||
.incbin "baserom.gba", 0x6B0B94, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has the destination address
|
||||
.4byte gUnknown_082618B0, gUnknown_08261C70, gUnknown_08262070, gUnknown_08262470
|
||||
.4byte gUnknown_08261930, gUnknown_08261CF0, gUnknown_082620F0, gUnknown_082624F0
|
||||
.4byte 0x0600D2A0, 0x0600D660, 0x06008260, 0x06008660
|
||||
|
||||
gRubyHoleIndicatorTilePointers:: @ 0x086B0BC4
|
||||
.incbin "baserom.gba", 0x6B0BC4, 0x40
|
||||
@ 4 sets of 4
|
||||
@ third value has the destination; fouth value blank.
|
||||
.4byte gUnknown_0825F8B0, gUnknown_0825F8F0, 0x0600A460, 0
|
||||
.4byte gUnknown_0825F930, gUnknown_0825F970, 0x0600A4C0, 0
|
||||
.4byte gUnknown_0825F9B0, gUnknown_0825F9F0, 0x0600A6C0, 0
|
||||
.4byte gUnknown_0825FA30, gUnknown_0825FA70, 0x0600A720, 0
|
||||
|
||||
gSapphireEvoArrowTilePtrs:: @ 0x086B0C04
|
||||
.incbin "baserom.gba", 0x6B0C04, 0xB4
|
||||
gRubyEvoArrowTilePtrs:: @ 0x086B0C04
|
||||
@ 3 sets of 5 sets of 3
|
||||
@ fifth set has the destination address
|
||||
.4byte gUnknown_0825D310, gUnknown_0825D710, gUnknown_0825DB10
|
||||
.4byte gUnknown_0825D310, gUnknown_0825D710, gUnknown_0825DB10
|
||||
.4byte gUnknown_0825D370, gUnknown_0825D770, gUnknown_0825DB70
|
||||
.4byte gUnknown_0825D3D0, gUnknown_0825D7D0, gUnknown_0825DBD0
|
||||
.4byte 0x0600D080, 0x0600D480, 0x06008080
|
||||
|
||||
gSapphireCoinRewardTilePtrs:: @ 0x086B0CB8
|
||||
.incbin "baserom.gba", 0x6B0CB8, 0xB4
|
||||
.4byte gUnknown_0825D430, gUnknown_0825D830, gUnknown_0825DC30
|
||||
.4byte gUnknown_0825D490, gUnknown_0825D890, gUnknown_0825DC90
|
||||
.4byte gUnknown_0825D4F0, gUnknown_0825D8F0, gUnknown_0825DCF0
|
||||
.4byte gUnknown_0825D550, gUnknown_0825D950, gUnknown_0825DD50
|
||||
.4byte 0x060080A0, 0x060084A0, 0x060088A0
|
||||
|
||||
gSapphireCatchArrowTilePtrs:: @ 0x086B0D6C
|
||||
.incbin "baserom.gba", 0x6B0D6C, 0xB4
|
||||
.4byte gUnknown_0825D5B0, gUnknown_0825D9B0, gUnknown_0825DDB0
|
||||
.4byte gUnknown_0825D5B0, gUnknown_0825D9B0, gUnknown_0825DDB0
|
||||
.4byte gUnknown_0825D610, gUnknown_0825DA10, gUnknown_0825DE10
|
||||
.4byte gUnknown_0825D670, gUnknown_0825DA70, gUnknown_0825DE70
|
||||
.4byte 0x060088C0, 0x06008CC0, 0x060090C0
|
||||
|
||||
gRubyCoinRewardTilePtrs:: @ 0x086B0CB8
|
||||
@ 3 sets of 5 sets of 3
|
||||
@ fifth set has the destination address
|
||||
.4byte gUnknown_0825DF10, gUnknown_0825E310, gUnknown_0825E710
|
||||
.4byte gUnknown_0825DF10, gUnknown_0825E310, gUnknown_0825E710
|
||||
.4byte gUnknown_0825DF70, gUnknown_0825E370, gUnknown_0825E770
|
||||
.4byte gUnknown_0825DFD0, gUnknown_0825E3D0, gUnknown_0825E7D0
|
||||
.4byte 0x0600B4E0, 0x0600B8E0, 0x0600BCE0
|
||||
|
||||
.4byte gUnknown_0825E030, gUnknown_0825E430, gUnknown_0825E830
|
||||
.4byte gUnknown_0825E090, gUnknown_0825E490, gUnknown_0825E890
|
||||
.4byte gUnknown_0825E0F0, gUnknown_0825E4F0, gUnknown_0825E8F0
|
||||
.4byte gUnknown_0825E150, gUnknown_0825E550, gUnknown_0825E950
|
||||
.4byte 0x0600BCE0, 0x0600C0E0, 0x0600C4E0
|
||||
|
||||
.4byte gUnknown_0825E1B0, gUnknown_0825E5B0, gUnknown_0825E9B0
|
||||
.4byte gUnknown_0825E1B0, gUnknown_0825E5B0, gUnknown_0825E9B0
|
||||
.4byte gUnknown_0825E210, gUnknown_0825E610, gUnknown_0825EA10
|
||||
.4byte gUnknown_0825E270, gUnknown_0825E670, gUnknown_0825EA70
|
||||
.4byte 0x0600C500, 0x0600C900, 0x0600CD00
|
||||
|
||||
gRubyCatchArrowTilePtrs:: @ 0x086B0D6C
|
||||
@ 3 sets of 5 sets of 3
|
||||
@ fifth set has the destination address
|
||||
.4byte gUnknown_0825EB10, gUnknown_0825EF10, gUnknown_0825F310
|
||||
.4byte gUnknown_0825EB10, gUnknown_0825EF10, gUnknown_0825F310
|
||||
.4byte gUnknown_0825EB70, gUnknown_0825EF70, gUnknown_0825F370
|
||||
.4byte gUnknown_0825EBD0, gUnknown_0825EFD0, gUnknown_0825F3D0
|
||||
.4byte 0x0600D2E0, 0x0600D6E0, 0x060082E0
|
||||
|
||||
.4byte gUnknown_0825EC50, gUnknown_0825F050, gUnknown_0825F430
|
||||
.4byte gUnknown_0825ECB0, gUnknown_0825F0B0, gUnknown_0825F490
|
||||
.4byte gUnknown_0825ED10, gUnknown_0825F110, gUnknown_0825F4F0
|
||||
.4byte gUnknown_0825ED70, gUnknown_0825F170, gUnknown_0825F550
|
||||
.4byte 0x060082E0, 0x060086E0, 0x06008AC0
|
||||
|
||||
.4byte gUnknown_0825EDD0, gUnknown_0825F1B0, gUnknown_0825F5B0
|
||||
.4byte gUnknown_0825EDD0, gUnknown_0825F1B0, gUnknown_0825F5B0
|
||||
.4byte gUnknown_0825EE30, gUnknown_0825F210, gUnknown_0825F610
|
||||
.4byte gUnknown_0825EE90, gUnknown_0825F270, gUnknown_0825F670
|
||||
.4byte 0x06008AC0, 0x06008EA0, 0x060092A0
|
||||
|
||||
gBallShadowTileIndices:: @ 0x086B0E20
|
||||
.incbin "baserom.gba", 0x6B0E20, 0x40
|
||||
@ 31 values (ix 0 - 30) used, then padding
|
||||
.2byte 0,0,0,0,1,1,1,1,2,2
|
||||
.2byte 2,2,3,3,3,3,4,4,4,4
|
||||
.2byte 4,5,5,5,5,5,5,5,5,5
|
||||
.2byte 5
|
||||
.align 2, 0
|
||||
|
||||
gSlingshotHitFrameIndices:: @ 0x086B0E60
|
||||
.incbin "baserom.gba", 0x6B0E60, 0xC
|
||||
.2byte 0,1,1,1,1,0
|
||||
|
||||
gBumperHitCounterTilePtrs:: @ 0x086B0E6C
|
||||
.incbin "baserom.gba", 0x6B0E6C, 0x30
|
||||
@ 6 sets of 2
|
||||
@ sixth set has destination address
|
||||
.4byte gUnknown_082DEEE0, gUnknown_082DF2E0
|
||||
.4byte gUnknown_082DEF20, gUnknown_082DF320
|
||||
.4byte gUnknown_082DEF60, gUnknown_082DF360
|
||||
.4byte gUnknown_082DEFA0, gUnknown_082DF3A0
|
||||
.4byte gUnknown_082DEFE0, gUnknown_082DF3E0
|
||||
.4byte 0x0600A640, 0x0600AA40
|
||||
|
||||
gSapphireProgressDigitTilePtrs:: @ 0x086B0E9C
|
||||
.incbin "baserom.gba", 0x6B0E9C, 0xB0
|
||||
@ 11 sets of 4
|
||||
@ eleventh set has destination address
|
||||
.4byte gUnknown_082DCE00, gUnknown_082DD200, gUnknown_082DCF40, gUnknown_082DD340
|
||||
.4byte gUnknown_082DCE20, gUnknown_082DD220, gUnknown_082DCF60, gUnknown_082DD360
|
||||
.4byte gUnknown_082DCE40, gUnknown_082DD240, gUnknown_082DCF80, gUnknown_082DD380
|
||||
.4byte gUnknown_082DCE60, gUnknown_082DD260, gUnknown_082DCFA0, gUnknown_082DD3A0
|
||||
.4byte gUnknown_082DCE80, gUnknown_082DD280, gUnknown_082DCFC0, gUnknown_082DD3C0
|
||||
.4byte gUnknown_082DCEA0, gUnknown_082DD2A0, gUnknown_082DCFE0, gUnknown_082DD3E0
|
||||
.4byte gUnknown_082DCEC0, gUnknown_082DD2C0, gUnknown_082DD000, gUnknown_082DD400
|
||||
.4byte gUnknown_082DCEE0, gUnknown_082DD2E0, gUnknown_082DD020, gUnknown_082DD420
|
||||
.4byte gUnknown_082DCF00, gUnknown_082DD300, gUnknown_082DD040, gUnknown_082DD440
|
||||
.4byte gUnknown_082DCF20, gUnknown_082DD320, gUnknown_082DD060, gUnknown_082DD460
|
||||
.4byte 0x0600B220, 0x0600B620, 0x0600B240, 0x0600B640
|
||||
|
||||
gRotatingBackgroundTilePtrs:: @ 0x086B0F4C
|
||||
.incbin "baserom.gba", 0x6B0F4C, 0x50
|
||||
@ 5 sets of 4
|
||||
@ fifth set has destination address
|
||||
.4byte gUnknown_082E3EC0, gUnknown_082E42C0, gUnknown_082E46C0, gUnknown_082E4AC0
|
||||
.4byte gUnknown_082E3F40, gUnknown_082E4340, gUnknown_082E4740, gUnknown_082E4B40
|
||||
.4byte gUnknown_082E3FC0, gUnknown_082E43C0, gUnknown_082E47C0, gUnknown_082E4BC0
|
||||
.4byte gUnknown_082E3F40, gUnknown_082E4340, gUnknown_082E4740, gUnknown_082E4B40
|
||||
.4byte 0x0600AEA0, 0x0600B2A0, 0x0600B6A0, 0x0600BAA0
|
||||
|
||||
gBonusModeIndicatorTilePtrs:: @ 0x086B0F9C
|
||||
.incbin "baserom.gba", 0x6B0F9C, 0x10
|
||||
gHatchMachineDrawSegment:: @ 0x086B0F9C
|
||||
@ 10 sets of 3 sets of 2
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_082DE1E0, gUnknown_082DE5E0
|
||||
.4byte gUnknown_082DE620, gUnknown_082DEA20
|
||||
.4byte 0x0600DD40, 0x0600DD80
|
||||
|
||||
gUnknown_086B0FAC:: @ 0x086B0FAC
|
||||
.incbin "baserom.gba", 0x6B0FAC, 0xE0
|
||||
.4byte gUnknown_082DE660, gUnknown_082DEA60
|
||||
.4byte gUnknown_082DE6A0, gUnknown_082DEAA0
|
||||
.4byte 0x0600DDC0, 0x0600DE00
|
||||
|
||||
.4byte gUnknown_082DE6E0, gUnknown_082DEAE0
|
||||
.4byte gUnknown_082DE720, gUnknown_082DEB20
|
||||
.4byte 0x0600D9C0, 0x0600DAC0
|
||||
|
||||
.4byte gUnknown_082DEB60, gUnknown_082DEB60
|
||||
.4byte gUnknown_082DEBA0, gUnknown_082DEBA0
|
||||
.4byte 0x0600DE40, 0x0600DE40
|
||||
|
||||
.4byte gUnknown_082DE7E0, gUnknown_082DEBE0
|
||||
.4byte gUnknown_082DE820, gUnknown_082DEC20
|
||||
.4byte 0x0600D900, 0x0600DA00
|
||||
|
||||
.4byte gUnknown_082DE860, gUnknown_082DEC60
|
||||
.4byte gUnknown_082DE8A0, gUnknown_082DECA0
|
||||
.4byte 0x0600DE80, 0x0600DEC0
|
||||
|
||||
.4byte gUnknown_082DE8E0, gUnknown_082DECE0
|
||||
.4byte gUnknown_082DE920, gUnknown_082DED20
|
||||
.4byte 0x0600DF00, 0x0600DF40
|
||||
|
||||
.4byte gUnknown_082DE960, gUnknown_082DED60
|
||||
.4byte gUnknown_082DE9A0, gUnknown_082DEDA0
|
||||
.4byte 0x0600DF80, 0x0600DFC0
|
||||
|
||||
.4byte gUnknown_082DE9E0, gUnknown_082DEDE0
|
||||
.4byte gUnknown_082DEE20, gUnknown_082DF220
|
||||
.4byte 0x0600E000, 0x0600E040
|
||||
|
||||
.4byte gUnknown_082DEE60, gUnknown_082DF260
|
||||
.4byte gUnknown_082DEEA0, gUnknown_082DF2A0
|
||||
.4byte 0x0600E080, 0x0600E0C0
|
||||
|
||||
gSapphireSlingshotTilePtrs:: @ 0x086B108C
|
||||
.incbin "baserom.gba", 0x6B108C, 0x78
|
||||
@ 2 sets (sides) of 3 sets of 5
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_082E2AA0, gUnknown_082E2EA0, gUnknown_082E32A0, gUnknown_082E36A0, gUnknown_082E3AC0
|
||||
.4byte gUnknown_082E2B00, gUnknown_082E2F00, gUnknown_082E3300, gUnknown_082E3700, gUnknown_082E3B20
|
||||
.4byte 0x0600E100, 0x0600E120, 0x0600E160, 0x0600E1C0, 0x0600E220
|
||||
|
||||
.4byte gUnknown_082E2BA0, gUnknown_082E2F80, gUnknown_082E3360, gUnknown_082E3760, gUnknown_082E3B60
|
||||
.4byte gUnknown_082E2C00, gUnknown_082E2FE0, gUnknown_082E33C0, gUnknown_082E37C0, gUnknown_082E3BC0
|
||||
.4byte 0x0600E260, 0x0600E280, 0x0600E2C0, 0x0600E320, 0x0600E380
|
||||
|
||||
gSapphireTrapIndicatorTilePtrs:: @ 0x086B1104
|
||||
.incbin "baserom.gba", 0x6B1104, 0x20
|
||||
@ 4 sets of 2
|
||||
@ fourth set has destination address
|
||||
.4byte gUnknown_082DDE20, gUnknown_082DE220
|
||||
.4byte gUnknown_082DDE60, gUnknown_082DE260
|
||||
.4byte gUnknown_082DDEA0, gUnknown_082DE2A0
|
||||
.4byte 0x060081C0, 0x060085C0
|
||||
|
||||
gSapphireCatchLightTilePtrs:: @ 0x086B1124
|
||||
.incbin "baserom.gba", 0x6B1124, 0xA8
|
||||
@ 3 sets of 7 sets of 2
|
||||
@ seventh set has destination address
|
||||
.4byte gUnknown_082DD9A0, gUnknown_082DDDA0
|
||||
.4byte gUnknown_082DD9E0, gUnknown_082DDDE0
|
||||
.4byte gUnknown_082DDEE0, gUnknown_082DE2E0
|
||||
.4byte gUnknown_082DDF20, gUnknown_082DE320
|
||||
.4byte gUnknown_082DE060, gUnknown_082DE460
|
||||
.4byte gUnknown_082DE0A0, gUnknown_082DE4A0
|
||||
.4byte 0x0600A180, 0x0600A580
|
||||
|
||||
.4byte gUnknown_082DD9A0, gUnknown_082DDDA0
|
||||
.4byte gUnknown_082DD9E0, gUnknown_082DDDE0
|
||||
.4byte gUnknown_082DDF60, gUnknown_082DE360
|
||||
.4byte gUnknown_082DDFA0, gUnknown_082DE3A0
|
||||
.4byte gUnknown_082DE0E0, gUnknown_082DE4E0
|
||||
.4byte gUnknown_082DE120, gUnknown_082DE520
|
||||
.4byte 0x0600A1C0, 0x0600A5C0
|
||||
|
||||
.4byte gUnknown_082DD9A0, gUnknown_082DDDA0
|
||||
.4byte gUnknown_082DD9E0, gUnknown_082DDDE0
|
||||
.4byte gUnknown_082DDFE0, gUnknown_082DE3E0
|
||||
.4byte gUnknown_082DE020, gUnknown_082DE420
|
||||
.4byte gUnknown_082DE160, gUnknown_082DE560
|
||||
.4byte gUnknown_082DE1A0, gUnknown_082DE5A0
|
||||
.4byte 0x0600A200, 0x0600A600
|
||||
|
||||
gSapphireModeTimerDisplayTilePtrs:: @ 0x086B11CC
|
||||
.incbin "baserom.gba", 0x6B11CC, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_082DF660, gUnknown_082DFA60, gUnknown_082DFE80, gUnknown_082E02E0
|
||||
.4byte gUnknown_082DF760, gUnknown_082DFB60, gUnknown_082DFF80, gUnknown_082E03E0
|
||||
.4byte 0x0600AD80, 0x0600B180, 0x0600B5A0, 0x0600BA00
|
||||
|
||||
gSapphireCatchArrowPaletteTilePtrs:: @ 0x086B11FC
|
||||
.incbin "baserom.gba", 0x6B11FC, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_082E06A0, gUnknown_082E0A60, gUnknown_082E0E60, gUnknown_082E1260
|
||||
.4byte gUnknown_082E0720, gUnknown_082E0AE0, gUnknown_082E0EE0, gUnknown_082E12E0
|
||||
.4byte 0x0600CEA0, 0x0600D260, 0x0600D660, 0x06008260
|
||||
|
||||
gSapphireEvoArrowPaletteTilePtrs:: @ 0x086B122C
|
||||
.incbin "baserom.gba", 0x6B122C, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_082E0860, gUnknown_082E0C60, gUnknown_082E1060, gUnknown_082E1460
|
||||
.4byte gUnknown_082E08E0, gUnknown_082E0CE0, gUnknown_082E10E0, gUnknown_082E14E0
|
||||
.4byte 0x0600A9A0, 0x0600ADA0, 0x0600B1A0, 0x0600B5A0
|
||||
|
||||
gSapphireRouletteSlotTilePtrs:: @ 0x086B125C
|
||||
.incbin "baserom.gba", 0x6B125C, 0x50
|
||||
@ 5 sets of 4
|
||||
@ fifth set has destination address
|
||||
.4byte gUnknown_082E1680, gUnknown_082E1A80, gUnknown_082E1E80, gUnknown_082E2280
|
||||
.4byte gUnknown_082E1700, gUnknown_082E1B00, gUnknown_082E1F00, gUnknown_082E2300
|
||||
.4byte gUnknown_082E1780, gUnknown_082E1B80, gUnknown_082E1F80, gUnknown_082E2380
|
||||
.4byte gUnknown_082E1800, gUnknown_082E1C00, gUnknown_082E2000, gUnknown_082E2400
|
||||
.4byte 0x0600BD20, 0x0600C120, 0x0600C520, 0x0600C920
|
||||
|
||||
gSapphireBallPowerUpLightTilePtrs:: @ 0x086B12AC
|
||||
.incbin "baserom.gba", 0x6B12AC, 0x24
|
||||
@ 3 sets of 3
|
||||
@ third value has destination address
|
||||
.4byte gUnknown_082DD620, gUnknown_082DD660, 0x06008540
|
||||
.4byte gUnknown_082DD6A0, gUnknown_082DD6E0, 0x060085A0
|
||||
.4byte gUnknown_082DD720, gUnknown_082DD760, 0x060085E0
|
||||
|
||||
gSapphireCatchFlashTilePtrs:: @ 0x086B12D0
|
||||
.incbin "baserom.gba", 0x6B12D0, 0x30
|
||||
@ 3 sets of 4
|
||||
@ third set has destination address
|
||||
.4byte gUnknown_082E0780, gUnknown_082E0B60, gUnknown_082E0F60, gUnknown_082E1360
|
||||
.4byte gUnknown_082E0800, gUnknown_082E0BE0, gUnknown_082E0FE0, gUnknown_082E13E0
|
||||
.4byte 0x0600C260, 0x0600C640, 0x0600CA40, 0x0600CE40
|
||||
|
||||
gSapphireHoleIndicatorTilePtrs:: @ 0x086B1300
|
||||
.incbin "baserom.gba", 0x6B1300, 0x40
|
||||
@ 4 sets of 4
|
||||
@ third value has the destination; fouth value blank.
|
||||
.4byte gUnknown_082DD7A0, gUnknown_082DD7E0, 0x0600A460, 0
|
||||
.4byte gUnknown_082DD820, gUnknown_082DD860, 0x0600A4C0, 0
|
||||
.4byte gUnknown_082DD8A0, gUnknown_082DD8E0, 0x0600A6C0, 0
|
||||
.4byte gUnknown_082DD920, gUnknown_082DD960, 0x0600A720, 0
|
||||
|
||||
gSapphireEvoArrowBonusTilePtrs:: @ 0x086B1340
|
||||
.incbin "baserom.gba", 0x6B1340, 0xB4
|
||||
gSapphireEvoArrowTilePtrs:: @ 0x086B1340
|
||||
@ 3 sets of 5 sets of 3
|
||||
@ fifth set has destination address
|
||||
.4byte gUnknown_082DA9E0, gUnknown_082DADE0, gUnknown_082DB1E0
|
||||
.4byte gUnknown_082DA9E0, gUnknown_082DADE0, gUnknown_082DB1E0
|
||||
.4byte gUnknown_082DAA40, gUnknown_082DAE40, gUnknown_082DB240
|
||||
.4byte gUnknown_082DAAA0, gUnknown_082DAEA0, gUnknown_082DB2A0
|
||||
.4byte 0x0600D080, 0x0600D480, 0x06008080
|
||||
|
||||
gSapphireCoinRewardAltTilePtrs:: @ 0x086B13F4
|
||||
.incbin "baserom.gba", 0x6B13F4, 0x78
|
||||
.4byte gUnknown_082DAB00, gUnknown_082DAF00, gUnknown_082DB300
|
||||
.4byte gUnknown_082DAB60, gUnknown_082DAF60, gUnknown_082DB360
|
||||
.4byte gUnknown_082DABC0, gUnknown_082DAFC0, gUnknown_082DB3C0
|
||||
.4byte gUnknown_082DAC20, gUnknown_082DB020, gUnknown_082DB420
|
||||
.4byte 0x060080A0, 0x060084A0, 0x060088A0
|
||||
|
||||
gUnknown_086B146C:: @ 0x086B146C
|
||||
.incbin "baserom.gba", 0x6B146C, 0x3C
|
||||
.4byte gUnknown_082DAC80, gUnknown_082DB080, gUnknown_082DB4A0
|
||||
.4byte gUnknown_082DAC80, gUnknown_082DB080, gUnknown_082DB4A0
|
||||
.4byte gUnknown_082DACE0, gUnknown_082DB0E0, gUnknown_082DB500
|
||||
.4byte gUnknown_082DAD40, gUnknown_082DB140, gUnknown_082DB560
|
||||
.4byte 0x060088C0, 0x06008CC0, 0x060090E0
|
||||
|
||||
gSapphireCatchArrowBonusTilePtrs:: @ 0x086B14A8
|
||||
.incbin "baserom.gba", 0x6B14A8, 0xB4
|
||||
gSapphireCoinRewardTilePtrs:: @ 0x086B13F4
|
||||
@ 3 sets of 5 sets of 3
|
||||
@ fourth set has destination address; fifth has spacers
|
||||
.4byte gUnknown_082DB5E0, gUnknown_082DB9E0, gUnknown_082DBDE0
|
||||
.4byte gUnknown_082DB640, gUnknown_082DBA40, gUnknown_082DBE40
|
||||
.4byte gUnknown_082DB6A0, gUnknown_082DBAA0, gUnknown_082DBEA0
|
||||
.4byte 0x0600C4A0, 0x0600C8A0, 0x0600CCA0
|
||||
.4byte 0,0,0
|
||||
|
||||
.4byte gUnknown_082DB720, gUnknown_082DBB20, gUnknown_082DBF20
|
||||
.4byte gUnknown_082DB780, gUnknown_082DBB80, gUnknown_082DBF80
|
||||
.4byte gUnknown_082DB7E0, gUnknown_082DBBE0, gUnknown_082DBFE0
|
||||
.4byte 0x0600CCE0, 0x0600D0E0, 0x0600D4C0
|
||||
.4byte 0,0,0
|
||||
|
||||
.4byte gUnknown_082DB820, gUnknown_082DBC20, gUnknown_082DC020
|
||||
.4byte gUnknown_082DB880, gUnknown_082DBC80, gUnknown_082DC080
|
||||
.4byte gUnknown_082DB8E0, gUnknown_082DBCE0, gUnknown_082DC0E0
|
||||
.4byte 0x0600D0E0, 0x0600D4E0, 0x060080E0
|
||||
.4byte 0,0,0
|
||||
|
||||
gSapphireCatchArrowTilePtrs:: @ 0x086B14A8
|
||||
@ 3 sets of 5 sets of 3
|
||||
@ fifth set has destination address
|
||||
.4byte gUnknown_082DC1E0, gUnknown_082DC5E0, gUnknown_082DC9E0
|
||||
.4byte gUnknown_082DC1E0, gUnknown_082DC5E0, gUnknown_082DC9E0
|
||||
.4byte gUnknown_082DC240, gUnknown_082DC640, gUnknown_082DCA40
|
||||
.4byte gUnknown_082DC2A0, gUnknown_082DC6A0, gUnknown_082DCAA0
|
||||
.4byte 0x0600D2E0, 0x0600D6E0, 0x060082E0
|
||||
|
||||
.4byte gUnknown_082DC320, gUnknown_082DC720, gUnknown_082DCB00
|
||||
.4byte gUnknown_082DC380, gUnknown_082DC780, gUnknown_082DCB60
|
||||
.4byte gUnknown_082DC3E0, gUnknown_082DC7E0, gUnknown_082DCBC0
|
||||
.4byte gUnknown_082DC440, gUnknown_082DC840, gUnknown_082DCC20
|
||||
.4byte 0x060082E0, 0x060086E0, 0x06008AC0
|
||||
|
||||
.4byte gUnknown_082DC4A0, gUnknown_082DC880, gUnknown_082DCC80
|
||||
.4byte gUnknown_082DC4A0, gUnknown_082DC880, gUnknown_082DCC80
|
||||
.4byte gUnknown_082DC500, gUnknown_082DC8E0, gUnknown_082DCCE0
|
||||
.4byte gUnknown_082DC560, gUnknown_082DC940, gUnknown_082DCD40
|
||||
.4byte 0x06008AC0, 0x06008EA0, 0x060092A0
|
||||
|
||||
gFieldSpriteSets:: @ 0x086B155C
|
||||
.4byte gUnknown_086B2390
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 186 B After Width: | Height: | Size: 186 B |
Binary file not shown.
|
Before Width: | Height: | Size: 186 B |
|
|
@ -435,7 +435,7 @@ extern void DispatchRubyCatchModeInit();
|
|||
extern void UpdateRubyCatchModeAnimation(void);
|
||||
//extern ? InitSharpedoCatchMode();
|
||||
extern void AnimateSharpedoCatchSequence();
|
||||
extern void InitEggHatchMode(void);
|
||||
extern void InitRubyEggHatchMode(void);
|
||||
//extern ? AnimateEggHatchSequence();
|
||||
//extern ? InitRubyEvolutionShopMode();
|
||||
//extern ? AnimateRubyEvolutionShopSequence();
|
||||
|
|
@ -483,9 +483,9 @@ extern void UpdatePokemonNamePosition();
|
|||
extern void HidePokemonNameDisplay();
|
||||
extern void InitEvolutionSuccessDisplay(void);
|
||||
extern void AnimateEvolutionSuccessScreen(void);
|
||||
extern void InitEggModeAnimation(void);
|
||||
extern void InitRubyEggModeAnimation(void);
|
||||
//extern ? UpdateEggModeAnimation();
|
||||
//extern ? UpdateEggHatchDisplay();
|
||||
//extern ? UpdateHatchCave();
|
||||
extern void CleanupEggModeState(void);
|
||||
//extern ? InitEggMode();
|
||||
//extern ? UpdateEggMode();
|
||||
|
|
@ -534,22 +534,22 @@ extern void DrawSpoinkSprite();
|
|||
extern void RunEvolutionCutscene(void);
|
||||
//extern ? sub_2DE54();
|
||||
extern void RunTravelEventCutscene(void);
|
||||
extern void DecrementFieldTimer();
|
||||
extern void DecrementPelipperTimer();
|
||||
extern void UpdatePelipperPondEntity();
|
||||
extern void AnimateWailmerEntity();
|
||||
extern void UpdateZigzagoonEntity();
|
||||
extern void DrawZigzagoonAndShockWall();
|
||||
extern void DrawZigzagoonAndRouletteStopPrompt();
|
||||
extern void UpdateSapphireBumperLogic();
|
||||
extern void DrawSapphireBumperSprites();
|
||||
extern void CalculateRubyBumperBounce();
|
||||
extern void HandleRubyBumperHit();
|
||||
extern void InitSapphireEggCaveState();
|
||||
extern void UpdateSapphireEggCaveAnimation();
|
||||
extern void InitSapphireEggHatchState();
|
||||
extern void UpdateSapphireEggHatchAnimation();
|
||||
extern void UpdateSapphireSeedotCollection();
|
||||
extern void DrawSapphireSeedotAndBasketSprites();
|
||||
extern void UpdateSapphireShopSignAnimation();
|
||||
extern void DrawSapphireShopSignSprite(void);
|
||||
extern void UpdateSapphireHoleLetterSystem();
|
||||
extern void UpdateSapphireEggMachine();
|
||||
extern void DrawBoardEdgeBanner(void);
|
||||
extern void RestoreBoardObjPalettes(s16);
|
||||
extern void RegisterCaptureOrEvolution(s16);
|
||||
|
|
@ -620,7 +620,7 @@ extern void SphealBoard_PelipperDeliversBall(void);
|
|||
extern void UpdateSealeoKnockdownPhysics(void);
|
||||
extern void AnimateSphealBackground(void);
|
||||
extern void UpdateSphealResultsScreen(void);
|
||||
extern void loadIntroduction(void);
|
||||
extern void loadFieldBoardGraphics(void);
|
||||
extern void SetBoardCollisionConfig(s16);
|
||||
extern void UpdateScrollingBackgroundTiles(void);
|
||||
//extern ? AllBoardProcess_1A_47100();
|
||||
|
|
@ -654,23 +654,23 @@ extern void ProcessMainBoardBallDrainAndLaunch(void);
|
|||
extern void ProcessBonusBoardBallDrain(void);
|
||||
extern void ResetBoardStateOnDeath(void);
|
||||
extern void UpdateRubyBoardAnimations(void);
|
||||
extern void AnimateRubySlingshotTimer(void);
|
||||
extern void AnimateRubySlingshotHit(void);
|
||||
extern void LoadShopItemGraphics(s16);
|
||||
extern void DrawRubyProgressDigits(void);
|
||||
extern void AnimateRubyTrapIndicator(void);
|
||||
extern void AnimateRubyCatchLightBlink(void);
|
||||
extern void AnimateRubyHoleIndicators(void);
|
||||
extern void DrawRubyModeTimerDisplay(void);
|
||||
extern void AnimateRubyCatchArrow(void);
|
||||
extern void AnimateRubyEvoArrow(void);
|
||||
extern void AnimateRubyCatchArrowPalette(void);
|
||||
extern void AnimateRubyEvoArrowPalette(void);
|
||||
extern void AnimateRubyRouletteSlot(void);
|
||||
extern void AnimateRubyCatchProgressArrow(void);
|
||||
extern void AnimateRubyBallPowerUpSequence(void);
|
||||
extern void DrawRubyBallPowerUpLights(void);
|
||||
extern void UpdateCoinRewardTimer(void);
|
||||
extern void DrawCoinRewardMeter(void);
|
||||
extern void DrawEvoArrowProgress(void);
|
||||
extern void DrawCatchArrowProgress(void);
|
||||
extern void DrawRubyCoinRewardMeter(void);
|
||||
extern void DrawRubyEvoArrowProgress(void);
|
||||
extern void DrawRubyCatchArrowProgress(void);
|
||||
extern void UpdateSapphireBoardAnimations(void);
|
||||
extern void DrawSapphireProgressDigits(void);
|
||||
extern void AnimateSapphireSlingshotHit(void);
|
||||
|
|
@ -679,16 +679,16 @@ extern void AnimateRotatingBackground(void);
|
|||
extern void AnimateSapphireCatchLightBlink(void);
|
||||
extern void AnimateSapphireHoleIndicators(void);
|
||||
extern void DrawSapphireModeTimerDisplay(void);
|
||||
extern void DrawCoinRewardMeterAlt(void);
|
||||
extern void DrawSapphireCoinRewardMeter(void);
|
||||
extern void AnimateSapphireCatchArrowPalette(void);
|
||||
extern void AnimateSapphireEvoArrowPalette(void);
|
||||
extern void DrawEvoArrowBonusField(void);
|
||||
extern void DrawCatchArrowBonusField(void);
|
||||
extern void AnimateCatchArrowPaletteFlash(void);
|
||||
extern void DrawSapphireEvoArrowProgress(void);
|
||||
extern void DrawSapphireCatchArrowProgress(void);
|
||||
extern void AnimateSapphireCatchArrowPaletteFlash(void);
|
||||
extern void AnimateSapphireRouletteSlot(void);
|
||||
extern void DrawBallPowerUpLights(void);
|
||||
extern void AnimateBonusModeIndicators(void);
|
||||
extern void AnimateBumperHitCounter(void);
|
||||
extern void DrawSapphireBallPowerUpLights(void);
|
||||
extern void AnimateHatchMachineSpinner(void);
|
||||
extern void AnimatePelliperBumper(void);
|
||||
extern void RubyBoardProcess_0A_50848(void);
|
||||
//extern ? RubyBoardProcess_0B_50918();
|
||||
extern void SapphireBoardProcess_0A_50AD4(void);
|
||||
|
|
|
|||
15
include/functions_main_boards.h
Normal file
15
include/functions_main_boards.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef GUARD_FUNCTIONS_MAIN_BOARD_H
|
||||
#define GUARD_FUNCTIONS_MAIN_BOARD_H
|
||||
|
||||
extern void SelectRubyShopDoorState(void);
|
||||
extern void AnimateRubyShopDoor(void);
|
||||
extern void UpdateEggModeAnimation(void);
|
||||
extern void UpdateHatchCave(void);
|
||||
|
||||
extern void DrawPikachuSpinner(void);
|
||||
|
||||
extern void UpdateEvolutionShopSprite(void);
|
||||
extern void InitRubyEggModeAnimation(void);
|
||||
extern void LoadShopItemGraphics(s16);
|
||||
|
||||
#endif //GUARD_FUNCTIONS_MAIN_BOARD_H
|
||||
23
include/functions_ruby.h
Normal file
23
include/functions_ruby.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef GUARD_FUNCTIONS_RUBY_H
|
||||
#define GUARD_FUNCTIONS_RUBY_H
|
||||
|
||||
#include "functions_main_boards.h"
|
||||
|
||||
extern void UpdateNuzleafEntity(void);
|
||||
extern void DrawRubyNuzleafPlatformSprite(void);
|
||||
extern void RubyPondTriBumperHandleHitAndDraw(void);
|
||||
extern void DrawWhiscash(void);
|
||||
extern void AnimateSharpedoEntity(void);
|
||||
extern void UpdateChikoritaAttackAnimation(void);
|
||||
extern void AnimateChikoritaSprite(void);
|
||||
extern void UpdateGulpinBossState(void);
|
||||
|
||||
extern void UpdateRubyRampPrizeGate(void);
|
||||
extern void DrawRubySideBumperSprites(void);
|
||||
extern void UpdateRubySideBumperAnimation(void);
|
||||
extern void UpdateRubyBoardEntityRendering(void);
|
||||
extern void UpdateRubyBoardEntityLogic(void);
|
||||
extern void HandleRubyFlipperButtonInput(void);
|
||||
extern void RubyPond_EntityLogic(void);
|
||||
|
||||
#endif //GUARD_FUNCTIONS_RUBY_H
|
||||
|
|
@ -248,11 +248,11 @@ struct PinballGame
|
|||
/*0x12E*/ s16 totalWeight; // Added weight of all possible mons in area
|
||||
/*0x130*/ s16 speciesWeights[25]; // Weight of each species
|
||||
/*0x162*/ s8 forcePondToWhiscash;
|
||||
/*0x163*/ s8 sapphirePondFlag;
|
||||
/*0x164*/ s8 pondAnimFrameIndex;
|
||||
/*0x165*/ s8 sapphireEntityCollisionFlag;
|
||||
/*0x166*/ u16 sapphireSpriteTimer;
|
||||
/*0x168*/ u16 pondAnimSubTimer;
|
||||
/*0x163*/ s8 spoinkEntityState;
|
||||
/*0x164*/ s8 spoinkAnimFrameIx;
|
||||
/*0x165*/ s8 ballTouchingSpoink;
|
||||
/*0x166*/ u16 spoinkPullbackYDistance;
|
||||
/*0x168*/ u16 spoinkAnimFrameTimer;
|
||||
/*0x16A*/ s16 bannerSlideX;
|
||||
/*0x16C*/ s8 rubyPondState;
|
||||
/*0x16D*/ u8 filler16D[0x1];
|
||||
|
|
@ -408,7 +408,7 @@ struct PinballGame
|
|||
/*0x2CA*/ s16 eggDeliveryY;
|
||||
/*0x2CC*/ s16 eggDeliveryVelX;
|
||||
/*0x2CE*/ s16 eggDeliveryVelY;
|
||||
/*0x2D0*/ s8 eggDeliveryState;
|
||||
/*0x2D0*/ s8 rubyEggDeliveryState;
|
||||
/*0x2D1*/ u8 filler2D1[3];
|
||||
/*0x2D4*/ u16 cyndaquilCaveSpriteX;
|
||||
/*0x2D6*/ u16 cyndaquilCaveSpriteY;
|
||||
|
|
@ -470,11 +470,11 @@ struct PinballGame
|
|||
/*0x335*/ u8 filler335[0x1];
|
||||
/*0x336*/ u16 seedotAnimTimer[3];
|
||||
/*0x33C*/ u16 seedotYOffset[3];
|
||||
/*0x342*/ s8 sapphireDiverterActive;
|
||||
/*0x343*/ s8 holeCaptureReady;
|
||||
/*0x344*/ s8 holeLetterNewHit;
|
||||
/*0x345*/ s8 holeLetterCount;
|
||||
/*0x346*/ s8 holeLetterSystemState;
|
||||
/*0x342*/ s8 hatchMachineActive; // Turns off while launching, Reenabled when ball touches ramp
|
||||
/*0x343*/ s8 sapphirerubyEggDeliveryState;
|
||||
/*0x344*/ s8 hatchMachineNewHit;
|
||||
/*0x345*/ s8 sapphireHatchMachineFrameIx;
|
||||
/*0x346*/ s8 sapphireHatchMachineState; // 0-6
|
||||
/*0x347*/ u8 filler347[0x1];
|
||||
/*0x348*/ u16 holeAnimFrameCounter;
|
||||
/*0x34A*/ s8 targetBumperHitCounter;
|
||||
|
|
|
|||
|
|
@ -30,55 +30,74 @@ SECTIONS
|
|||
{
|
||||
src/crt0.o(.text);
|
||||
src/util.o(.text);
|
||||
src/rom_850.o(.text);
|
||||
src/main.o(.text);
|
||||
src/gbplayer.o(.text);
|
||||
src/link.o(.text);
|
||||
src/rom_2414.o(.text);
|
||||
src/bonus_field_select.o(.text);
|
||||
src/ereader.o(.text);
|
||||
src/pokedex.o(.text);
|
||||
src/field_select.o(.text);
|
||||
src/intro.o(.text);
|
||||
src/high_scores.o(.text);
|
||||
src/rom_1068C.o(.text);
|
||||
src/display.o(.text);
|
||||
src/titlescreen.o(.text);
|
||||
src/board_process5.o(.text);
|
||||
src/board_process7.o(.text);
|
||||
src/board_process6.o(.text);
|
||||
src/collision_checks.o(.text);
|
||||
src/board_process6_collision.o(.text);
|
||||
src/collision_ruby.o(.text);
|
||||
src/collision_sapphire.o(.text);
|
||||
src/collision_dusclops.o(.text);
|
||||
src/collision_kecleon.o(.text);
|
||||
src/collision_kyogre.o(.text);
|
||||
src/collision_groudon.o(.text);
|
||||
src/collision_rayquaza.o(.text);
|
||||
src/collision_spheal.o(.text);
|
||||
src/game_idle.o(.text);
|
||||
src/board_process4.o(.text);
|
||||
src/board_process3_ruby.o(.text);
|
||||
src/rom_1A0F4.o(.text);
|
||||
src/rom_1A98C.o(.text);
|
||||
src/rom_201B8.o(.text);
|
||||
src/board_state_transitions_and_idle.o(.text);
|
||||
src/board_process3_ruby_entities.o(.text);
|
||||
src/banners.o(.text);
|
||||
src/ruby_catch_holes.o(.text);
|
||||
src/main_board_catch_holes.o(.text);
|
||||
src/main_portrait_display.o(.text);
|
||||
src/board_process3_ruby_entities_2.o(.text);
|
||||
src/board_process_3_charge_spinner.o(.text);
|
||||
src/ruby_trigger_targets.o(.text);
|
||||
src/pichu_entity.o(.text);
|
||||
src/rom_27E08.o(.text);
|
||||
src/rom_27F94.o(.text);
|
||||
src/rom_2C538.o(.text);
|
||||
src/rom_2E67C.o(.text);
|
||||
src/rom_30480.o(.text);
|
||||
src/rom_31BE8.o(.text);
|
||||
src/rom_31CF8.o(.text);
|
||||
src/catch_tile_logic.o(.text);
|
||||
src/travel_mode.o(.text);
|
||||
src/evolution_mode.o(.text);
|
||||
src/catch_and_hatch_modes.o(.text);
|
||||
src/catch_tile_particles.o(.text);
|
||||
src/center_capture_hole.o(.text);
|
||||
src/ruby_ramp.o(.text);
|
||||
src/launcher_and_cutscenes.o(.text);
|
||||
src/sapphire_pond_and_zigzagoon.o(.text);
|
||||
src/board_bumpers.o(.text);
|
||||
src/sapphire_seedot_egg_shop.o(.text);
|
||||
src/board_edge.o(.text);
|
||||
src/catch_hatch_picker.o(.text);
|
||||
src/board_process3_sapphire.o(.text);
|
||||
src/board_process3_dusclops.o(.text);
|
||||
src/rom_356A0.o(.text);
|
||||
src/bonus_complete_scoring_transition.o(.text);
|
||||
src/board_process3_kecleon.o(.text);
|
||||
src/board_process3_kyogre.o(.text);
|
||||
src/board_process3_groudon.o(.text);
|
||||
src/board_process3_rayquaza.o(.text);
|
||||
src/board_process3_spheal.o(.text);
|
||||
src/rom_467F4.o(.text);
|
||||
src/board_setup.o(.text);
|
||||
src/board_process1.o(.text);
|
||||
src/debug_menu.o(.text);
|
||||
src/mode_change_and_debug_menu.o(.text);
|
||||
src/pause_game.o(.text);
|
||||
src/pinball_game_main.o(.text);
|
||||
src/save_and_restore_game.o(.text);
|
||||
src/board_process8.o(.text);
|
||||
src/board_process2.o(.text);
|
||||
src/rom_4F258.o(.text);
|
||||
src/rom_50AD4.o(.text);
|
||||
src/board_process0.o(.text);
|
||||
src/ruby_board_indicators.o(.text);
|
||||
src/sapphire_board_indicators.o(.text);
|
||||
src/board_process0_sprite_init.o(.text);
|
||||
src/options.o(.text);
|
||||
src/pokemon_cry.o(.text);
|
||||
src/save.o(.text);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
extern void RenderBannerSlideAnimation(void);
|
||||
|
||||
|
||||
void ProcessBannerCameraTransition(void)
|
||||
{
|
||||
if ((gMain.modeChangeFlags & MODE_CHANGE_BANNER) != 0)
|
||||
415
src/board_bumpers.c
Normal file
415
src/board_bumpers.c
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/main_board.h"
|
||||
|
||||
extern const u8 gSapphireBoardShopShockWall_Gfx[][0x80];
|
||||
|
||||
extern const s16 gSapphireBumperAnimFrames[][2];
|
||||
extern const s16 gBumperMosaicValues[];
|
||||
extern const u8 gSapphireBumperLeft_Gfx[][0x300];
|
||||
extern const u8 gSapphireBumperLeftHit_Gfx[][0x200];
|
||||
extern const u8 gSapphireBumperRight_Gfx[][0x300];
|
||||
extern const u8 gSapphireBumperRightHit_Gfx[][0x200];
|
||||
extern const u8 gPondBumper_Gfx[][0x200];
|
||||
|
||||
void UpdateSapphireBumperLogic(void)
|
||||
{
|
||||
s16 i;
|
||||
u32 mosaicVal;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
switch (gCurrentPinballGame->sapphireBumperState[i])
|
||||
{
|
||||
case 0:
|
||||
if (gSapphireBumperAnimFrames[gCurrentPinballGame->sapphireBumperAnimKeyframe[i]][1] > gCurrentPinballGame->sapphireBumperAnimSubTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i]++;
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
if (gCurrentPinballGame->sapphireBumperAnimKeyframe[i] > 3)
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->sapphireBumperHitFxTimer[i] < 152)
|
||||
gCurrentPinballGame->sapphireBumperHitFxTimer[i]++;
|
||||
else
|
||||
gCurrentPinballGame->sapphireBumperHitFxTimer[i] = 0;
|
||||
break;
|
||||
case 1:
|
||||
if (gSapphireBumperAnimFrames[gCurrentPinballGame->sapphireBumperAnimKeyframe[i]][1] > gCurrentPinballGame->sapphireBumperAnimSubTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i]++;
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
if (gCurrentPinballGame->sapphireBumperAnimKeyframe[i] == 5)
|
||||
{
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE6);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->sapphireBumperAnimKeyframe[i] == 6)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperLitCountdown)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperLitCountdown == 1)
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 7;
|
||||
gCurrentPinballGame->sapphireBumperState[i] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->sapphireBumperHitFxTimer[i] = 20;
|
||||
break;
|
||||
case 2:
|
||||
if (gSapphireBumperAnimFrames[gCurrentPinballGame->sapphireBumperAnimKeyframe[i]][1] > gCurrentPinballGame->sapphireBumperAnimSubTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i]++;
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
if (gCurrentPinballGame->sapphireBumperAnimKeyframe[i] == 8)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE7);
|
||||
|
||||
if (gCurrentPinballGame->sapphireBumperAnimKeyframe[i] > 8)
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 0;
|
||||
gCurrentPinballGame->sapphireBumperState[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->sapphireBumperHitFxTimer[i] = 20;
|
||||
break;
|
||||
case 3:
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 9;
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
gCurrentPinballGame->sapphireBumperState[i] = 4;
|
||||
gCurrentPinballGame->sapphireBumperHitFxTimer[i] = 20;
|
||||
break;
|
||||
case 4:
|
||||
if (gSapphireBumperAnimFrames[gCurrentPinballGame->sapphireBumperAnimKeyframe[i]][1] > gCurrentPinballGame->sapphireBumperAnimSubTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i]++;
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
if (gCurrentPinballGame->sapphireBumperAnimKeyframe[i] > 17)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState == 6)
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 0;
|
||||
gCurrentPinballGame->sapphireBumperState[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->sapphireBumperHitFxTimer[i] = 20;
|
||||
break;
|
||||
case 5:
|
||||
if (gSapphireBumperAnimFrames[gCurrentPinballGame->sapphireBumperAnimKeyframe[i]][1] > gCurrentPinballGame->sapphireBumperAnimSubTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i]++;
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
if (gCurrentPinballGame->sapphireBumperAnimKeyframe[i] > 17)
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperState[i] = 0;
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->sapphireBumperHitFxTimer[i] = 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ballCatchState != TRAP_EVO_SHOP_HOLE)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperLitCountdown)
|
||||
gCurrentPinballGame->sapphireBumperLitCountdown--;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ballLaunchTimer)
|
||||
{
|
||||
gCurrentPinballGame->ballLaunchTimer--;
|
||||
if (gCurrentPinballGame->ballLaunchTimer == 0)
|
||||
gCurrentPinballGame->secondaryBall = gCurrentPinballGame->ballStates;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->shopBumperHitTimer)
|
||||
{
|
||||
if (gCurrentPinballGame->shopBumperHitTimer == 17)
|
||||
{
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE8);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10;
|
||||
PlayRumble(13);
|
||||
}
|
||||
|
||||
mosaicVal = gBumperMosaicValues[gCurrentPinballGame->shopBumperHitTimer / 3];
|
||||
REG_MOSAIC = (mosaicVal << 12) | (mosaicVal << 8) | (mosaicVal << 4) | (mosaicVal << 0);
|
||||
gCurrentPinballGame->shopBumperHitTimer--;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->boardState > 2)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState != 6)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperState[i])
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperState[i] = 0;
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[i] = 0;
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->evoArrowProgress > 2)
|
||||
{
|
||||
if (gCurrentPinballGame->evolvablePartySize > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperState[0] < 3)
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperState[0] = 3;
|
||||
gCurrentPinballGame->sapphireBumperState[1] = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperState[0] > 2)
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperState[0] = 0;
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[0] = 0;
|
||||
gCurrentPinballGame->sapphireBumperState[1] = 0;
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSapphireBumperSprites(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
group = &gMain.spriteGroups[61];
|
||||
if (!group->available)
|
||||
return;
|
||||
|
||||
group->baseX = 68 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 144 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gSapphireBumperAnimFrames[gCurrentPinballGame->sapphireBumperAnimKeyframe[0]][0];
|
||||
DmaCopy16(3, &gSapphireBumperLeft_Gfx[index], (void *)0x06012DA0, 0x280);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = &gMain.spriteGroups[58];
|
||||
group->baseX = 68 - gCurrentPinballGame->cameraXOffset;
|
||||
if (gCurrentPinballGame->sapphireBumperHitFxTimer[0] < 14)
|
||||
{
|
||||
group->baseY = 144 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gCurrentPinballGame->sapphireBumperHitFxTimer[0] / 2;
|
||||
DmaCopy16(3, &gSapphireBumperLeftHit_Gfx[index], (void *)0x06014720, 0x180);
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseY = 200;
|
||||
}
|
||||
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
|
||||
group = &gMain.spriteGroups[62];
|
||||
group->baseX = 36 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 163 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gSapphireBumperAnimFrames[gCurrentPinballGame->sapphireBumperAnimKeyframe[1]][0];
|
||||
DmaCopy16(3, &gSapphireBumperRight_Gfx[index], (void *)0x060130A0, 0x280);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = &gMain.spriteGroups[59];
|
||||
group->baseX = 36 - gCurrentPinballGame->cameraXOffset;
|
||||
if (gCurrentPinballGame->sapphireBumperHitFxTimer[1] < 14)
|
||||
{
|
||||
group->baseY = 163 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gCurrentPinballGame->sapphireBumperHitFxTimer[1] / 2;
|
||||
DmaCopy16(3, &gSapphireBumperRightHit_Gfx[index], (void *)0x06014920, 0x180);
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseY = 200;
|
||||
}
|
||||
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
|
||||
group = &gMain.spriteGroups[76];
|
||||
group->baseX = 61 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 186 - gCurrentPinballGame->cameraYOffset;
|
||||
if (gCurrentPinballGame->eggHatchShockWallOverride)
|
||||
{
|
||||
gCurrentPinballGame->shopShockWallAnimState = 3;
|
||||
}
|
||||
else if (gCurrentPinballGame->sapphireBumperState[0])
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperState[1])
|
||||
gCurrentPinballGame->shopShockWallAnimState = 3;
|
||||
else
|
||||
gCurrentPinballGame->shopShockWallAnimState = 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->sapphireBumperState[1])
|
||||
{
|
||||
gCurrentPinballGame->shopShockWallAnimState = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->shopShockWallAnimState = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->shopShockWallAnimState < 3)
|
||||
index = gCurrentPinballGame->shopShockWallAnimState * 3 + (gCurrentPinballGame->globalAnimFrameCounter % 30) / 10;
|
||||
else
|
||||
index = 9;
|
||||
|
||||
DmaCopy16(3, &gSapphireBoardShopShockWall_Gfx[index], (void *)0x060146A0, 0x80);
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
void CalculateRubyBumperBounce(void)
|
||||
{
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].x = 920;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].y = (133 - (gCurrentPinballGame->globalAnimFrameCounter % 60) / 30) * 10;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].x = 1260;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].y = (131 - ((gCurrentPinballGame->globalAnimFrameCounter + 10) % 60) / 30) * 10;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].x = 1080;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].y = (161 - ((gCurrentPinballGame->globalAnimFrameCounter + 20) % 60) / 30) * 10;
|
||||
}
|
||||
|
||||
void HandleRubyBumperHit(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
group = &gMain.spriteGroups[63];
|
||||
if (gCurrentPinballGame->bumperHitCountdown > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->bumperHitCountdown == 2)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 500;
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_HIT);
|
||||
PlayRumble(7);
|
||||
if (gCurrentPinballGame->boardState == 4 && gCurrentPinballGame->boardSubState == 5)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchTilesBumperAcknowledged < 6)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchTilesBumperAcknowledged == 0)
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 1;
|
||||
else if (gCurrentPinballGame->hatchTilesBumperAcknowledged == 1)
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 3;
|
||||
else
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 6;
|
||||
|
||||
if (gCurrentPinballGame->hatchTilesBumperAcknowledged == 6)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchTilesBoardAcknowledged == 0)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 50;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 600;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0xEC;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 4;
|
||||
gCurrentPinballGame->bannerGfxIndex = 7;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 80;
|
||||
gCurrentPinballGame->bannerSlidePosition = -2500;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[7], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[7], (void *)0x050003C0, 0x20);
|
||||
gMain.blendControl = 0xCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->pondEntitySpriteFlag++;
|
||||
gCurrentPinballGame->bumperHitsSinceReset++;
|
||||
if (gCurrentPinballGame->bumperHitsSinceReset == 100)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 50000;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->bumperHitCountdown--;
|
||||
}
|
||||
|
||||
if (group->available)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->pondBumperStates[i] > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->pondBumperStates[i] < 0)
|
||||
gCurrentPinballGame->pondBumperStates[i] += 3;
|
||||
|
||||
index = gCurrentPinballGame->pondBumperStates[i] / 4 + 2;
|
||||
gCurrentPinballGame->pondBumperStates[i]--;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = ((gCurrentPinballGame->globalAnimFrameCounter + (i * 10)) % 30) / 15;
|
||||
}
|
||||
|
||||
DmaCopy16(3, &gPondBumper_Gfx[index], (void *)0x060133A0 + i * 0x200, 0x200);
|
||||
|
||||
group->baseX = gCurrentPinballGame->rubyBumperLogicPosition[i].x / 10 - gCurrentPinballGame->cameraXOffset - 8;
|
||||
group->baseY = gCurrentPinballGame->rubyBumperLogicPosition[i].y / 10 - gCurrentPinballGame->cameraYOffset - 10;
|
||||
gCurrentPinballGame->rubyBumperCollisionPosition[i].x = (-(gCurrentPinballGame->rubyBumperLogicPosition[i].x / 10) + 8) * 2;
|
||||
gCurrentPinballGame->rubyBumperCollisionPosition[i].y = (-(gCurrentPinballGame->rubyBumperLogicPosition[i].y / 10) + 3) * 2;
|
||||
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
76
src/board_edge.c
Normal file
76
src/board_edge.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "gba/gba.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/fields.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern const u8 gRubyStageCyndaquil_Gfx[][0x280];
|
||||
|
||||
void DrawBoardEdgeBanner(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
group = &gMain.spriteGroups[81];
|
||||
else
|
||||
group = &gMain.spriteGroups[85];
|
||||
|
||||
if (group->available)
|
||||
{
|
||||
if (gCurrentPinballGame->cameraBaseX < 8)
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->cameraXOffset;
|
||||
group->baseX = -8 - group->baseX;
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->cameraXOffset;
|
||||
group->baseX = 256 - group->baseX;
|
||||
}
|
||||
|
||||
group->baseY = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
struct OamDataSimple *oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY + i * 0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed when saving or loading from a main field
|
||||
* arg0
|
||||
* 0 when saving and loading normally
|
||||
* 2 when loading into the evo or mart menu
|
||||
*/
|
||||
void RestoreBoardObjPalettes(s16 arg0)
|
||||
{
|
||||
if (gCurrentPinballGame->paletteSwapActive == 1)
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0], (void*)OBJ_PLTT, 0x20);
|
||||
}
|
||||
|
||||
if (gMain.selectedField == FIELD_SAPPHIRE)
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0] + 0x40, (void*)OBJ_PLTT + 0x40, 0xC0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0] + 0x40, (void*)OBJ_PLTT + 0x40, 0xE0);
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0] + 0x140, (void *)OBJ_PLTT + 0x140, 0x20);
|
||||
|
||||
// related to Y position of camera on the field
|
||||
if (gCurrentPinballGame->cameraYViewport < 170)
|
||||
{
|
||||
DmaCopy16(3, gFieldPaletteVariants[gMain.selectedField][arg0 * 2], (void *)OBJ_PLTT + 0x160, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gFieldPaletteVariants[gMain.selectedField][arg0 * 2 + 1], (void *)OBJ_PLTT + 0x160, 0x20);
|
||||
}
|
||||
}
|
||||
|
|
@ -421,12 +421,12 @@ void ProcessMainBoardBallDrainAndLaunch(void)
|
|||
if (gCurrentPinballGame->boardState && gCurrentPinballGame->newButtonActions[1] && gCurrentPinballGame->ballInLaunchChute)
|
||||
{
|
||||
gCurrentPinballGame->launcherCharging = 1;
|
||||
gCurrentPinballGame->sapphirePondFlag = 1;
|
||||
gCurrentPinballGame->spoinkEntityState = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->launcherCharging && gCurrentPinballGame->releasedButtonActions[1])
|
||||
{
|
||||
gCurrentPinballGame->sapphirePondFlag = 3;
|
||||
gCurrentPinballGame->spoinkEntityState = 3;
|
||||
if (gCurrentPinballGame->ballInLaunchChute)
|
||||
{
|
||||
PlayRumble(7);
|
||||
|
|
|
|||
|
|
@ -1,51 +1,24 @@
|
|||
#include "global.h"
|
||||
#include "functions.h"
|
||||
#include "functions_ruby.h"
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/ruby_states.h"
|
||||
|
||||
extern const void (*gBoardStateInitFuncs[])(void);
|
||||
extern const void (*gBoardStateUpdateFuncs[])(void);
|
||||
|
||||
extern void HandleBoardStateTransitionTeardown(void);
|
||||
extern void UpdateRubyBoardEntityRendering(void);
|
||||
extern void UpdateRubyBoardEntityLogic(void);
|
||||
extern void HandleRubyFlipperButtonInput(void);
|
||||
extern void UpdateNuzleafEntity(void);
|
||||
extern void SelectShopDoorState(void);
|
||||
extern void AnimateShopDoor(void);
|
||||
extern void DrawWhiscash(void);
|
||||
extern void RubyPond_EntityLogic(void);
|
||||
extern void RubyPondTriBumperHandleHitAndDraw(void);
|
||||
extern void AnimateSharpedoEntity(void);
|
||||
extern void DrawPikachuSpinner(void);
|
||||
extern void UpdateChikoritaAttackAnimation(void);
|
||||
extern void AnimateChikoritaSprite(void);
|
||||
extern void UpdateGulpinBossState(void);
|
||||
extern void UpdateSideBumperAnimation(void);
|
||||
extern void DrawSideBumperSprites(void);
|
||||
extern void UpdateEvolutionShopSprite(void);
|
||||
extern void InitEggModeAnimation(void);
|
||||
extern void UpdateEggModeAnimation(void);
|
||||
extern void UpdateEggHatchDisplay(void);
|
||||
extern void UpdateRubyRampPrizeGate(void);
|
||||
extern void DrawRubyNuzleafPlatformSprite(void);
|
||||
extern void LoadShopItemGraphics(s16);
|
||||
|
||||
void RubyBoardProcess_3A_19A20(void)
|
||||
{
|
||||
gCurrentPinballGame->catchModeArrows = 2;
|
||||
UpdateNuzleafEntity();
|
||||
LoadShopItemGraphics(0);
|
||||
AnimateShopDoor();
|
||||
InitEggModeAnimation();
|
||||
AnimateRubyShopDoor();
|
||||
InitRubyEggModeAnimation();
|
||||
UpdateEggModeAnimation();
|
||||
|
||||
gCurrentPinballGame->cyndaquilCaveSpriteX = 73;
|
||||
gCurrentPinballGame->cyndaquilCaveSpriteY = 154;
|
||||
gCurrentPinballGame->eggCaveState = 0;
|
||||
UpdateEggHatchDisplay();
|
||||
UpdateHatchCave();
|
||||
RubyPond_EntityLogic();
|
||||
|
||||
gCurrentPinballGame->pondBumperStates[0] = 10;
|
||||
|
|
@ -91,271 +64,3 @@ void RubyBoardProcess_3B_19B10(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RequestBoardStateTransition(u8 arg0)
|
||||
{
|
||||
gCurrentPinballGame->boardTransitionPhase = 2;
|
||||
gCurrentPinballGame->nextBoardState = arg0;
|
||||
if (gCurrentPinballGame->boardState == 2)
|
||||
gMain.fieldSpriteGroups[13]->available = 0;
|
||||
}
|
||||
|
||||
void BoardStateDispatcher(void)
|
||||
{
|
||||
switch (gCurrentPinballGame->boardTransitionPhase)
|
||||
{
|
||||
case 0:
|
||||
gBoardStateInitFuncs[gCurrentPinballGame->boardState]();
|
||||
gCurrentPinballGame->boardTransitionPhase++;
|
||||
break;
|
||||
case 1:
|
||||
gBoardStateUpdateFuncs[gCurrentPinballGame->boardState]();
|
||||
break;
|
||||
case 2:
|
||||
HandleBoardStateTransitionTeardown();
|
||||
gCurrentPinballGame->prevBoardState = gCurrentPinballGame->boardState;
|
||||
gCurrentPinballGame->boardState = gCurrentPinballGame->nextBoardState;
|
||||
gCurrentPinballGame->boardTransitionPhase = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitFieldIdle(void)
|
||||
{
|
||||
s16 num1;
|
||||
u8 num2;
|
||||
|
||||
if (gCurrentPinballGame->prevBoardState > 0)
|
||||
{
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
num1 = gCurrentPinballGame->numCompletedBonusStages / 5;
|
||||
if ((num1 & 1) == 0)
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_RUBY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_RUBY2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num1 = gCurrentPinballGame->numCompletedBonusStages / 5;
|
||||
if ((num1 & 1) == 0)
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_SAPPHIRE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_SAPPHIRE2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
num2 = gCurrentPinballGame->prevBoardState - 1;
|
||||
if (num2 > 1)
|
||||
{
|
||||
gCurrentPinballGame->evoArrowProgress = gCurrentPinballGame->arrowProgressPreserved;
|
||||
gCurrentPinballGame->catchArrowProgress = gCurrentPinballGame->catchModeArrows;
|
||||
gCurrentPinballGame->arrowProgressPreserved = 0;
|
||||
gCurrentPinballGame->catchModeArrows = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateFieldIdle(void)
|
||||
{
|
||||
if (gCurrentPinballGame->allHolesLit != 0)
|
||||
{
|
||||
if (gCurrentPinballGame->allHolesLitDelayTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->allHolesLitDelayTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestBoardStateTransition(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleBoardStateTransitionTeardown(void)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState == 2 && gCurrentPinballGame->nextBoardState > 2)
|
||||
ResetCatchState(0);
|
||||
|
||||
if (gCurrentPinballGame->boardState > 2)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->nextBoardState == 3)
|
||||
{
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->nextBoardState == 4)
|
||||
{
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->nextBoardState == 6)
|
||||
{
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->arrowProgressPreserved = 0;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->nextBoardState > 3)
|
||||
{
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRubyBoardEntityRendering(void)
|
||||
{
|
||||
int randNum;
|
||||
|
||||
ProcessBannerCameraTransition();
|
||||
SelectShopDoorState();
|
||||
if (gCurrentPinballGame->rampPrizeRespawnTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->rampPrizeRespawnTimer--;
|
||||
if (gCurrentPinballGame->rampPrizeRespawnTimer == 0)
|
||||
{
|
||||
randNum = Random();
|
||||
gCurrentPinballGame->rampPrizeType = ((randNum + gMain.systemFrameCount) % 100) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->cameraYViewport < 110)
|
||||
{
|
||||
UpdateNuzleafEntity();
|
||||
AnimateShopDoor();
|
||||
DrawRubyNuzleafPlatformSprite();
|
||||
}
|
||||
AnimateOneUpSprite();
|
||||
if (gCurrentPinballGame->cameraYViewport < 168)
|
||||
{
|
||||
UpdateEggModeAnimation();
|
||||
}
|
||||
if (gCurrentPinballGame->cameraYViewport < 220)
|
||||
{
|
||||
UpdateEggHatchDisplay();
|
||||
if (gCurrentPinballGame->shouldProcessWhiscash)
|
||||
{
|
||||
DrawWhiscash();
|
||||
}
|
||||
else
|
||||
{
|
||||
RubyPondTriBumperHandleHitAndDraw();
|
||||
}
|
||||
AnimateSharpedoEntity();
|
||||
DrawPikachuSpinner();
|
||||
}
|
||||
UpdateChikoritaAttackAnimation();
|
||||
if (gCurrentPinballGame->cameraYViewport > 63)
|
||||
{
|
||||
AnimateChikoritaSprite();
|
||||
UpdateGulpinBossState();
|
||||
}
|
||||
if (gCurrentPinballGame->cameraYViewport > 115)
|
||||
{
|
||||
UpdateRubyRampPrizeGate();
|
||||
}
|
||||
if (gCurrentPinballGame->cameraYViewport > 130)
|
||||
{
|
||||
DrawSideBumperSprites();
|
||||
}
|
||||
UpdateSpoinkAnimation();
|
||||
if (gCurrentPinballGame->cameraYViewport > 168)
|
||||
{
|
||||
DrawSpoinkSprite();
|
||||
}
|
||||
UpdateKickbackLogic();
|
||||
ProcessChargeIndicator();
|
||||
UpdateRubyBoardAnimations();
|
||||
UpdatePortraitSpritePositions();
|
||||
UpdateEvolutionShopSprite();
|
||||
DrawBoardEdgeBanner();
|
||||
|
||||
if (gCurrentPinballGame->coinRewardAmount != 0)
|
||||
{
|
||||
AnimateCoinReward();
|
||||
}
|
||||
BonusStage_HandleModeChangeFlags();
|
||||
|
||||
if (gCurrentPinballGame->ballLaunchTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->ballLaunchTimer--;
|
||||
if (gCurrentPinballGame->ballLaunchTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->secondaryBall = gCurrentPinballGame->ballStates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRubyBoardEntityLogic(void)
|
||||
{
|
||||
RubyPond_EntityLogic();
|
||||
UpdateRubyCatchModeAnimation();
|
||||
UpdatePikachuChargeCounter();
|
||||
UpdateSideBumperAnimation();
|
||||
if (gCurrentPinballGame->mainBoardCountdownTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->mainBoardCountdownTimer--;
|
||||
}
|
||||
}
|
||||
|
||||
//Duplicate of HandleSapphireFlipperButtonInput, with "gCurrentPinballGame->rampGateHitFlag = 1;" added in the final if statement
|
||||
void HandleRubyFlipperButtonInput(void)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
if (gCurrentPinballGame->newButtonActions[0])
|
||||
{
|
||||
if (gCurrentPinballGame->pikaKickbackTimer == 0 && gCurrentPinballGame->outLanePikaPosition != 2 &&
|
||||
gCurrentPinballGame->pichuEntranceTimer == 0 && gCurrentPinballGame->kickbackFiring == 0)
|
||||
{
|
||||
gCurrentPinballGame->outLanePikaPosition = 0;
|
||||
}
|
||||
|
||||
tmp = gCurrentPinballGame->holeIndicators[0];
|
||||
gCurrentPinballGame->holeIndicators[0] = gCurrentPinballGame->holeIndicators[1];
|
||||
gCurrentPinballGame->holeIndicators[1] = gCurrentPinballGame->holeIndicators[2];
|
||||
gCurrentPinballGame->holeIndicators[2] = gCurrentPinballGame->holeIndicators[3];
|
||||
gCurrentPinballGame->holeIndicators[3] = tmp;
|
||||
|
||||
tmp = gCurrentPinballGame->ballPowerUpLight[0];
|
||||
gCurrentPinballGame->ballPowerUpLight[0] = gCurrentPinballGame->ballPowerUpLight[1];
|
||||
gCurrentPinballGame->ballPowerUpLight[1] = gCurrentPinballGame->ballPowerUpLight[2];
|
||||
gCurrentPinballGame->ballPowerUpLight[2] = tmp;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->newButtonActions[1])
|
||||
{
|
||||
if (gCurrentPinballGame->pikaKickbackTimer == 0 && gCurrentPinballGame->outLanePikaPosition != 2 &&
|
||||
gCurrentPinballGame->pichuEntranceTimer == 0 && gCurrentPinballGame->kickbackFiring == 0)
|
||||
{
|
||||
gCurrentPinballGame->outLanePikaPosition = 1;
|
||||
}
|
||||
|
||||
tmp = gCurrentPinballGame->holeIndicators[3];
|
||||
gCurrentPinballGame->holeIndicators[3] = gCurrentPinballGame->holeIndicators[2];
|
||||
gCurrentPinballGame->holeIndicators[2] = gCurrentPinballGame->holeIndicators[1];
|
||||
gCurrentPinballGame->holeIndicators[1] = gCurrentPinballGame->holeIndicators[0];
|
||||
gCurrentPinballGame->holeIndicators[0] = tmp;
|
||||
|
||||
tmp = gCurrentPinballGame->ballPowerUpLight[2];
|
||||
gCurrentPinballGame->ballPowerUpLight[2] = gCurrentPinballGame->ballPowerUpLight[1];
|
||||
gCurrentPinballGame->ballPowerUpLight[1] = gCurrentPinballGame->ballPowerUpLight[0];
|
||||
gCurrentPinballGame->ballPowerUpLight[0] = tmp;
|
||||
|
||||
gCurrentPinballGame->rampGateHitFlag = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
148
src/board_process3_ruby_entities.c
Normal file
148
src/board_process3_ruby_entities.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#include "global.h"
|
||||
#include "functions.h"
|
||||
#include "functions_ruby.h"
|
||||
#include "main.h"
|
||||
|
||||
void UpdateRubyBoardEntityRendering(void)
|
||||
{
|
||||
int randNum;
|
||||
|
||||
ProcessBannerCameraTransition();
|
||||
SelectRubyShopDoorState();
|
||||
if (gCurrentPinballGame->rampPrizeRespawnTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->rampPrizeRespawnTimer--;
|
||||
if (gCurrentPinballGame->rampPrizeRespawnTimer == 0)
|
||||
{
|
||||
randNum = Random();
|
||||
gCurrentPinballGame->rampPrizeType = ((randNum + gMain.systemFrameCount) % 100) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->cameraYViewport < 110)
|
||||
{
|
||||
UpdateNuzleafEntity();
|
||||
AnimateRubyShopDoor();
|
||||
DrawRubyNuzleafPlatformSprite();
|
||||
}
|
||||
AnimateOneUpSprite();
|
||||
if (gCurrentPinballGame->cameraYViewport < 168)
|
||||
{
|
||||
UpdateEggModeAnimation();
|
||||
}
|
||||
if (gCurrentPinballGame->cameraYViewport < 220)
|
||||
{
|
||||
UpdateHatchCave();
|
||||
if (gCurrentPinballGame->shouldProcessWhiscash)
|
||||
{
|
||||
DrawWhiscash();
|
||||
}
|
||||
else
|
||||
{
|
||||
RubyPondTriBumperHandleHitAndDraw();
|
||||
}
|
||||
AnimateSharpedoEntity();
|
||||
DrawPikachuSpinner();
|
||||
}
|
||||
UpdateChikoritaAttackAnimation();
|
||||
if (gCurrentPinballGame->cameraYViewport > 63)
|
||||
{
|
||||
AnimateChikoritaSprite();
|
||||
UpdateGulpinBossState();
|
||||
}
|
||||
if (gCurrentPinballGame->cameraYViewport > 115)
|
||||
{
|
||||
UpdateRubyRampPrizeGate();
|
||||
}
|
||||
if (gCurrentPinballGame->cameraYViewport > 130)
|
||||
{
|
||||
DrawRubySideBumperSprites();
|
||||
}
|
||||
UpdateSpoinkAnimation();
|
||||
if (gCurrentPinballGame->cameraYViewport > 168)
|
||||
{
|
||||
DrawSpoinkSprite();
|
||||
}
|
||||
|
||||
UpdateKickbackLogic();
|
||||
ProcessChargeIndicator();
|
||||
UpdateRubyBoardAnimations();
|
||||
UpdatePortraitSpritePositions();
|
||||
UpdateEvolutionShopSprite();
|
||||
DrawBoardEdgeBanner();
|
||||
|
||||
if (gCurrentPinballGame->coinRewardAmount != 0)
|
||||
{
|
||||
AnimateCoinReward();
|
||||
}
|
||||
BonusStage_HandleModeChangeFlags();
|
||||
|
||||
if (gCurrentPinballGame->ballLaunchTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->ballLaunchTimer--;
|
||||
if (gCurrentPinballGame->ballLaunchTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->secondaryBall = gCurrentPinballGame->ballStates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRubyBoardEntityLogic(void)
|
||||
{
|
||||
RubyPond_EntityLogic();
|
||||
UpdateRubyCatchModeAnimation();
|
||||
UpdatePikachuChargeCounter();
|
||||
UpdateRubySideBumperAnimation();
|
||||
if (gCurrentPinballGame->mainBoardCountdownTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->mainBoardCountdownTimer--;
|
||||
}
|
||||
}
|
||||
|
||||
//Duplicate of HandleSapphireFlipperButtonInput, with "gCurrentPinballGame->rampGateHitFlag = 1;" added in the final if statement
|
||||
void HandleRubyFlipperButtonInput(void)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
if (gCurrentPinballGame->newButtonActions[0])
|
||||
{
|
||||
if (gCurrentPinballGame->pikaKickbackTimer == 0 && gCurrentPinballGame->outLanePikaPosition != 2 &&
|
||||
gCurrentPinballGame->pichuEntranceTimer == 0 && gCurrentPinballGame->kickbackFiring == 0)
|
||||
{
|
||||
gCurrentPinballGame->outLanePikaPosition = 0;
|
||||
}
|
||||
|
||||
tmp = gCurrentPinballGame->holeIndicators[0];
|
||||
gCurrentPinballGame->holeIndicators[0] = gCurrentPinballGame->holeIndicators[1];
|
||||
gCurrentPinballGame->holeIndicators[1] = gCurrentPinballGame->holeIndicators[2];
|
||||
gCurrentPinballGame->holeIndicators[2] = gCurrentPinballGame->holeIndicators[3];
|
||||
gCurrentPinballGame->holeIndicators[3] = tmp;
|
||||
|
||||
tmp = gCurrentPinballGame->ballPowerUpLight[0];
|
||||
gCurrentPinballGame->ballPowerUpLight[0] = gCurrentPinballGame->ballPowerUpLight[1];
|
||||
gCurrentPinballGame->ballPowerUpLight[1] = gCurrentPinballGame->ballPowerUpLight[2];
|
||||
gCurrentPinballGame->ballPowerUpLight[2] = tmp;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->newButtonActions[1])
|
||||
{
|
||||
if (gCurrentPinballGame->pikaKickbackTimer == 0 && gCurrentPinballGame->outLanePikaPosition != 2 &&
|
||||
gCurrentPinballGame->pichuEntranceTimer == 0 && gCurrentPinballGame->kickbackFiring == 0)
|
||||
{
|
||||
gCurrentPinballGame->outLanePikaPosition = 1;
|
||||
}
|
||||
|
||||
tmp = gCurrentPinballGame->holeIndicators[3];
|
||||
gCurrentPinballGame->holeIndicators[3] = gCurrentPinballGame->holeIndicators[2];
|
||||
gCurrentPinballGame->holeIndicators[2] = gCurrentPinballGame->holeIndicators[1];
|
||||
gCurrentPinballGame->holeIndicators[1] = gCurrentPinballGame->holeIndicators[0];
|
||||
gCurrentPinballGame->holeIndicators[0] = tmp;
|
||||
|
||||
tmp = gCurrentPinballGame->ballPowerUpLight[2];
|
||||
gCurrentPinballGame->ballPowerUpLight[2] = gCurrentPinballGame->ballPowerUpLight[1];
|
||||
gCurrentPinballGame->ballPowerUpLight[1] = gCurrentPinballGame->ballPowerUpLight[0];
|
||||
gCurrentPinballGame->ballPowerUpLight[0] = tmp;
|
||||
|
||||
gCurrentPinballGame->rampGateHitFlag = 1;
|
||||
}
|
||||
}
|
||||
907
src/board_process3_ruby_entities_2.c
Normal file
907
src/board_process3_ruby_entities_2.c
Normal file
|
|
@ -0,0 +1,907 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/ruby_states.h"
|
||||
|
||||
extern struct SongHeader se_whiscash_splashdown;
|
||||
|
||||
extern const u8 gRubyBoardSharpedo_Gfx[][0x260];
|
||||
extern const s16 gSharpedoAnimFrameData[][2];
|
||||
extern const u16 gSharpedoSpritesheetOam[42][3][3];
|
||||
extern const u8 gRubyFlashingTiles_Secondary[][0x100];
|
||||
extern const u8 gChinchouBumperPalettes[];
|
||||
extern const struct Vector16 gChinchouWaypointPositions[];
|
||||
|
||||
extern const s16 gPondBumperTransitionFrames[];
|
||||
extern const u8 gLotadBumperTiles[][0x100];
|
||||
extern const u8 gLotadBumperPalettes[];
|
||||
extern const s16 gLotadBobOffsets[];
|
||||
extern const s16 gWhiscashFramesetData[][4];
|
||||
extern const s16 gWhiscashShakeOffsets[];
|
||||
extern const u8 gWhiscashPalettes[];
|
||||
extern const u8 gWhiscash_Gfx[][0x480];
|
||||
|
||||
extern const u8 gRubyBoardShopDoor_Gfx[][0x180];
|
||||
|
||||
extern const s16 gNuzleafAnimFrameData[50][3];
|
||||
extern const s16 gNuzleafPositions[][2];
|
||||
extern const u8 gRubyStageNuzleaf_Gfx[][0x280];
|
||||
extern const u16 gNuzleafOamData[58][6];
|
||||
|
||||
#define MIN_POND_SWITCHES_BEFORE_WHISCASH_AVAILABLE 3
|
||||
|
||||
void UpdateNuzleafEntity(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 * dst;
|
||||
s16 var0;
|
||||
s16 var1;
|
||||
|
||||
group = &gMain.spriteGroups[71];
|
||||
var0 = 0;
|
||||
var1 = 0;
|
||||
switch (gCurrentPinballGame->nuzleafAnimState)
|
||||
{
|
||||
case 0:
|
||||
var0 = (gMain.systemFrameCount % 36) / 18;
|
||||
var1 = var0;
|
||||
break;
|
||||
case 1:
|
||||
gCurrentPinballGame->nuzleafFrameTimer = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex = 0;
|
||||
gCurrentPinballGame->nuzleafAnimState = 2;
|
||||
var1 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][0];
|
||||
var0 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][2];
|
||||
m4aSongNumStart(SE_UNKNOWN_0xCF);
|
||||
PlayRumble(7);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 50000;
|
||||
break;
|
||||
case 2:
|
||||
if (gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][1] > gCurrentPinballGame->nuzleafFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->nuzleafFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->nuzleafFrameTimer = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex++;
|
||||
if (gCurrentPinballGame->nuzleafFrameIndex == 7)
|
||||
{
|
||||
gCurrentPinballGame->nuzleafAnimState = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex = 0;
|
||||
gCurrentPinballGame->nuzleafPositionIndex = 1;
|
||||
}
|
||||
}
|
||||
var1 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][0];
|
||||
var0 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][2];
|
||||
break;
|
||||
case 3:
|
||||
gCurrentPinballGame->nuzleafFrameTimer = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex = 7;
|
||||
gCurrentPinballGame->nuzleafAnimState = 4;
|
||||
var1 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][0];
|
||||
var0 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][2];
|
||||
m4aSongNumStart(SE_UNKNOWN_0xCF);
|
||||
PlayRumble(7);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 100000;
|
||||
break;
|
||||
case 4:
|
||||
if (gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][1] > gCurrentPinballGame->nuzleafFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->nuzleafFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->nuzleafFrameTimer = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex++;
|
||||
if (gCurrentPinballGame->nuzleafFrameIndex == 18)
|
||||
{
|
||||
gCurrentPinballGame->nuzleafAnimState = 5;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xD1);
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->nuzleafFrameTimer == 6)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xD0);
|
||||
|
||||
var1 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][0];
|
||||
var0 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][2];
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
if (gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][1] > gCurrentPinballGame->nuzleafFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->nuzleafFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->nuzleafFrameTimer = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex++;
|
||||
if (gCurrentPinballGame->nuzleafFrameIndex == 24)
|
||||
gCurrentPinballGame->nuzleafFrameIndex = 18;
|
||||
}
|
||||
|
||||
var1 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][0];
|
||||
var0 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][2];
|
||||
break;
|
||||
case 7:
|
||||
gCurrentPinballGame->nuzleafHitFlag = 0;
|
||||
gCurrentPinballGame->nuzleafPositionIndex = 0;
|
||||
gCurrentPinballGame->nuzleafFrameTimer = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex = 0;
|
||||
gCurrentPinballGame->nuzleafAnimState = 0;
|
||||
gCurrentPinballGame->nuzleafFrameIndex = 24;
|
||||
var1 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][0];
|
||||
var0 = gNuzleafAnimFrameData[gCurrentPinballGame->nuzleafFrameIndex][2];
|
||||
break;
|
||||
}
|
||||
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = gNuzleafPositions[gCurrentPinballGame->nuzleafPositionIndex][0] - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gNuzleafPositions[gCurrentPinballGame->nuzleafPositionIndex][1] - gCurrentPinballGame->cameraYOffset;
|
||||
DmaCopy16(3, gRubyStageNuzleaf_Gfx[gCurrentPinballGame->nuzleafGfxTileIndex], (void *)0x06014380, 0x260);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gNuzleafOamData[var1][i * 3 + 0];
|
||||
*dst++ = gNuzleafOamData[var1][i * 3 + 1];
|
||||
*dst++ = gNuzleafOamData[var1][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->nuzleafGfxTileIndex = var0;
|
||||
}
|
||||
|
||||
void SelectRubyShopDoorState(void)
|
||||
{
|
||||
if (gCurrentPinballGame->ballCatchState != 3)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->evolutionShopActive == 0)
|
||||
gCurrentPinballGame->shopDoorTargetFrame = gCurrentPinballGame->shopDoorOpenLevel & 0xF;
|
||||
else
|
||||
gCurrentPinballGame->shopDoorTargetFrame = 3;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardState != 6)
|
||||
{
|
||||
gCurrentPinballGame->shopDoorTargetFrame = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateRubyShopDoor(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 priority;
|
||||
|
||||
group = &gMain.spriteGroups[65];
|
||||
if ((gCurrentPinballGame->shopDoorTargetFrame & 0xF) != gCurrentPinballGame->shopDoorCurrentFrame)
|
||||
{
|
||||
if (gCurrentPinballGame->shopDoorAnimDelay)
|
||||
{
|
||||
if (gCurrentPinballGame->shopDoorAnimDelay == 5)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 3;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 0;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xBD);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->shopDoorAnimDelay--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->shopDoorCurrentFrame > (gCurrentPinballGame->shopDoorTargetFrame & 0xF))
|
||||
{
|
||||
gCurrentPinballGame->shopDoorCurrentFrame--;
|
||||
gCurrentPinballGame->shopDoorAnimDelay = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->shopDoorCurrentFrame++;
|
||||
gCurrentPinballGame->shopDoorAnimDelay = 4;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gRubyBoardShopDoor_Gfx[gCurrentPinballGame->shopDoorCurrentFrame], (void *)0x06013180, 0x180);
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->shopDoorCurrentFrame < 3)
|
||||
priority = 3;
|
||||
else
|
||||
priority = 2;
|
||||
|
||||
group->baseX = 208 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 80 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &gMain.spriteGroups[65].oam[i];
|
||||
gOamBuffer[oamSimple->oamId].priority = priority;
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWhiscash(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 var0;
|
||||
const s16 *var1;
|
||||
|
||||
group = &gMain.spriteGroups[63];
|
||||
var1 = gWhiscashFramesetData[gCurrentPinballGame->whiscashFrameIx];
|
||||
if (group->available)
|
||||
{
|
||||
var0 = var1[0];
|
||||
DmaCopy16(3, gWhiscashPalettes + gCurrentPinballGame->activePaletteIndex * 0x60, (void *)0x05000320, 0x20);
|
||||
DmaCopy16(3, gWhiscash_Gfx[var0], (void *)0x06014680, 0x460);
|
||||
gCurrentPinballGame->rubyBumperCollisionPosition[0].x = -248;
|
||||
gCurrentPinballGame->rubyBumperCollisionPosition[0].y = -316;
|
||||
group->baseX = var1[2] + 124u - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = var1[3] + 150u - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
if (var0 == 4 || var0 == 10)
|
||||
gCurrentPinballGame->whiscashInvulnerable = 0;
|
||||
else
|
||||
gCurrentPinballGame->whiscashInvulnerable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//Ruby Pond
|
||||
void RubyPond_EntityLogic(void)
|
||||
{
|
||||
s16 i;
|
||||
u16 angle;
|
||||
u16 angle2;
|
||||
s16 var1;
|
||||
s16 frameDecidedNextPondState;
|
||||
struct Vector32 tempVec;
|
||||
struct Vector32 tempVec2;
|
||||
int squaredMagnitude;
|
||||
|
||||
if (gCurrentPinballGame->shouldProcessWhiscash)
|
||||
{
|
||||
// If board is currently in one of the modes (catch/etc) force reset to the 3 chinchou
|
||||
if (gCurrentPinballGame->boardState > 2)
|
||||
gCurrentPinballGame->rubyPondContentsChanging = TRUE;
|
||||
|
||||
// Don't immediately force change state if Wishcash is actively doing something
|
||||
if (gCurrentPinballGame->rubyPondContentsChanging)
|
||||
{
|
||||
if (gCurrentPinballGame->whiscashState < WHISCASH_STATE_ABSORB_ZONE_HIT)
|
||||
{
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_LEAVING;
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_LEAVING-1;
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->rubyPondContentsChanging = FALSE;
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->whiscashState)
|
||||
{
|
||||
case WHISCASH_STATE_ARRIVAL:
|
||||
if (gWhiscashFramesetData[gCurrentPinballGame->whiscashFrameIx][1] > gCurrentPinballGame->whiscashStateTimer)
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashFrameIx++;
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_SITTING)
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_SITTING;
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_SPLASH)
|
||||
m4aSongNumStart(SE_WHISCASH_EMERGE_SPLASH);
|
||||
}
|
||||
break;
|
||||
case WHISCASH_STATE_SITTING:
|
||||
// Alternates between frame 4 and 5
|
||||
gCurrentPinballGame->whiscashFrameIx = (gCurrentPinballGame->whiscashStateTimer % 44) / 22 + 4;
|
||||
gCurrentPinballGame->whiscashStateTimer++;
|
||||
break;
|
||||
case WHISCASH_STATE_ABSORB_ZONE_HIT:
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_ABSORB_BALL_START;
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_ABSORBING;
|
||||
gCurrentPinballGame->ball->oamPriority = 0;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
m4aSongNumStart(SE_WHISCASH_CATCH_BALL);
|
||||
PlayRumble(7);
|
||||
break;
|
||||
case WHISCASH_STATE_ABSORBING:
|
||||
if (gWhiscashFramesetData[gCurrentPinballGame->whiscashFrameIx][1] > gCurrentPinballGame->whiscashStateTimer)
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashFrameIx++;
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_BALL_HELD_SUNK+1)
|
||||
{
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_BALL_HELD_SUNK;
|
||||
gCurrentPinballGame->whiscashStateTimer = 65;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_TO_SPHEAL_BOARD;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_LEAVING)
|
||||
m4aSongNumStart(SE_WHISCASH_LEAVE_BURBLE);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_ABSORB_BALL_START)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAngle += 64;
|
||||
gCurrentPinballGame->ball->positionQ8.x = 0x8900;
|
||||
gCurrentPinballGame->ball->positionQ8.y = 0xBD00;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_ABSORB_BALL_START+1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAngle += 64;
|
||||
gCurrentPinballGame->ball->positionQ8.x = 0x8C00;
|
||||
gCurrentPinballGame->ball->positionQ8.y = 0xB700;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_ABSORB_BALL_START+2)
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
break;
|
||||
case WHISCASH_STATE_TO_SPHEAL_BOARD:
|
||||
gCurrentPinballGame->startButtonDisabled = 1;
|
||||
if (gCurrentPinballGame->whiscashStateTimer == 65)
|
||||
{
|
||||
m4aSongNumStart(SE_WARP);
|
||||
gMain.blendControl = 0x9E;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashStateTimer)
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer--;
|
||||
gMain.blendBrightness = 16 - gCurrentPinballGame->whiscashStateTimer / 4;
|
||||
if (gCurrentPinballGame->whiscashStateTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->nextBonusField = FIELD_SPHEAL;
|
||||
gCurrentPinballGame->bonusReturnState = 1;
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
TransitionToBonusField();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WHISCASH_STATE_INIT_RETURN_FROM_BONUS: //from board initialization
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_DELIVER_BALL_START;
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_RISE_SPIT_LEAVE;
|
||||
gCurrentPinballGame->ball->oamPriority = 0;
|
||||
break;
|
||||
case WHISCASH_STATE_RISE_SPIT_LEAVE:
|
||||
if (gWhiscashFramesetData[gCurrentPinballGame->whiscashFrameIx][1] > gCurrentPinballGame->whiscashStateTimer)
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashFrameIx++;
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_DELIVER_BALL_END+1)
|
||||
{
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_SUBMERGED;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_CLEANUP;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_SPITBALL + 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAngle -= 64;
|
||||
gCurrentPinballGame->ball->positionQ8.x = 0x8300;
|
||||
gCurrentPinballGame->ball->positionQ8.y = 0xC700;
|
||||
gCurrentPinballGame->ball->velocity.x = -120;
|
||||
gCurrentPinballGame->ball->velocity.y = 210;
|
||||
gCurrentPinballGame->ball->oamPriority = 3;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_EMERGING)
|
||||
m4aSongNumStart(SE_WHISCASH_EMERGE_SPLASH);
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_SPITBALL + 7) {
|
||||
m4aSongNumStart(SE_WHISCASH_LEAVE_BURBLE);
|
||||
}
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_SPITBALL)
|
||||
{
|
||||
m4aSongNumStart(SE_WHISCASH_SPIT_BALL);
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_SPITBALL)
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->ball->spinAngle -= 64;
|
||||
gCurrentPinballGame->ball->positionQ8.x = 0x8500;
|
||||
gCurrentPinballGame->ball->positionQ8.y = 0xC000;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_SPITBALL+2)
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
break;
|
||||
case WHISCASH_STATE_HIT:
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_HIT;
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_ANGRY;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10;
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_HIT);
|
||||
PlayRumble(7);
|
||||
if (gCurrentPinballGame->saverTimeRemaining)
|
||||
gCurrentPinballGame->saverTimeRemaining = 1;
|
||||
break;
|
||||
case WHISCASH_STATE_ANGRY:
|
||||
if (gWhiscashFramesetData[gCurrentPinballGame->whiscashFrameIx][1] > gCurrentPinballGame->whiscashStateTimer)
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashFrameIx++;
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_GONE_AFTER_HIT+1)
|
||||
{
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_SUBMERGED;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_CLEANUP;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_LEAVING_AFTER_HIT)
|
||||
m4aSongNumStart(SE_WHISCASH_LEAVE_BURBLE);
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_HIT+2)
|
||||
m4aSongNumStart(SE_WHISCASH_EARTHQUAKE);
|
||||
}
|
||||
|
||||
// Heavy shaking starts
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_GONE_AFTER_HIT)
|
||||
{
|
||||
gCurrentPinballGame->screenShakeX = gWhiscashShakeOffsets[gCurrentPinballGame->whiscashStateTimer % 8];
|
||||
if (gCurrentPinballGame->whiscashStateTimer % 4 == 0)
|
||||
MPlayStart(&gMPlayInfo_SE3, &se_whiscash_splashdown);
|
||||
|
||||
if (gCurrentPinballGame->whiscashStateTimer % 10 == 0)
|
||||
PlayRumble(12);
|
||||
}
|
||||
break;
|
||||
case WHISCASH_STATE_LEAVING: //Early Exit (mode started)
|
||||
if (gWhiscashFramesetData[gCurrentPinballGame->whiscashFrameIx][1] > gCurrentPinballGame->whiscashStateTimer)
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashFrameIx++;
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_BALL_HELD_SUNK+1)
|
||||
{
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_SUBMERGED;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_CLEANUP;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->whiscashFrameIx == WHISCASH_FRAME_LEAVING)
|
||||
m4aSongNumStart(SE_WHISCASH_LEAVE_BURBLE);
|
||||
}
|
||||
break;
|
||||
case WHISCASH_STATE_CLEANUP:
|
||||
gCurrentPinballGame->shouldProcessWhiscash = FALSE;
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_SUBMERGED;
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->rubyPondContentsChanging = TRUE;
|
||||
gCurrentPinballGame->rubyPondChangeTimer = 64;
|
||||
gCurrentPinballGame->screenShakeX = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->rubyPondContentsChanging)
|
||||
{
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer < 144)
|
||||
{
|
||||
gCurrentPinballGame->pondBumperStates[0] = gPondBumperTransitionFrames[gCurrentPinballGame->rubyPondChangeTimer / 8];
|
||||
gCurrentPinballGame->pondBumperStates[1] = gCurrentPinballGame->pondBumperStates[0];
|
||||
gCurrentPinballGame->pondBumperStates[2] = gCurrentPinballGame->pondBumperStates[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->rubyPondContentsChanging = FALSE;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pondBumperStates[0] == 10)
|
||||
{
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer % 8 == 0 && gCurrentPinballGame->rubyPondChangeTimer / 8 == 8)
|
||||
{
|
||||
// Can't switch to Whiscash if in a catch/hatch/etc state, or if it hasn't yet hit a threshold
|
||||
// of pond states first.
|
||||
gCurrentPinballGame->pondSwitchesSinceLastWhiscash++;
|
||||
if (gCurrentPinballGame->pondSwitchesSinceLastWhiscash < MIN_POND_SWITCHES_BEFORE_WHISCASH_AVAILABLE ||
|
||||
gCurrentPinballGame->boardState > 2)
|
||||
{
|
||||
frameDecidedNextPondState = (gMain.systemFrameCount % 5) + 1;
|
||||
if (gCurrentPinballGame->rubyPondState == frameDecidedNextPondState)
|
||||
gCurrentPinballGame->rubyPondState = ((gMain.systemFrameCount + 1) % 5) + 1;
|
||||
else
|
||||
gCurrentPinballGame->rubyPondState = frameDecidedNextPondState;
|
||||
}
|
||||
else
|
||||
{
|
||||
frameDecidedNextPondState = (gMain.systemFrameCount % 6) + 1;
|
||||
if (gCurrentPinballGame->rubyPondState == frameDecidedNextPondState)
|
||||
gCurrentPinballGame->rubyPondState = ((gMain.systemFrameCount + 1) % 6) + 1;
|
||||
else
|
||||
gCurrentPinballGame->rubyPondState = frameDecidedNextPondState;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->forcePondToWhiscash)
|
||||
{
|
||||
gCurrentPinballGame->forcePondToWhiscash = FALSE;
|
||||
gCurrentPinballGame->rubyPondState = RUBY_POND_STATE_WHISCASH;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_WHISCASH)
|
||||
{
|
||||
gCurrentPinballGame->shouldProcessWhiscash = TRUE;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_ARRIVAL;
|
||||
gCurrentPinballGame->whiscashStateTimer = 0;
|
||||
gCurrentPinballGame->whiscashFrameIx = WHISCASH_FRAME_SUBMERGED;
|
||||
gCurrentPinballGame->rubyPondContentsChanging = FALSE;
|
||||
gCurrentPinballGame->pondSwitchesSinceLastWhiscash = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_CHINCHOU_SINGLE_CLOCKWISE)
|
||||
{
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].x = gChinchouWaypointPositions[0].x * 10;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].y = gChinchouWaypointPositions[0].y * 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->rubyPondChangeTimer++;
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 32)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_LEAVES);
|
||||
|
||||
switch (gCurrentPinballGame->rubyPondState)
|
||||
{
|
||||
case RUBY_POND_STATE_CHINCHOU_STAGGERED:
|
||||
case RUBY_POND_STATE_CHINCHOU_CLOCKWISE:
|
||||
case RUBY_POND_STATE_CHINCHOU_COUNTERCLOCKWISE:
|
||||
case RUBY_POND_STATE_CHINCHOU_ROWS:
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 102)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_EMERGES);
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 116)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_EMERGES);
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 130)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_EMERGES);
|
||||
break;
|
||||
case RUBY_POND_STATE_LOTAD:
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 102)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_EMERGES);
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 118)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_EMERGES);
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 134)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_EMERGES);
|
||||
break;
|
||||
case RUBY_POND_STATE_CHINCHOU_SINGLE_CLOCKWISE:
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer == 104)
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_EMERGES);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->rubyPondState)
|
||||
{
|
||||
case RUBY_POND_STATE_CHINCHOU_STAGGERED:
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].x = 1250;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].y = 1270;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].x = 1600;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].y = 1360;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].x = 1370;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].y = 1610;
|
||||
break;
|
||||
case RUBY_POND_STATE_CHINCHOU_CLOCKWISE:
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
angle = (gCurrentPinballGame->globalAnimFrameCounter & 0x7F) * 0x200 + i * 0x5555;
|
||||
var1 = (gCurrentPinballGame->globalAnimFrameCounter % 60) - 30;
|
||||
if (var1 < 0)
|
||||
var1 = -var1;
|
||||
|
||||
gCurrentPinballGame->bumperOrbitRadius = 180;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[i].x = (gCurrentPinballGame->bumperOrbitRadius * Cos(angle)) / 20000 + 1380;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[i].y = (gCurrentPinballGame->bumperOrbitRadius * Sin(angle)) / 20000 + 1500;
|
||||
}
|
||||
break;
|
||||
case RUBY_POND_STATE_CHINCHOU_COUNTERCLOCKWISE:
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
angle = 10000 - ((gCurrentPinballGame->globalAnimFrameCounter & 0x7F) * 0x200 + i * 0x5555);
|
||||
var1 = (gCurrentPinballGame->globalAnimFrameCounter % 60) - 30;
|
||||
if (var1 < 0)
|
||||
var1 = -var1;
|
||||
|
||||
gCurrentPinballGame->bumperOrbitRadius = 180;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[i].x = (gCurrentPinballGame->bumperOrbitRadius * Cos(angle)) / 20000 + 1380;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[i].y = (gCurrentPinballGame->bumperOrbitRadius * Sin(angle)) / 20000 + 1500;
|
||||
}
|
||||
break;
|
||||
case RUBY_POND_STATE_CHINCHOU_ROWS:
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
var1 = 23 - (gCurrentPinballGame->globalAnimFrameCounter % 46);
|
||||
if (var1 < 0)
|
||||
var1 = -var1;
|
||||
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[i + 1].x = (i * 33 + 121) * 10;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[i + 1].y = var1 * 5 + 1340;
|
||||
}
|
||||
|
||||
var1 = 23 - (gCurrentPinballGame->globalAnimFrameCounter + 23) % 46;
|
||||
if (var1 < 0)
|
||||
var1 = 0-var1;
|
||||
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].x = 1370;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].y = var1 * 5 + 1620;
|
||||
break;
|
||||
case RUBY_POND_STATE_LOTAD:
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].x = 1210;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].y = gLotadBobOffsets[(gCurrentPinballGame->globalAnimFrameCounter % 60) / 10] + 1300;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].x = 1600;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].y = gLotadBobOffsets[((gCurrentPinballGame->globalAnimFrameCounter + 20) % 60) / 10] + 1410;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].x = 1370;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].y = gLotadBobOffsets[((gCurrentPinballGame->globalAnimFrameCounter + 40) % 60) / 10] + 1660;
|
||||
break;
|
||||
case RUBY_POND_STATE_CHINCHOU_SINGLE_CLOCKWISE:
|
||||
tempVec.x = gChinchouWaypointPositions[gCurrentPinballGame->chinchouWaypointTarget].x * 10 - gCurrentPinballGame->rubyBumperLogicPosition[0].x;
|
||||
tempVec.y = gChinchouWaypointPositions[gCurrentPinballGame->chinchouWaypointTarget].y * 10 - gCurrentPinballGame->rubyBumperLogicPosition[0].y;
|
||||
squaredMagnitude = (tempVec.x * tempVec.x) + (tempVec.y * tempVec.y);
|
||||
angle2 = ArcTan2(tempVec.x, -tempVec.y);
|
||||
tempVec2.x = (Cos(angle2) * 7) / 20000;
|
||||
tempVec2.y = (Sin(angle2) * -7) / 20000;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].x += tempVec2.x;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].y += tempVec2.y;
|
||||
if (squaredMagnitude < 2500)
|
||||
gCurrentPinballGame->chinchouWaypointTarget = Random() % 4;
|
||||
|
||||
// moved off screen
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].x = 0;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].y = -300;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].x = 0;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].y = -300;
|
||||
break;
|
||||
case RUBY_POND_STATE_WHISCASH:
|
||||
// moved off screen
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].x = 0;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[0].y = -300;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].x = 0;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[1].y = -300;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].x = 0;
|
||||
gCurrentPinballGame->rubyBumperLogicPosition[2].y = -300;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ruby pond bumpers Handle Hit and draw
|
||||
void RubyPondTriBumperHandleHitAndDraw(void)
|
||||
{
|
||||
s16 i;
|
||||
s16 j;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 var0;
|
||||
|
||||
if (gCurrentPinballGame->bumperHitCountdown > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->bumperHitCountdown == 2)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 500;
|
||||
m4aSongNumStart(SE_RUBY_BUMPER_HIT);
|
||||
PlayRumble(7);
|
||||
if (gCurrentPinballGame->boardState == 4 && gCurrentPinballGame->boardSubState == 5 && gCurrentPinballGame->hatchTilesBumperAcknowledged < 6)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchTilesBumperAcknowledged == 0)
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 1;
|
||||
else if (gCurrentPinballGame->hatchTilesBumperAcknowledged == 1)
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 3;
|
||||
else
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 6;
|
||||
|
||||
if (gCurrentPinballGame->hatchTilesBumperAcknowledged == 6)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchTilesBoardAcknowledged == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_LOTAD)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 50;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 600;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 236;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 4;
|
||||
gCurrentPinballGame->bannerGfxIndex = 6;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 80;
|
||||
gCurrentPinballGame->bannerSlidePosition = -2500;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[6], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[6], (void *)0x050003C0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 50;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 600;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 236;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 4;
|
||||
gCurrentPinballGame->bannerGfxIndex = 1;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 80;
|
||||
gCurrentPinballGame->bannerSlidePosition = -2500;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[1], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[1], (void *)0x050003C0, 0x20);
|
||||
}
|
||||
|
||||
gMain.blendControl = 0xCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->pondEntitySpriteFlag++;
|
||||
gCurrentPinballGame->bumperHitsSinceReset++;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->bumperHitCountdown--;
|
||||
}
|
||||
|
||||
group = &gMain.spriteGroups[62];
|
||||
if (gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_LOTAD)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->pondBumperStates[i])
|
||||
{
|
||||
if (gCurrentPinballGame->pondBumperStates[i] > 100)
|
||||
{
|
||||
gCurrentPinballGame->pondBumperStates[i]--;
|
||||
if (gCurrentPinballGame->pondBumperStates[i] == 100)
|
||||
gCurrentPinballGame->pondBumperStates[i] = 0;
|
||||
|
||||
var0 = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 = gCurrentPinballGame->pondBumperStates[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 = (gCurrentPinballGame->globalAnimFrameCounter % 50) / 25;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gLotadBumperTiles[var0], (void *)0x06012E80 + i * 0x100, 0x100);
|
||||
}
|
||||
|
||||
DmaCopy16(3, gLotadBumperPalettes + gCurrentPinballGame->activePaletteIndex * 0x60, (void *)0x05000320, 0x20);
|
||||
}
|
||||
else // chinchou
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->pondBumperStates[i])
|
||||
{
|
||||
if (gCurrentPinballGame->pondBumperStates[i] > 100)
|
||||
{
|
||||
var0 = 9 - gCurrentPinballGame->pondBumperStates[i] / 105;
|
||||
gCurrentPinballGame->pondBumperStates[i]--;
|
||||
if (gCurrentPinballGame->pondBumperStates[i] == 100)
|
||||
gCurrentPinballGame->pondBumperStates[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 = gCurrentPinballGame->pondBumperStates[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 = (gCurrentPinballGame->globalAnimFrameCounter % 50) / 25;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gRubyFlashingTiles_Secondary[var0], (void *)0x06012E80 + i * 0x100, 0x100);
|
||||
}
|
||||
|
||||
DmaCopy16(3, gChinchouBumperPalettes + gCurrentPinballGame->activePaletteIndex * 0x60, (void *)0x05000320, 0x20);
|
||||
}
|
||||
|
||||
// Draw Bumpers: Lotad/chinchou
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->rubyBumperLogicPosition[i].x / 10 - gCurrentPinballGame->cameraXOffset - 8;
|
||||
group->baseY = gCurrentPinballGame->rubyBumperLogicPosition[i].y / 10 - gCurrentPinballGame->cameraYOffset - 4;
|
||||
gCurrentPinballGame->rubyBumperCollisionPosition[i].x = (-(gCurrentPinballGame->rubyBumperLogicPosition[i].x / 10) + 8) * 2;
|
||||
gCurrentPinballGame->rubyBumperCollisionPosition[i].y = (-(gCurrentPinballGame->rubyBumperLogicPosition[i].y / 10) + 7) * 2;
|
||||
if (group->baseY < -40)
|
||||
group->baseY = -40;
|
||||
|
||||
//sprites have a left/right half.
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
oamSimple = &group->oam[j + i * 2];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateSharpedoEntity(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 * dst;
|
||||
const u16 * src;
|
||||
s16 index;
|
||||
s16 var0;
|
||||
|
||||
index = (gMain.systemFrameCount % 55) / 11;
|
||||
group = &gMain.spriteGroups[61];
|
||||
DmaCopy16(3, gRubyBoardSharpedo_Gfx[gCurrentPinballGame->catchHoleTileVariant], (void *)0x06012C20, 0x260);
|
||||
if (gCurrentPinballGame->catchHoleAnimFrame)
|
||||
index = gCurrentPinballGame->catchHoleAnimFrame;
|
||||
|
||||
var0 = gSharpedoAnimFrameData[index][0];
|
||||
gCurrentPinballGame->catchHoleTileVariant = gSharpedoAnimFrameData[index][1];
|
||||
group->baseX = 179 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 174 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
src = gSharpedoSpritesheetOam[var0][i];
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,8 +24,8 @@ void SapphireBoardProcess_3A_326F4(void)
|
|||
gCurrentPinballGame->chargeIndicatorScaleX = 0x100;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 0x100;
|
||||
|
||||
InitSapphireEggCaveState();
|
||||
UpdateSapphireEggCaveAnimation();
|
||||
InitSapphireEggHatchState();
|
||||
UpdateSapphireEggHatchAnimation();
|
||||
UpdateSapphireShopSignAnimation();
|
||||
DrawSapphireShopSignSprite();
|
||||
UpdatePelipperPondEntity();
|
||||
|
|
@ -60,13 +60,14 @@ void UpdateSapphireBoardEntityRendering(void)
|
|||
|
||||
if (gCurrentPinballGame->cameraYViewport < 0x5a)
|
||||
{
|
||||
UpdateSapphireEggCaveAnimation();
|
||||
UpdateSapphireHoleLetterSystem();
|
||||
UpdateSapphireEggHatchAnimation();
|
||||
UpdateSapphireEggMachine();
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->holeLetterCount == 3 && gCurrentPinballGame->holeLetterSystemState == 0)
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx == 3 &&
|
||||
gCurrentPinballGame->sapphireHatchMachineState == 0)
|
||||
{
|
||||
gCurrentPinballGame->catchArrowPaletteActive = 1;
|
||||
}
|
||||
|
|
@ -103,7 +104,7 @@ void UpdateSapphireBoardEntityRendering(void)
|
|||
|
||||
if (0x76 < gCurrentPinballGame->cameraYViewport)
|
||||
{
|
||||
DrawZigzagoonAndShockWall();
|
||||
DrawZigzagoonAndRouletteStopPrompt();
|
||||
DrawSapphireSeedotAndBasketSprites();
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +134,7 @@ void UpdateSapphireBoardEntityLogic(void)
|
|||
gCurrentPinballGame->mainBoardCountdownTimer--;
|
||||
|
||||
UpdateZigzagoonEntity();
|
||||
DecrementFieldTimer();
|
||||
DecrementPelipperTimer();
|
||||
UpdateSapphireShopSignAnimation();
|
||||
|
||||
if (!(gMain.modeChangeFlags & MODE_CHANGE_END_OF_GAME))
|
||||
|
|
|
|||
|
|
@ -338,7 +338,6 @@ void ComputeFlipperBounce(struct Vector16* arg0, struct Vector16* arg1, s16 arg2
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void ComputeWallReflection(u16 arg0, struct Vector16 *arg1, struct Vector16 *arg2)
|
||||
{
|
||||
u16 angleOfFlippedArg1;
|
||||
|
|
@ -742,7 +741,6 @@ u16 CheckFlipperCollision(struct Vector16* arg0, u16* arg1)
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
u16 CheckCatchTargetCollision(struct Vector16 *arg0, u16 *arg1)
|
||||
{
|
||||
struct Vector16 vec1;
|
||||
|
|
@ -832,7 +830,6 @@ u16 CheckCatchTargetCollision(struct Vector16 *arg0, u16 *arg1)
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
void ProcessBonusTrapPhysics(void)
|
||||
{
|
||||
struct Vector16 vec1;
|
||||
|
|
@ -991,4 +988,4 @@ void ComputeFlipperLaunchVelocity(s32 arg0, s16 arg1, struct Vector16* arg2, u16
|
|||
arg2->x = scale * Cos(angle2) / 20000;
|
||||
arg2->y = -scale * Sin(angle2) / 20000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ void MainBoardProcess_7B_12524(void)
|
|||
SetMatrixScale(currentBallState->scale, currentBallState->scale, 0);
|
||||
|
||||
spriteGroup->baseX = -(gCurrentPinballGame->cameraBaseX + 7) + currentBallState->positionQ0.x - gCurrentPinballGame->screenShakeX;
|
||||
spriteGroup->baseY = -(gCurrentPinballGame->cameraBaseY + 7) + currentBallState->positionQ0.y - gCurrentPinballGame->cameraScrollOffset - gCurrentPinballGame->cameraYAdjust + gCurrentPinballGame->sapphireSpriteTimer;
|
||||
spriteGroup->baseY = -(gCurrentPinballGame->cameraBaseY + 7) + currentBallState->positionQ0.y - gCurrentPinballGame->cameraScrollOffset - gCurrentPinballGame->cameraYAdjust + gCurrentPinballGame->spoinkPullbackYDistance;
|
||||
|
||||
currentBallState->screenPosition.x = spriteGroup->baseX;
|
||||
currentBallState->screenPosition.y = spriteGroup->baseY;
|
||||
|
|
@ -100,7 +100,7 @@ void MainBoardProcess_7B_12524(void)
|
|||
SetMatrixScale(currentBallState->scale, currentBallState->scale, 0);
|
||||
|
||||
spriteGroup->baseX = -(gCurrentPinballGame->cameraBaseX + 7) + currentBallState->positionQ0.x - gCurrentPinballGame->screenShakeX;
|
||||
spriteGroup->baseY = -(gCurrentPinballGame->cameraBaseY + 7) + currentBallState->positionQ0.y - gCurrentPinballGame->cameraScrollOffset - gCurrentPinballGame->cameraYAdjust + gCurrentPinballGame->sapphireSpriteTimer;
|
||||
spriteGroup->baseY = -(gCurrentPinballGame->cameraBaseY + 7) + currentBallState->positionQ0.y - gCurrentPinballGame->cameraScrollOffset - gCurrentPinballGame->cameraYAdjust + gCurrentPinballGame->spoinkPullbackYDistance;
|
||||
|
||||
currentBallState->screenPosition.x = spriteGroup->baseX;
|
||||
currentBallState->screenPosition.y = spriteGroup->baseY;
|
||||
|
|
|
|||
148
src/board_process_3_charge_spinner.c
Normal file
148
src/board_process_3_charge_spinner.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern struct SongHeader se_pika_full_charge_1_up;
|
||||
extern struct SongHeader se_pika_spinner_clack;
|
||||
|
||||
void UpdatePikachuChargeCounter(void)
|
||||
{
|
||||
if (gCurrentPinballGame->pikaChargeTarget != gCurrentPinballGame->pikaChargeProgress)
|
||||
{
|
||||
gCurrentPinballGame->pikaChargeProgress += 2;
|
||||
gCurrentPinballGame->chargeFillValue = gCurrentPinballGame->pikaChargeProgress / 14;
|
||||
gCurrentPinballGame->fullChargeSlideAnimTimer = 80;
|
||||
gCurrentPinballGame->chargeIndicatorScaleX = 256;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 256;
|
||||
if (gCurrentPinballGame->chargeFillValue == 11)
|
||||
gCurrentPinballGame->chargeFillAnimTimer = 120;
|
||||
|
||||
if (gCurrentPinballGame->chargeFillValue > 11)
|
||||
{
|
||||
gCurrentPinballGame->chargeFillValue = 12;
|
||||
gCurrentPinballGame->fullChargeSlideAnimTimer = 120;
|
||||
gCurrentPinballGame->chargeIndicatorScaleX = 256;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 256;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pikaChargeProgress < 168 && gCurrentPinballGame->pikaChargeProgress % 8 == 0)
|
||||
{
|
||||
s8 offset = gCurrentPinballGame->pikaChargeProgress / 21;
|
||||
m4aSongNumStart(SE_PIKA_CHARGE_DO + offset);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pikaChargeTarget <= gCurrentPinballGame->pikaChargeProgress)
|
||||
{
|
||||
gCurrentPinballGame->pikaChargeProgress = gCurrentPinballGame->pikaChargeTarget;
|
||||
if (gCurrentPinballGame->pikaChargeProgress >= 168)
|
||||
{
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_pika_full_charge_1_up);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 3000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pikaSpinCooldownTimer)
|
||||
gCurrentPinballGame->pikaSpinCooldownTimer--;
|
||||
|
||||
if (gCurrentPinballGame->pikaSpinMomentum > 0)
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinMomentum -= 3;
|
||||
if (gCurrentPinballGame->pikaSpinMomentum < 0)
|
||||
gCurrentPinballGame->pikaSpinMomentum = 0;
|
||||
|
||||
if (gCurrentPinballGame->pikaSpinFrameCounter < gCurrentPinballGame->pikaSpinPeriod - 1)
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinFrameCounter = 0;
|
||||
MPlayStart(&gMPlayInfo_SE3, &se_pika_spinner_clack);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 100;
|
||||
if (gCurrentPinballGame->chargeFillValue < 12 && gCurrentPinballGame->kickbackFiring == 0)
|
||||
{
|
||||
gCurrentPinballGame->fullChargeSlideAnimTimer = 80;
|
||||
gCurrentPinballGame->chargeIndicatorScaleX = 256;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 256;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->pikaSpinPeriod = (450 - gCurrentPinballGame->pikaSpinMomentum) / 10;
|
||||
if (gCurrentPinballGame->pikaSpinPeriod < 5)
|
||||
gCurrentPinballGame->pikaSpinPeriod = 5;
|
||||
|
||||
gCurrentPinballGame->pikachuSpinFrame = (gCurrentPinballGame->pikaSpinFrameCounter * 16) / gCurrentPinballGame->pikaSpinPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->pikaSpinMomentum < 0)
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinMomentum += 3;
|
||||
if (gCurrentPinballGame->pikaSpinMomentum > 0)
|
||||
gCurrentPinballGame->pikaSpinMomentum = 0;
|
||||
|
||||
if (gCurrentPinballGame->pikaSpinFrameCounter < gCurrentPinballGame->pikaSpinPeriod - 1)
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinFrameCounter = 0;
|
||||
MPlayStart(&gMPlayInfo_SE3, &se_pika_spinner_clack);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 100;
|
||||
if (gCurrentPinballGame->chargeFillValue < 12 && gCurrentPinballGame->kickbackFiring == 0)
|
||||
{
|
||||
gCurrentPinballGame->fullChargeSlideAnimTimer = 80;
|
||||
gCurrentPinballGame->chargeIndicatorScaleX = 256;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 256;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->pikaSpinPeriod = (450 + gCurrentPinballGame->pikaSpinMomentum) / 10;
|
||||
if (gCurrentPinballGame->pikaSpinPeriod < 5)
|
||||
gCurrentPinballGame->pikaSpinPeriod = 5;
|
||||
|
||||
gCurrentPinballGame->pikachuSpinFrame = (gCurrentPinballGame->pikaSpinFrameCounter * 16) / gCurrentPinballGame->pikaSpinPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->pikachuSpinFrame > 0)
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinFrameCounter++;
|
||||
gCurrentPinballGame->pikaSpinFrameCounter %= 40;
|
||||
gCurrentPinballGame->pikachuSpinFrame = (gCurrentPinballGame->pikaSpinFrameCounter * 16) / 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPikachuSpinner(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
index = gCurrentPinballGame->pikachuSpinFrame;
|
||||
group = gMain.fieldSpriteGroups[31];
|
||||
group->baseX = 206 - gCurrentPinballGame->cameraXOffset;
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
group->baseY = 174 - gCurrentPinballGame->cameraYOffset;
|
||||
else
|
||||
group->baseY = 154 - gCurrentPinballGame->cameraYOffset;
|
||||
|
||||
if (gCurrentPinballGame->pikachuSpinFrame != gCurrentPinballGame->pikachuSpinPrevFrame)
|
||||
{
|
||||
gCurrentPinballGame->pikachuSpinPrevFrame = gCurrentPinballGame->pikachuSpinFrame;
|
||||
DmaCopy16(3, gMainBoardPikaSpinner_Gfx[index], (void *)0x06010780, 0x120);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ extern const u8 gSphealIntroSprites_Gfx[];
|
|||
|
||||
extern const struct FieldBoardLayout gFieldBoardConfigs[];
|
||||
|
||||
void loadIntroduction(void)
|
||||
void loadFieldBoardGraphics(void)
|
||||
{
|
||||
struct BoardConfig *dest = &gBoardConfig;
|
||||
const struct FieldBoardLayout *src = gFieldBoardConfigs;
|
||||
134
src/board_state_transitions_and_idle.c
Normal file
134
src/board_state_transitions_and_idle.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern const void (*gBoardStateInitFuncs[])(void);
|
||||
extern const void (*gBoardStateUpdateFuncs[])(void);
|
||||
|
||||
extern void HandleBoardStateTransitionTeardown(void);
|
||||
|
||||
void RequestBoardStateTransition(u8 arg0)
|
||||
{
|
||||
gCurrentPinballGame->boardTransitionPhase = 2;
|
||||
gCurrentPinballGame->nextBoardState = arg0;
|
||||
if (gCurrentPinballGame->boardState == 2)
|
||||
gMain.fieldSpriteGroups[13]->available = 0;
|
||||
}
|
||||
|
||||
void BoardStateDispatcher(void)
|
||||
{
|
||||
switch (gCurrentPinballGame->boardTransitionPhase)
|
||||
{
|
||||
case 0:
|
||||
gBoardStateInitFuncs[gCurrentPinballGame->boardState]();
|
||||
gCurrentPinballGame->boardTransitionPhase++;
|
||||
break;
|
||||
case 1:
|
||||
gBoardStateUpdateFuncs[gCurrentPinballGame->boardState]();
|
||||
break;
|
||||
case 2:
|
||||
HandleBoardStateTransitionTeardown();
|
||||
gCurrentPinballGame->prevBoardState = gCurrentPinballGame->boardState;
|
||||
gCurrentPinballGame->boardState = gCurrentPinballGame->nextBoardState;
|
||||
gCurrentPinballGame->boardTransitionPhase = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitFieldIdle(void)
|
||||
{
|
||||
s16 num1;
|
||||
u8 num2;
|
||||
|
||||
if (gCurrentPinballGame->prevBoardState > 0)
|
||||
{
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
num1 = gCurrentPinballGame->numCompletedBonusStages / 5;
|
||||
if ((num1 & 1) == 0)
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_RUBY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_RUBY2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num1 = gCurrentPinballGame->numCompletedBonusStages / 5;
|
||||
if ((num1 & 1) == 0)
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_SAPPHIRE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m4aSongNumStart(MUS_FIELD_SAPPHIRE2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
num2 = gCurrentPinballGame->prevBoardState - 1;
|
||||
if (num2 > 1)
|
||||
{
|
||||
gCurrentPinballGame->evoArrowProgress = gCurrentPinballGame->arrowProgressPreserved;
|
||||
gCurrentPinballGame->catchArrowProgress = gCurrentPinballGame->catchModeArrows;
|
||||
gCurrentPinballGame->arrowProgressPreserved = 0;
|
||||
gCurrentPinballGame->catchModeArrows = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateFieldIdle(void)
|
||||
{
|
||||
if (gCurrentPinballGame->allHolesLit != 0)
|
||||
{
|
||||
if (gCurrentPinballGame->allHolesLitDelayTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->allHolesLitDelayTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestBoardStateTransition(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleBoardStateTransitionTeardown(void)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState == 2 && gCurrentPinballGame->nextBoardState > 2)
|
||||
ResetCatchState(0);
|
||||
|
||||
if (gCurrentPinballGame->boardState > 2)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->nextBoardState == 3)
|
||||
{
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->nextBoardState == 4)
|
||||
{
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->nextBoardState == 6)
|
||||
{
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->arrowProgressPreserved = 0;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->nextBoardState > 3)
|
||||
{
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
}
|
||||
}
|
||||
914
src/catch_and_hatch_modes.c
Normal file
914
src/catch_and_hatch_modes.c
Normal file
|
|
@ -0,0 +1,914 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern u8 gCatchSpriteFrameBuffer[];
|
||||
|
||||
extern struct BoardConfig gBoardConfig;
|
||||
extern u8 gCatchSpritePaletteBuffer[];
|
||||
extern u8 gCatchSpritePalettes[];
|
||||
|
||||
extern const u8 gSapphireCatchTilesGfx[];
|
||||
extern const u8 gSapphireCatchPalette[];
|
||||
extern const u8 gDefaultBallPalette[];
|
||||
extern const u8 gBasketAnimationTilesGfx[][0x480];
|
||||
extern const u8 gCapturePalette[];
|
||||
extern const s16 gHatchSequentialFrameData[8][2];
|
||||
extern const struct Vector16 gJirachiWaypoints[];
|
||||
extern const u16 gJirachiStarFrameIndices[][10];
|
||||
|
||||
extern const u8 (*gMonIconPalettes[])[0x20];
|
||||
extern const u16 gSapphireFloatOamFramesets[68][3][3];
|
||||
extern const u16 gSapphireHatchOamFramesets[14][18];
|
||||
extern const u8 (*gCatchSpriteGfxPtrs[])[0x480];
|
||||
|
||||
extern struct SongHeader se_evo_item_appear;
|
||||
|
||||
enum HatchTileRevealStates {
|
||||
HATCH_TILE_REVEAL_NONE = 0,
|
||||
HATCH_TILE_REVEAL_ONE_AT_A_TIME = 1,
|
||||
HATCH_TILE_REVEAL_ALL_AT_ONCE = 2
|
||||
};
|
||||
|
||||
#define BONUS_CATCH_TIME 7200 //2 minutes, 60FPS
|
||||
|
||||
void CleanupCatchEmState(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
gCurrentPinballGame->creatureHitCount = 0;
|
||||
gCurrentPinballGame->captureFlashTimer = 0;
|
||||
gMain.fieldSpriteGroups[18]->available = 0;
|
||||
gMain.fieldSpriteGroups[12]->available = 0;
|
||||
gCurrentPinballGame->jirachiCollisionEnabled = 0;
|
||||
LoadPortraitGraphics(0, 0);
|
||||
gCurrentPinballGame->portraitDisplayState = 0;
|
||||
ResetEventState();
|
||||
for (i = 0; i < 6; i++)
|
||||
gCurrentPinballGame->hatchTilePalette[i] = 13;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (i < gCurrentPinballGame->evoItemCount)
|
||||
gCurrentPinballGame->catchLights[i] = 1;
|
||||
else
|
||||
gCurrentPinballGame->catchLights[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void InitCatchEmMode(void)
|
||||
{
|
||||
s16 i, j;
|
||||
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->boardModeType = 1;
|
||||
gCurrentPinballGame->eventTimer = gCurrentPinballGame->timerBonus + BONUS_CATCH_TIME;
|
||||
gCurrentPinballGame->timerBonus = 0;
|
||||
gCurrentPinballGame->creatureHitCount = 0;
|
||||
gCurrentPinballGame->creatureHitCooldown = 0;
|
||||
gCurrentPinballGame->captureFlashTimer = 0;
|
||||
gCurrentPinballGame->hatchTilesBoardAcknowledged = 0;
|
||||
gCurrentPinballGame->hatchSequentialTilesRevealed = 0;
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 0;
|
||||
gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer = 0;
|
||||
gCurrentPinballGame->hatchFrameId = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
gCurrentPinballGame->catchProgressFlashing = 0;
|
||||
|
||||
if (gCurrentPinballGame->catchEmModeStartCount == 0)
|
||||
{
|
||||
gCurrentPinballGame->saverTimeRemaining = 6000;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->saverTimeRemaining = 4200;
|
||||
}
|
||||
gCurrentPinballGame->catchEmModeStartCount++;
|
||||
|
||||
DmaCopy16(3, gDefaultBallPalette, (void *)PLTT + 0x180, 0x20);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
gCurrentPinballGame->hatchTileShufflePool[i] = i;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->hatchGridCellIndex = gMain.systemFrameCount % 6;
|
||||
gCurrentPinballGame->hatchTilesRemaining = 5;
|
||||
|
||||
for (j = gCurrentPinballGame->hatchGridCellIndex; j < gCurrentPinballGame->hatchTilesRemaining; j++)
|
||||
{
|
||||
gCurrentPinballGame->hatchTileShufflePool[j] = gCurrentPinballGame->hatchTileShufflePool[j+1];
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCatchEmMode(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
if (gCurrentPinballGame->boardModeType && gCurrentPinballGame->eventTimer < 2 && gCurrentPinballGame->boardSubState < 10)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
m4aSongNumStart(MUS_END_OF_BALL2);
|
||||
gCurrentPinballGame->stageTimer = 200;
|
||||
gCurrentPinballGame->boardSubState = 10;
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 0:
|
||||
BuildSpeciesWeightsForCatchEmMode();
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 1:
|
||||
PickSpeciesForCatchEmMode();
|
||||
if (gMain.mainState != STATE_GAME_IDLE)
|
||||
SaveFile_SetPokedexFlags(gCurrentPinballGame->currentSpecies, 1);
|
||||
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 2:
|
||||
LoadCatchSpriteGraphics();
|
||||
gCurrentPinballGame->catchModeArrows = 0;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 3:
|
||||
LoadPortraitGraphics(3, 0);
|
||||
gCurrentPinballGame->hatchTileRevealState = HATCH_TILE_REVEAL_NONE;
|
||||
gCurrentPinballGame->hatchRevealPhase = 0;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
for (i = 0; i < 6; i++)
|
||||
gCurrentPinballGame->hatchTilePalette[i] = 15;
|
||||
break;
|
||||
case 4: // init hatch mode
|
||||
if (gMain.modeChangeFlags == MODE_CHANGE_NONE)
|
||||
{
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer == 94)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 93)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 120;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 2;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 1;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 80;
|
||||
gCurrentPinballGame->bannerSlidePosition = -2500;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[2], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[2], (void *)0x050003C0, 0x20);
|
||||
gMain.blendControl = 0xCE;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 73)
|
||||
{
|
||||
m4aSongNumStart(MUS_CATCH_EM_MODE);
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer < 17)
|
||||
{
|
||||
gCurrentPinballGame->boardModeType = 2;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
}
|
||||
}
|
||||
else // Sapphire board
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer == 68)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 67)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 120;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 2;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 1;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 80;
|
||||
gCurrentPinballGame->bannerSlidePosition = -2500;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[2], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[2], (void *)0x050003C0, 0x20);
|
||||
gMain.blendControl = 0xCE;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 47)
|
||||
{
|
||||
m4aSongNumStart(MUS_CATCH_EM_MODE2);
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->boardModeType = 2;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckHatchTileRevealState();
|
||||
return;
|
||||
case 5: // hatch mode running
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 1;
|
||||
CheckHatchTileRevealState();
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
return;
|
||||
case 6:
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 0;
|
||||
if (gCurrentPinballGame->stageTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->activePortraitType = 10;
|
||||
DmaCopy16(3, gSapphireCatchTilesGfx, (void *)0x06015800, 0x1400);
|
||||
DmaCopy16(3, gSapphireCatchPalette, (void *)0x050003C0, 0x20);
|
||||
m4aSongNumStart(SE_UNKNOWN_0xA7);
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
PlayEggCrackAnimation();
|
||||
return;
|
||||
case 8:
|
||||
ResetHatchFrameState();
|
||||
DmaCopy16(3, gCapturePalette, (void *)0x050003E0, 0x20);
|
||||
DmaCopy16(3, gCatchSpritePalettes, (void *)0x050003A0, 0x20);
|
||||
gCurrentPinballGame->catchTargetX = 118;
|
||||
gCurrentPinballGame->catchTargetY = 264;
|
||||
gCurrentPinballGame->evoBlinkTimer = 0;
|
||||
gCurrentPinballGame->catchLights[0] = 2;
|
||||
gCurrentPinballGame->catchLights[1] = 2;
|
||||
gCurrentPinballGame->catchLights[2] = 2;
|
||||
DrawCaughtPokemonSprite();
|
||||
gCurrentPinballGame->jirachiCollisionEnabled = 1;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->bgmFadeTimer = 140;
|
||||
PlayCry_Normal(gSpeciesInfo[gCurrentPinballGame->currentSpecies].speciesIdRS, 0);
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
return;
|
||||
case 9:
|
||||
if (gCurrentPinballGame->stageTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->bannerDisplayTimer = 0;
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
}
|
||||
DrawCaughtPokemonSprite();
|
||||
if (gCurrentPinballGame->creatureHitCooldown)
|
||||
gCurrentPinballGame->creatureHitCooldown--;
|
||||
break;
|
||||
case 10:
|
||||
CleanupCaughtPokemonSprite();
|
||||
DisableHatchTileDisplay();
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 11:
|
||||
CleanupCatchEmState();
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 12:
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 0;
|
||||
if (gCurrentPinballGame->stageTimer)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->catchLights[2] == 1)
|
||||
RequestBoardStateTransition(3);
|
||||
else
|
||||
RequestBoardStateTransition(1);
|
||||
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//jirachi.c starts here
|
||||
void InitJirachiBonus(void)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->boardModeType = 1;
|
||||
gCurrentPinballGame->eventTimer = gCurrentPinballGame->timerBonus + 1800;
|
||||
gCurrentPinballGame->timerBonus = 0;
|
||||
gCurrentPinballGame->creatureHitCount = 0;
|
||||
gCurrentPinballGame->creatureHitCooldown = 0;
|
||||
gCurrentPinballGame->captureFlashTimer = 0;
|
||||
gCurrentPinballGame->jirachiWaypointTimer = 0;
|
||||
gCurrentPinballGame->jirachiLogicX = 900;
|
||||
gCurrentPinballGame->jirachiLogicY = -1400;
|
||||
gCurrentPinballGame->jirachiWaypoint = 0;
|
||||
gCurrentPinballGame->jirachiTargetX = 0;
|
||||
gCurrentPinballGame->jirachiTargetY = 0;
|
||||
gCurrentPinballGame->jirachiDisplayX = 0;
|
||||
gCurrentPinballGame->jirachiDisplayY = 0;
|
||||
gCurrentPinballGame->jirachiCenterX = 0;
|
||||
gCurrentPinballGame->jirachiCenterY = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 0;
|
||||
gCurrentPinballGame->catchProgressFlashing = 0;
|
||||
gCurrentPinballGame->jirachiTagTimer[0] = 0;
|
||||
gCurrentPinballGame->jirachiTagTimer[1] = 10;
|
||||
gCurrentPinballGame->jirachiTagTimer[2] = 20;
|
||||
gCurrentPinballGame->jirachiTagTimer[3] = 30;
|
||||
gCurrentPinballGame->saverTimeRemaining = 3240;
|
||||
gCurrentPinballGame->allHolesLit = 0;
|
||||
gCurrentPinballGame->holeIndicators[0] = 0;
|
||||
gCurrentPinballGame->holeIndicators[1] = gCurrentPinballGame->holeIndicators[0];
|
||||
gCurrentPinballGame->holeIndicators[2] = gCurrentPinballGame->holeIndicators[0];
|
||||
gCurrentPinballGame->holeIndicators[3] = gCurrentPinballGame->holeIndicators[0];
|
||||
DmaCopy16(3, gDefaultBallPalette, (void *)0x05000180, 0x20);
|
||||
}
|
||||
|
||||
void UpdateJirachiBonus(void)
|
||||
{
|
||||
struct Vector32 tempVec;
|
||||
struct Vector32 deltaVec;
|
||||
u16 angle;
|
||||
int xx, yy;
|
||||
int deltaMagSquared;
|
||||
u16 var0;
|
||||
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 0:
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_JIRACHI;
|
||||
LoadCatchSpriteGraphics();
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
return;
|
||||
case 1:
|
||||
if (gMain.modeChangeFlags == MODE_CHANGE_NONE)
|
||||
{
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer == 94)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 93)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 120;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 5;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 1;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 80;
|
||||
gCurrentPinballGame->bannerSlidePosition = -2500;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[5], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[5], (void *)0x050003C0, 0x20);
|
||||
gMain.blendControl = 0xCE;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 73)
|
||||
{
|
||||
m4aSongNumStart(MUS_JIRACHI);
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 40)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer == 68)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 67)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 120;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 5;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 1;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 80;
|
||||
gCurrentPinballGame->bannerSlidePosition = -2500;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[5], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[5], (void *)0x050003C0, 0x20);
|
||||
gMain.blendControl = 0xCE;
|
||||
return;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 47)
|
||||
{
|
||||
m4aSongNumStart(MUS_JIRACHI);
|
||||
return;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 40)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((gMain.modeChangeFlags & MODE_CHANGE_BANNER) && gCurrentPinballGame->bannerSlideTimer == 1)
|
||||
{
|
||||
gCurrentPinballGame->portraitDisplayState = 3;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
DmaCopy16(3, gCapturePalette, (void *)0x050003E0, 0x20);
|
||||
DmaCopy16(3, gCatchSpritePalettes, (void *)0x050003A0, 0x20);
|
||||
gCurrentPinballGame->evoBlinkTimer = 0;
|
||||
gCurrentPinballGame->catchLights[0] = 2;
|
||||
gCurrentPinballGame->catchLights[1] = 2;
|
||||
gCurrentPinballGame->catchLights[2] = 2;
|
||||
gCurrentPinballGame->jirachiCollisionEnabled = 1;
|
||||
gMain.fieldSpriteGroups[33]->available = 1;
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, (void *)0x06010CA0, 0x480);
|
||||
gCurrentPinballGame->modeAnimTimer = 40;
|
||||
gCurrentPinballGame->jirachiLogicX = 900;
|
||||
gCurrentPinballGame->jirachiLogicY = -1400;
|
||||
gCurrentPinballGame->jirachiWaypoint = 0;
|
||||
gCurrentPinballGame->jirachiTargetX = gJirachiWaypoints[gCurrentPinballGame->jirachiWaypoint].x;
|
||||
gCurrentPinballGame->jirachiTargetY = gJirachiWaypoints[gCurrentPinballGame->jirachiWaypoint].y;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
m4aSongNumStart(SE_JIRACHI_MOVE);
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->jirachiDisplayX = gCurrentPinballGame->jirachiLogicX;
|
||||
gCurrentPinballGame->jirachiDisplayY = gCurrentPinballGame->jirachiLogicY;
|
||||
return;
|
||||
case 3:
|
||||
if (gCurrentPinballGame->captureState == 2)
|
||||
{
|
||||
gCurrentPinballGame->catchTargetX = gCurrentPinballGame->jirachiDisplayX / 10 + 118;
|
||||
gCurrentPinballGame->catchTargetY = gCurrentPinballGame->jirachiDisplayY / 10 + 272;
|
||||
}
|
||||
else
|
||||
{
|
||||
deltaVec.x = gCurrentPinballGame->jirachiTargetX - gCurrentPinballGame->jirachiLogicX;
|
||||
deltaVec.y = gCurrentPinballGame->jirachiTargetY - gCurrentPinballGame->jirachiLogicY;
|
||||
xx = deltaVec.x * deltaVec.x;
|
||||
yy = deltaVec.y * deltaVec.y;
|
||||
deltaMagSquared = xx + yy;
|
||||
angle = ArcTan2(deltaVec.x, -deltaVec.y);
|
||||
if (deltaMagSquared < 2500)
|
||||
{
|
||||
tempVec.x = 0;
|
||||
tempVec.y = 0;
|
||||
if (gCurrentPinballGame->jirachiWaypointTimer < 200)
|
||||
{
|
||||
gCurrentPinballGame->jirachiWaypointTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->jirachiWaypointTimer = 0;
|
||||
if (gCurrentPinballGame->jirachiWaypoint < 11)
|
||||
gCurrentPinballGame->jirachiWaypoint++;
|
||||
else
|
||||
gCurrentPinballGame->jirachiWaypoint = 0;
|
||||
|
||||
m4aSongNumStart(SE_JIRACHI_MOVE);
|
||||
gCurrentPinballGame->jirachiTargetX = gJirachiWaypoints[gCurrentPinballGame->jirachiWaypoint].x;
|
||||
gCurrentPinballGame->jirachiTargetY = gJirachiWaypoints[gCurrentPinballGame->jirachiWaypoint].y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempVec.x = (Cos(angle) * 7) / 20000;
|
||||
tempVec.y = (Sin(angle) * -7) / 20000;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->jirachiLogicX += tempVec.x;
|
||||
gCurrentPinballGame->jirachiLogicY += tempVec.y;
|
||||
var0 = ((gCurrentPinballGame->stageTimer % 80) << 0x10) / 80;
|
||||
gCurrentPinballGame->jirachiDisplayX = gCurrentPinballGame->jirachiLogicX;
|
||||
gCurrentPinballGame->jirachiDisplayY = gCurrentPinballGame->jirachiLogicY + (Sin(var0) * 60) / 20000;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer < 500)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 40;
|
||||
if (gCurrentPinballGame->stageTimer == 499)
|
||||
gCurrentPinballGame->boardModeType = 2;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
DrawJirachiSprites();
|
||||
if (gCurrentPinballGame->creatureHitCooldown)
|
||||
gCurrentPinballGame->creatureHitCooldown--;
|
||||
|
||||
if (gCurrentPinballGame->boardModeType && gCurrentPinballGame->eventTimer < 2 && gCurrentPinballGame->boardSubState < 5)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
m4aSongNumStart(MUS_END_OF_BALL2);
|
||||
gCurrentPinballGame->boardSubState = 4;
|
||||
gCurrentPinballGame->stageTimer = 150;
|
||||
gCurrentPinballGame->jirachiCollisionEnabled = 0;
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_evo_item_appear);
|
||||
}
|
||||
return;
|
||||
case 4:
|
||||
if (gCurrentPinballGame->stageTimer)
|
||||
gCurrentPinballGame->stageTimer--;
|
||||
else
|
||||
gCurrentPinballGame->boardSubState = 5;
|
||||
|
||||
DrawJirachiSprites();
|
||||
if (gCurrentPinballGame->creatureHitCooldown)
|
||||
gCurrentPinballGame->creatureHitCooldown--;
|
||||
break;
|
||||
case 5:
|
||||
DrawJirachiSprites();
|
||||
CleanupJirachiSprites();
|
||||
CleanupCatchEmState();
|
||||
gCurrentPinballGame->jirachiActivationFlags = 240;
|
||||
gCurrentPinballGame->boardSubState = 6;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
return;
|
||||
case 6:
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 0;
|
||||
if (gCurrentPinballGame->stageTimer)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->catchLights[2] == 1)
|
||||
RequestBoardStateTransition(3);
|
||||
else
|
||||
RequestBoardStateTransition(1);
|
||||
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//sprite graphics starts here
|
||||
void LoadCatchSpriteGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
s16 catchIndex;
|
||||
const u8 *sp0[3];
|
||||
const u8 *spC[3];
|
||||
|
||||
catchIndex = gSpeciesInfo[gCurrentPinballGame->currentSpecies].catchIndex;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
sp0[i] = gCatchSpriteGfxPtrs[catchIndex / 5][(i + (catchIndex % 5) * 3)];
|
||||
spC[i] = gMonIconPalettes[catchIndex / 5][i * 5 + catchIndex % 5];
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
DmaCopy16(3, sp0[i], &gCatchSpriteGfxBuffer[i * 0x480], 0x480);
|
||||
DmaCopy16(3, spC[i], &gCatchSpritePalettes[i * 0x20], 0x20);
|
||||
}
|
||||
|
||||
DmaCopy16(3, gMonIconPalettes[0][15], &gCatchSpritePalettes[0x60], 0x20);
|
||||
}
|
||||
|
||||
void LoadEggSpriteGraphics(void)
|
||||
{
|
||||
s16 eggIndex;
|
||||
const u8 *src0;
|
||||
const u8 *src1;
|
||||
|
||||
eggIndex= gSpeciesInfo[gCurrentPinballGame->currentSpecies].eggIndex;
|
||||
src0 = gMonHatchSpriteGroupGfx[eggIndex / 6][eggIndex % 6];
|
||||
src1 = gMonHatchSpriteGroupPals[eggIndex / 6][eggIndex % 6];
|
||||
DmaCopy16(3, src0, gCatchSpriteFrameBuffer, 0x10E0);
|
||||
DmaCopy16(3, src1, gCatchSpritePaletteBuffer, 0x20);
|
||||
}
|
||||
|
||||
void DrawCaughtPokemonSprite(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 priority;
|
||||
s16 index;
|
||||
|
||||
index = (gMain.fieldFrameCount % 50) / 25;
|
||||
group = gMain.fieldSpriteGroups[33];
|
||||
if (!group->available)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->jirachiCenterX = 96;
|
||||
gCurrentPinballGame->jirachiCenterY = 288;
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 288 - gCurrentPinballGame->cameraYOffset;
|
||||
if (gCurrentPinballGame->captureFlashTimer > 4)
|
||||
{
|
||||
if (gCurrentPinballGame->captureFlashTimer == 20 || gCurrentPinballGame->captureFlashTimer == 200)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, (void *)0x06010CA0, 0x480);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->captureFlashTimer == 24)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, (void *)0x06010CA0, 0x480);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->captureFlashTimer--;;
|
||||
}
|
||||
else if (gCurrentPinballGame->randomSpriteVariantSeed == 5)
|
||||
{
|
||||
DmaCopy16(3, &gCatchSpriteGfxBuffer[index * 0x480], (void *)0x06010CA0, 0x480);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->captureSequenceTimer < 13)
|
||||
priority = 2;
|
||||
else
|
||||
priority = 1;
|
||||
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
gOamBuffer[oamSimple->oamId].priority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
void CleanupCaughtPokemonSprite(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
|
||||
group = gMain.fieldSpriteGroups[33];
|
||||
if (group->available)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = 200;
|
||||
gOamBuffer[oamSimple->oamId].y = 180;
|
||||
}
|
||||
}
|
||||
|
||||
gMain.fieldSpriteGroups[33]->available = 0;
|
||||
}
|
||||
|
||||
void DrawJirachiSprites(void)
|
||||
{
|
||||
s16 i, j;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const u16 *src;
|
||||
s16 index;
|
||||
s16 priority;
|
||||
s16 var1;
|
||||
|
||||
index = (gMain.fieldFrameCount % 50) / 25;
|
||||
group = gMain.fieldSpriteGroups[33];
|
||||
if (group->available)
|
||||
{
|
||||
gCurrentPinballGame->jirachiCenterX = gCurrentPinballGame->jirachiDisplayX / 10 + 96;
|
||||
gCurrentPinballGame->jirachiCenterY = gCurrentPinballGame->jirachiDisplayY / 10 + 288;
|
||||
group->baseX = gCurrentPinballGame->jirachiDisplayX / 10 + 96u - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->jirachiDisplayY / 10 + 288u - gCurrentPinballGame->cameraYOffset;
|
||||
if (gCurrentPinballGame->boardSubState > 3)
|
||||
{
|
||||
if (gCurrentPinballGame->stageTimer >= 90)
|
||||
{
|
||||
index = (150 - gCurrentPinballGame->stageTimer) / 4;
|
||||
DmaCopy16(3, &gBasketAnimationTilesGfx[index], (void *)0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseY = 190;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->captureFlashTimer > 4)
|
||||
{
|
||||
if (gCurrentPinballGame->captureFlashTimer == 20 || gCurrentPinballGame->captureFlashTimer == 200)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, (void *)0x06010CA0, 0x480);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->captureFlashTimer == 24)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, (void *)0x06010CA0, 0x480);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->captureFlashTimer--;
|
||||
}
|
||||
else if (gCurrentPinballGame->randomSpriteVariantSeed == 5)
|
||||
{
|
||||
DmaCopy16(3, &gCatchSpriteGfxBuffer[index * 0x480], (void *)0x06010CA0, 0x480);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->captureState != 2)
|
||||
{
|
||||
priority = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->captureSequenceTimer < 13)
|
||||
priority = 2;
|
||||
else
|
||||
priority = 1;
|
||||
}
|
||||
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
else if (group->baseY < -60)
|
||||
group->baseY = -60;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
gOamBuffer[oamSimple->oamId].priority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
|
||||
group = gMain.fieldSpriteGroups[45 + j];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->jirachiStarTagPos[j].x - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->jirachiStarTagPos[j].y - gCurrentPinballGame->cameraYOffset;
|
||||
var1 = gJirachiStarFrameIndices[j][9 - gCurrentPinballGame->jirachiTagTimer[j] / 4];
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
else if (group->baseY < -60)
|
||||
group->baseY = -60;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
src = gSapphireFloatOamFramesets[var1][i];
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->captureState != 2 && gCurrentPinballGame->boardSubState < 4)
|
||||
{
|
||||
if (gCurrentPinballGame->jirachiTagTimer[j] == 0)
|
||||
{
|
||||
gCurrentPinballGame->jirachiTagTimer[j] = 40;
|
||||
gCurrentPinballGame->jirachiStarTagPos[j].x = gCurrentPinballGame->jirachiCenterX;
|
||||
gCurrentPinballGame->jirachiStarTagPos[j].y = gCurrentPinballGame->jirachiCenterY + 16;
|
||||
gMain.fieldSpriteGroups[45 + j]->available = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->jirachiTagTimer[j])
|
||||
{
|
||||
gCurrentPinballGame->jirachiTagTimer[j]--;
|
||||
if (gCurrentPinballGame->jirachiTagTimer[j] == 0)
|
||||
gMain.fieldSpriteGroups[45 + j]->available = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CleanupJirachiSprites(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
|
||||
group = gMain.fieldSpriteGroups[33];
|
||||
if (group->available)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = 200;
|
||||
gOamBuffer[oamSimple->oamId].y = 180;
|
||||
}
|
||||
}
|
||||
|
||||
gMain.fieldSpriteGroups[33]->available = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
gMain.fieldSpriteGroups[45 + i]->available = 0;
|
||||
}
|
||||
|
||||
//draw_catch_tiles
|
||||
void CheckHatchTileRevealState(void)
|
||||
{
|
||||
// Cross vertical threshold, check completion
|
||||
if (gCurrentPinballGame->cameraYViewport > 138)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchTileRevealState == HATCH_TILE_REVEAL_NONE && gCurrentPinballGame->hatchTilesBumperAcknowledged > 0)
|
||||
{
|
||||
// Reveal all at once, if the bumpers have been hit enough in one trip up to reveal all tiles
|
||||
// This will be in 'banner' mode at this point, scrolling down, and records points mid sequence
|
||||
if (gCurrentPinballGame->hatchTilesBoardAcknowledged + 6 == gCurrentPinballGame->hatchTilesBumperAcknowledged)
|
||||
{
|
||||
gCurrentPinballGame->hatchTileRevealState = HATCH_TILE_REVEAL_ALL_AT_ONCE;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 300000;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->hatchTileRevealState = HATCH_TILE_REVEAL_ONE_AT_A_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->hatchTilesBoardAcknowledged = gCurrentPinballGame->hatchTilesBumperAcknowledged;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hatchTileRevealState == HATCH_TILE_REVEAL_ALL_AT_ONCE)
|
||||
RevealAllHatchTilesAtOnce();
|
||||
else if (gCurrentPinballGame->hatchTileRevealState == HATCH_TILE_REVEAL_ONE_AT_A_TIME)
|
||||
RevealSequentialHatchTiles();
|
||||
}
|
||||
|
||||
void PlayEggCrackAnimation(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
|
||||
if (gHatchSequentialFrameData[gCurrentPinballGame->hatchFrameId][1] > gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer)
|
||||
{
|
||||
gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer = 0;
|
||||
gCurrentPinballGame->hatchFrameId++;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hatchFrameId == 2 && gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer > 3)
|
||||
{
|
||||
gCurrentPinballGame->portraitDisplayState = 3;
|
||||
gMain.fieldSpriteGroups[33]->available = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hatchFrameId > 2)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpritePalettes, (void *)0x050003A0, 0x20);
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, (void *)0x06010CA0, 0x480);
|
||||
DrawCaughtPokemonSprite();
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[18];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 296 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gSapphireHatchOamFramesets[gHatchSequentialFrameData[gCurrentPinballGame->hatchFrameId][0]][i*3+0];
|
||||
*dst++ = gSapphireHatchOamFramesets[gHatchSequentialFrameData[gCurrentPinballGame->hatchFrameId][0]][i*3+1];
|
||||
*dst++ = gSapphireHatchOamFramesets[gHatchSequentialFrameData[gCurrentPinballGame->hatchFrameId][0]][i*3+2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
gMain.fieldSpriteGroups[18]->available = 1;
|
||||
if (gCurrentPinballGame->hatchFrameId > 6)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gMain.fieldSpriteGroups[18]->available = 0;
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ResetHatchFrameState(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
gCurrentPinballGame->hatchFrameId = 0;
|
||||
for (i = 0; i < 6; i++)
|
||||
gCurrentPinballGame->hatchTilePalette[i] = 13;
|
||||
}
|
||||
|
||||
|
|
@ -9,6 +9,127 @@
|
|||
extern const u16 gWildMonLocations[AREA_COUNT][2][WILD_MON_LOCATION_COUNT];
|
||||
extern const u16 gEggLocations[MAIN_FIELD_COUNT][26];
|
||||
|
||||
/**
|
||||
* 0 if captured via ball
|
||||
* 1 if evolved
|
||||
*/
|
||||
void RegisterCaptureOrEvolution(s16 evolved)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
if (!evolved)
|
||||
{
|
||||
if (gMain.mainState != STATE_GAME_IDLE)
|
||||
SaveFile_SetPokedexFlags(gCurrentPinballGame->currentSpecies, SPECIES_CAUGHT);
|
||||
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionMethod != 0)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionTarget < SPECIES_NONE)
|
||||
{
|
||||
if (gCurrentPinballGame->evolvablePartySize < MAX_EVOLVABLE_PARTY_SIZE)
|
||||
{
|
||||
gCurrentPinballGame->evolvablePartySpecies[gCurrentPinballGame->evolvablePartySize] =
|
||||
gCurrentPinballGame->currentSpecies;
|
||||
|
||||
gCurrentPinballGame->evolvablePartySize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_EVOLVABLE_PARTY_SIZE; i++)
|
||||
gCurrentPinballGame->evolvablePartySpecies[i] = gCurrentPinballGame->evolvablePartySpecies[i + 1];
|
||||
|
||||
gCurrentPinballGame->evolvablePartySpecies[MAX_EVOLVABLE_PARTY_SIZE - 1] = gCurrentPinballGame->currentSpecies;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->evolvablePartySize--;
|
||||
|
||||
for (i = gCurrentPinballGame->evolvingPartyIndex; i < gCurrentPinballGame->evolvablePartySize; i++)
|
||||
gCurrentPinballGame->evolvablePartySpecies[i] = gCurrentPinballGame->evolvablePartySpecies[i + 1];
|
||||
|
||||
if (gCurrentPinballGame->currentSpecies == SPECIES_WURMPLE)
|
||||
{
|
||||
if ((gMain.systemFrameCount & 1) == 0)
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_SILCOON] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_SILCOON;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_CASCOON;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_CASCOON] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_CASCOON;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_SILCOON;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_GLOOM)
|
||||
{
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_VILEPLUME;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_BELLOSSOM;
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_CLAMPERL)
|
||||
{
|
||||
if ((gMain.systemFrameCount & 1) == 0)
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_HUNTAIL] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_HUNTAIL;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_GOREBYSS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_GOREBYSS] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_GOREBYSS;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_HUNTAIL;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_NINCADA)
|
||||
{
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_SHEDINJA;
|
||||
if (gMain.mainState != STATE_GAME_IDLE)
|
||||
SaveFile_SetPokedexFlags(SPECIES_SHEDINJA, SPECIES_CAUGHT);
|
||||
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_NINJASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->currentSpecies =
|
||||
gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionTarget;
|
||||
}
|
||||
|
||||
if (gMain.mainState != STATE_GAME_IDLE)
|
||||
SaveFile_SetPokedexFlags(gCurrentPinballGame->currentSpecies, SPECIES_CAUGHT);
|
||||
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionMethod != 0)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionTarget < SPECIES_NONE)
|
||||
{
|
||||
if (gCurrentPinballGame->evolvablePartySize < MAX_EVOLVABLE_PARTY_SIZE)
|
||||
{
|
||||
gCurrentPinballGame->evolvablePartySpecies[gCurrentPinballGame->evolvablePartySize] =
|
||||
gCurrentPinballGame->currentSpecies;
|
||||
gCurrentPinballGame->evolvablePartySize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_EVOLVABLE_PARTY_SIZE; i++)
|
||||
gCurrentPinballGame->evolvablePartySpecies[i] = gCurrentPinballGame->evolvablePartySpecies[i + 1];
|
||||
|
||||
gCurrentPinballGame->evolvablePartySpecies[MAX_EVOLVABLE_PARTY_SIZE - 1] = gCurrentPinballGame->currentSpecies;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 GetTimeAdjustedRandom()
|
||||
{
|
||||
return Random() + (gMain.systemFrameCount + gMain.fieldFrameCount);
|
||||
|
|
|
|||
380
src/catch_tile_logic.c
Normal file
380
src/catch_tile_logic.c
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern const s16 gHatchSequentialTileFramesetData[][2];
|
||||
extern const u16 gHatchSequentialTileBreakSpritesheetOam[28][18];
|
||||
extern const s16 gHatchRevealSparkleTimings[];
|
||||
extern const u16 gHatchRevealOamFramesets[16][18];
|
||||
extern const u8 gHatchRevealPalette[];
|
||||
extern const u16 gHatchFullRevealOamFramesets[18][18];
|
||||
extern const u8 gHatchRevealTilesGfx[];
|
||||
extern const s16 gHatchRevealFinalTimings[];
|
||||
extern const u8 gHatchFinalTilesGfx[];
|
||||
extern const u8 gHatchFinalPalette[];
|
||||
extern const u16 gHatchSequentialOamFramesets[22][12];
|
||||
|
||||
extern const u8 gHatchStartTilesGfx[];
|
||||
extern const u8 gHatchStartPalette[];
|
||||
extern const u8 gHatchStage2TilesGfx[];
|
||||
extern const u8 gHatchStage2Palette[];
|
||||
extern const u8 gHatchStage3TilesGfx[];
|
||||
extern const u8 gHatchStage3Palette[];
|
||||
|
||||
|
||||
void DisableHatchTileDisplay(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
|
||||
group = gMain.fieldSpriteGroups[18];
|
||||
if (group->available)
|
||||
{
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = 200;
|
||||
gOamBuffer[oamSimple->oamId].y = 180;
|
||||
}
|
||||
}
|
||||
gMain.fieldSpriteGroups[18]->available = 0;
|
||||
group = gMain.fieldSpriteGroups[12];
|
||||
if (group->available)
|
||||
{
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = 200;
|
||||
gOamBuffer[oamSimple->oamId].y = 180;
|
||||
}
|
||||
}
|
||||
gMain.fieldSpriteGroups[12]->available = 0;
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
|
||||
void RevealSequentialHatchTiles(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
s16 var0;
|
||||
int var1;
|
||||
|
||||
var1 = 1;
|
||||
gMain.fieldSpriteGroups[18]->available = 1;
|
||||
if (gCurrentPinballGame->hatchFrameId > 0)
|
||||
UpdateSequentialTileParticles();
|
||||
|
||||
if (gCurrentPinballGame->hatchSequentialTilesRevealed < gCurrentPinballGame->hatchTilesBoardAcknowledged)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchFrameId == 0 && gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->activePortraitType = 11;
|
||||
DmaCopy16(3, gHatchRevealPalette, (void *)0x050003C0, 0x20);
|
||||
DmaCopy16(3, gHatchRevealTilesGfx, (void *)0x06015800, 0x2800);
|
||||
}
|
||||
|
||||
if (gHatchSequentialTileFramesetData[gCurrentPinballGame->hatchFrameId][1] > gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer)
|
||||
{
|
||||
gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer = 0;
|
||||
gCurrentPinballGame->hatchFrameId++;
|
||||
if (gCurrentPinballGame->hatchFrameId > 12)
|
||||
{
|
||||
gCurrentPinballGame->hatchSequentialTilesRevealed++;
|
||||
gCurrentPinballGame->hatchFrameId = 0;
|
||||
var1 = 0;
|
||||
gCurrentPinballGame->hatchTilesRemaining--;
|
||||
if (gCurrentPinballGame->hatchSequentialTilesRevealed == gCurrentPinballGame->hatchTilesBoardAcknowledged)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchTilesRemaining >= 0)
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hatchTilesRemaining < 0)
|
||||
{
|
||||
gCurrentPinballGame->hatchTilesBoardAcknowledged = 0;
|
||||
gCurrentPinballGame->hatchSequentialTilesRevealed = 0;
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 0;
|
||||
for (i = 0; i < 6; i++)
|
||||
gCurrentPinballGame->hatchTileShufflePool[i] = i;
|
||||
|
||||
var0 = gMain.systemFrameCount % 6;
|
||||
gCurrentPinballGame->hatchTilesRemaining = 5;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gMain.fieldSpriteGroups[18]->available = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->hatchTilesRemaining == 0)
|
||||
{
|
||||
var0 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 = gMain.systemFrameCount % gCurrentPinballGame->hatchTilesRemaining;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->hatchGridCellIndex = gCurrentPinballGame->hatchTileShufflePool[var0];
|
||||
for (i = var0; i < gCurrentPinballGame->hatchTilesRemaining; i++)
|
||||
gCurrentPinballGame->hatchTileShufflePool[i] = gCurrentPinballGame->hatchTileShufflePool[i + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->hatchFrameId == 1)
|
||||
gCurrentPinballGame->hatchTilePalette[gCurrentPinballGame->hatchGridCellIndex] = 13;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var1 = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hatchFrameId == 1)
|
||||
{
|
||||
m4aSongNumStart(SE_CATCH_TILE_REVEAL);
|
||||
InitSequentialTileParticles();
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hatchFrameId == 12)
|
||||
var1 = 0;
|
||||
|
||||
group = gMain.fieldSpriteGroups[18];
|
||||
if (var1)
|
||||
{
|
||||
group->baseX = (gCurrentPinballGame->hatchGridCellIndex % 3) * 16 - (gCurrentPinballGame->cameraXOffset - 96);
|
||||
group->baseY = (gCurrentPinballGame->hatchGridCellIndex / 3) * 16 - (gCurrentPinballGame->cameraYOffset - 300);
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseY = 200;
|
||||
}
|
||||
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gHatchSequentialTileBreakSpritesheetOam[gHatchSequentialTileFramesetData[gCurrentPinballGame->hatchFrameId][0]][i * 3 + 0];
|
||||
*dst++ = gHatchSequentialTileBreakSpritesheetOam[gHatchSequentialTileFramesetData[gCurrentPinballGame->hatchFrameId][0]][i * 3 + 1];
|
||||
*dst++ = gHatchSequentialTileBreakSpritesheetOam[gHatchSequentialTileFramesetData[gCurrentPinballGame->hatchFrameId][0]][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].priority = 3;
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
void RevealAllHatchTilesAtOnce(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
s16 var0;
|
||||
|
||||
switch (gCurrentPinballGame->hatchRevealPhase)
|
||||
{
|
||||
case 0:
|
||||
if (gCurrentPinballGame->revealAnimFrameCounter < 60)
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
}
|
||||
gMain.blendControl = 0xCE;
|
||||
break;
|
||||
case 1:
|
||||
gCurrentPinballGame->activePortraitType = 5;
|
||||
DmaCopy16(3, gHatchStartTilesGfx, (void *)0x06015800, 0x2000);
|
||||
DmaCopy16(3, gHatchStartPalette, (void *)0x050003C0, 0x20);
|
||||
gMain.fieldSpriteGroups[35]->available = 1;
|
||||
m4aSongNumStart(SE_CATCH_ALL_REVEAL_LIGHTNING);
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (gHatchRevealSparkleTimings[gCurrentPinballGame->revealFramesetIndex] > gCurrentPinballGame->revealAnimFrameCounter)
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex++;
|
||||
if (gCurrentPinballGame->revealFramesetIndex > 7)
|
||||
{
|
||||
gCurrentPinballGame->revealFramesetIndex = 7;
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
gMain.fieldSpriteGroups[35]->available = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->revealFramesetIndex;
|
||||
group = gMain.fieldSpriteGroups[35];
|
||||
group->baseX = 124 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 244 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gHatchRevealOamFramesets[var0][i * 3 + 0];
|
||||
*dst++ = gHatchRevealOamFramesets[var0][i * 3 + 1];
|
||||
*dst++ = gHatchRevealOamFramesets[var0][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
gCurrentPinballGame->activePortraitType = 6;
|
||||
DmaCopy16(3, gHatchStage2TilesGfx, (void *)0x06015800, 0x800);
|
||||
DmaCopy16(3, gHatchStage2Palette, (void *)0x050003C0, 0x20);
|
||||
gMain.fieldSpriteGroups[36]->available = 1;
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->startButtonDisabled = 1;
|
||||
break;
|
||||
case 4:
|
||||
var0 = gCurrentPinballGame->revealAnimFrameCounter / 2;
|
||||
if (gCurrentPinballGame->revealAnimFrameCounter < 15)
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gMain.fieldSpriteGroups[36]->available = 0;
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex = 0;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[36];
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 300 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gHatchFullRevealOamFramesets[var0][i * 3 + 0];
|
||||
*dst++ = gHatchFullRevealOamFramesets[var0][i * 3 + 1];
|
||||
*dst++ = gHatchFullRevealOamFramesets[var0][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
gCurrentPinballGame->activePortraitType = 7;
|
||||
DmaCopy16(3, gHatchStage3TilesGfx, (void *)0x06015800, 0x2000);
|
||||
DmaCopy16(3, gHatchStage3Palette, (void *)0x050003C0, 0x20);
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
InitBurstTileParticles();
|
||||
m4aSongNumStart(SE_CATCH_ALL_REVEAL_SHATTER);
|
||||
break;
|
||||
case 6:
|
||||
gMain.blendBrightness = 0;
|
||||
gMain.blendControl = ((REG_DISPCNT & (DISPCNT_OBJ_ON | DISPCNT_BG_ALL_ON)) >> 8) | 0xA0;
|
||||
if (gCurrentPinballGame->revealAnimFrameCounter < 73)
|
||||
{
|
||||
s16 var1;
|
||||
if (gCurrentPinballGame->revealAnimFrameCounter < 8)
|
||||
{
|
||||
gMain.blendBrightness = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 6; i++)
|
||||
gCurrentPinballGame->hatchTilePalette[i] = 13;
|
||||
|
||||
gMain.blendBrightness = ((8 - gCurrentPinballGame->revealAnimFrameCounter) / 4) + 16;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->revealAnimFrameCounter < 72)
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->revealAnimFrameCounter > 8U)
|
||||
{
|
||||
if (gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer < 0x7000)
|
||||
UpdateBurstTileParticles();
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
gCurrentPinballGame->activePortraitType = 8;
|
||||
DmaCopy16(3, gHatchFinalTilesGfx, (void *)0x06015800, 0x1800);
|
||||
DmaCopy16(3, gHatchFinalPalette, (void *)0x050003C0, 0x20);
|
||||
gMain.fieldSpriteGroups[37]->available = 1;
|
||||
gCurrentPinballGame->hatchRevealPhase++;
|
||||
gCurrentPinballGame->startButtonDisabled = 0;
|
||||
break;
|
||||
case 8:
|
||||
if (gHatchRevealFinalTimings[gCurrentPinballGame->revealFramesetIndex] > gCurrentPinballGame->revealAnimFrameCounter)
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex++;
|
||||
if (gCurrentPinballGame->revealFramesetIndex > 10)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gMain.fieldSpriteGroups[37]->available = 0;
|
||||
gCurrentPinballGame->hatchTilesBoardAcknowledged = 0;
|
||||
gCurrentPinballGame->hatchSequentialTilesRevealed = 0;
|
||||
gCurrentPinballGame->hatchTilesBumperAcknowledged = 0;
|
||||
gMain.blendControl = 0xCE;
|
||||
gMain.blendBrightness = 0;
|
||||
gMain.fieldSpriteGroups[37]->available = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex = 10;
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->revealFramesetIndex;
|
||||
group = gMain.fieldSpriteGroups[37];
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 300 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gHatchSequentialOamFramesets[var0][i * 3 + 0];
|
||||
*dst++ = gHatchSequentialOamFramesets[var0][i * 3 + 1];
|
||||
*dst++ = gHatchSequentialOamFramesets[var0][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
178
src/catch_tile_particles.c
Normal file
178
src/catch_tile_particles.c
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
extern const s16 gHatchRevealPieceIndices[][16];
|
||||
extern const s16 gHatchPieceVelocities[][2];
|
||||
extern const s16 gHatchPieceAffineModes[];
|
||||
extern const s16 gHatchPieceMatrixNums[6];
|
||||
extern const s16 gHatchPieceAnimIndices[][12];
|
||||
extern const u16 gHatchParticleOamAttributes[][3];
|
||||
extern const u16 gHatchAnimOamAttributes[][3];
|
||||
|
||||
void InitSequentialTileParticles(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
gCurrentPinballGame->tileParticlePos[i].x = 0;
|
||||
gCurrentPinballGame->tileParticlePos[i].y = 0;
|
||||
gCurrentPinballGame->tileParticleVel[i].x = 200 - (Random() % 400);
|
||||
gCurrentPinballGame->tileParticleVel[i].y = 80 - (Random() % 550);
|
||||
gCurrentPinballGame->tileParticleGravity[i] = 10 + (Random() % 15);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->particleAnimTimer = 0;
|
||||
gMain.fieldSpriteGroups[12]->available = 1;
|
||||
}
|
||||
|
||||
void UpdateSequentialTileParticles(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const u16 *src;
|
||||
s16 var0;
|
||||
struct Vector16 tempVector;
|
||||
|
||||
group = gMain.fieldSpriteGroups[12];
|
||||
if (group->available)
|
||||
{
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
var0 = gHatchPieceAnimIndices[i][gCurrentPinballGame->particleAnimTimer / 4];
|
||||
gCurrentPinballGame->tileParticleVel[i].y += gCurrentPinballGame->tileParticleGravity[i];
|
||||
if (gCurrentPinballGame->tileParticlePos[i].y < 14000)
|
||||
{
|
||||
gCurrentPinballGame->tileParticlePos[i].x += gCurrentPinballGame->tileParticleVel[i].x;
|
||||
gCurrentPinballGame->tileParticlePos[i].y += gCurrentPinballGame->tileParticleVel[i].y;
|
||||
}
|
||||
|
||||
tempVector.x = ((gCurrentPinballGame->hatchGridCellIndex % 3) * 16 + 96u - gCurrentPinballGame->cameraXOffset) + (gCurrentPinballGame->tileParticlePos[i].x / 100);
|
||||
tempVector.y = ((gCurrentPinballGame->hatchGridCellIndex / 3) * 16 + 300u - gCurrentPinballGame->cameraYOffset) + (gCurrentPinballGame->tileParticlePos[i].y / 100);
|
||||
if (tempVector.y >= 200)
|
||||
tempVector.y = 200;
|
||||
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gHatchAnimOamAttributes[var0][0];
|
||||
*dst++ = gHatchAnimOamAttributes[var0][1];
|
||||
*dst++ = gHatchAnimOamAttributes[var0][2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += tempVector.x;
|
||||
gOamBuffer[oamSimple->oamId].y += tempVector.y;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->particleAnimTimer < 48)
|
||||
{
|
||||
gCurrentPinballGame->particleAnimTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer = 0x7100;
|
||||
gMain.fieldSpriteGroups[12]->available = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void InitBurstTileParticles(void)
|
||||
{
|
||||
s16 i;
|
||||
const struct Vector16 *var0;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
gCurrentPinballGame->tileParticlePos[i].x = ((i % 3) * 16 - 24) * 100;
|
||||
gCurrentPinballGame->tileParticlePos[i].y = ((i / 3) * 16 - 28) * 100;
|
||||
gCurrentPinballGame->tileParticleVel[i].x = gHatchPieceVelocities[i][0] - ((Random() % 200) - 60);
|
||||
gCurrentPinballGame->tileParticleVel[i].y = gHatchPieceVelocities[i][1] - ((Random() % 200) - 60);
|
||||
gCurrentPinballGame->tileParticleGravity[i] = (Random() % 4) + 1;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->tileParticlePos[0].x = -5600;
|
||||
gCurrentPinballGame->tileParticlePos[0].y = -6000;
|
||||
gCurrentPinballGame->tileParticleGravity[0] = 3;
|
||||
gCurrentPinballGame->tileParticlePos[4].x = -4000;
|
||||
gCurrentPinballGame->tileParticlePos[4].y = -4400;
|
||||
gCurrentPinballGame->tileParticleGravity[4] = 3;
|
||||
gCurrentPinballGame->particleAnimTimer = 0;
|
||||
gMain.fieldSpriteGroups[12]->available = 1;
|
||||
}
|
||||
|
||||
void UpdateBurstTileParticles(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
s16 index;
|
||||
struct Vector16 tempVector;
|
||||
s16 sp0[6];
|
||||
s16 scale;
|
||||
|
||||
group = gMain.fieldSpriteGroups[12];
|
||||
if (group->available)
|
||||
{
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
index = gCurrentPinballGame->particleAnimTimer / 5;
|
||||
sp0[i] = gHatchRevealPieceIndices[i][index];
|
||||
if (gCurrentPinballGame->particleAnimTimer > 4)
|
||||
{
|
||||
gCurrentPinballGame->tileParticleVel[i].y += gCurrentPinballGame->tileParticleGravity[i];
|
||||
if (i == 4)
|
||||
gCurrentPinballGame->tileParticleVel[i].x += gCurrentPinballGame->tileParticleGravity[4] * 4;
|
||||
|
||||
gCurrentPinballGame->tileParticlePos[i].x += gCurrentPinballGame->tileParticleVel[i].x;
|
||||
gCurrentPinballGame->tileParticlePos[i].y += gCurrentPinballGame->tileParticleVel[i].y;
|
||||
}
|
||||
|
||||
tempVector.x = (gCurrentPinballGame->tileParticlePos[i].x / 100) + 96u - gCurrentPinballGame->cameraXOffset;
|
||||
tempVector.y = (gCurrentPinballGame->tileParticlePos[i].y / 100) + 304u - gCurrentPinballGame->cameraYOffset;
|
||||
if (tempVector.y >= 160)
|
||||
tempVector.y = 160;
|
||||
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gHatchParticleOamAttributes[sp0[i]][0];
|
||||
*dst++ = gHatchParticleOamAttributes[sp0[i]][1];
|
||||
*dst++ = gHatchParticleOamAttributes[sp0[i]][2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += tempVector.x;
|
||||
gOamBuffer[oamSimple->oamId].y += tempVector.y;
|
||||
gOamBuffer[oamSimple->oamId].affineMode = gHatchPieceAffineModes[i];
|
||||
gOamBuffer[oamSimple->oamId].matrixNum = gHatchPieceMatrixNums[i];
|
||||
}
|
||||
}
|
||||
|
||||
scale = ((gCurrentPinballGame->particleAnimTimer * gCurrentPinballGame->particleAnimTimer * 0xD0) / 0x510) + 0x80;
|
||||
if (sp0[0] == 4)
|
||||
scale = -scale;
|
||||
SetMatrixScale(scale, scale, 2);
|
||||
|
||||
scale = 0x80;
|
||||
if (sp0[1] == 4)
|
||||
scale = -scale;
|
||||
SetMatrixScale(scale, scale, 3);
|
||||
|
||||
scale = ((gCurrentPinballGame->particleAnimTimer * gCurrentPinballGame->particleAnimTimer * 0x100) / 0x510) + 0x80;
|
||||
if (sp0[3] == 4)
|
||||
scale = -scale;
|
||||
SetMatrixScale(scale, scale, 4);
|
||||
|
||||
scale = ((gCurrentPinballGame->particleAnimTimer * gCurrentPinballGame->particleAnimTimer * 0x1C0) / 0x510) + 0x40;
|
||||
if (sp0[4]== 4)
|
||||
scale = -scale;
|
||||
SetMatrixScale(scale, scale, 5);
|
||||
|
||||
if (gCurrentPinballGame->particleAnimTimer < 47)
|
||||
{
|
||||
gCurrentPinballGame->particleAnimTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->hatchSequentialTileRevealFrameAnimTimer = 0x7100;
|
||||
gMain.fieldSpriteGroups[12]->available = 0;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
228
src/collision_dusclops.c
Normal file
228
src/collision_dusclops.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "constants/dusclops_states.h"
|
||||
|
||||
s16 CollisionCheck_Dusclops(struct Vector16* arg0, u16* arg1) {
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
u16 return_val;
|
||||
s16 collisionTileIndex;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
|
||||
u32 some_enum;
|
||||
u32 switch_enum;
|
||||
|
||||
return_val = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
collisionTileIndex = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
|
||||
CheckDusclopsEntitiesCollision(arg0, &sp00, &sp02);
|
||||
switch_enum = sp02 & 0xF;
|
||||
some_enum = sp02 >> 4;
|
||||
|
||||
switch (switch_enum)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 6:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00;
|
||||
if (*arg1 >= 0x3FF0 && *arg1 <= 0x4010)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < gBoardConfig.fieldLayout.ballSpawnX - 8 ||
|
||||
gCurrentPinballGame->ball->positionQ0.y < gBoardConfig.fieldLayout.ballSpawnY - 8)
|
||||
{
|
||||
|
||||
if (gCurrentPinballGame->ball->spinSpeed > 0)
|
||||
{
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->spinSpeed != 0)
|
||||
{
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain.systemFrameCount & 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0x28;
|
||||
gCurrentPinballGame->ball->spinSpeed = 1;
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0xFFD8;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0xFFFF;
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return_val = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg1 = sp00 & 0x0000FFF0;
|
||||
return_val = 1;
|
||||
break;
|
||||
case 5:
|
||||
some_enum = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
CheckDusclopsAbsorbZoneHit(some_enum, &return_val, arg1);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void CheckDusclopsEntitiesCollision(struct Vector16 *arg0, s16* arg1, u8* arg2) {
|
||||
s16 deltaX;
|
||||
s16 deltaY;
|
||||
u16 maskedResult;
|
||||
u8 lowerNibble;
|
||||
u8 temp;
|
||||
|
||||
maskedResult = 0;
|
||||
lowerNibble = 0;
|
||||
|
||||
if(gCurrentPinballGame->boardEntityCollisionMode == DUSCLOPS_ENTITY_COLLISION_MODE_DUSCLOPS)
|
||||
{
|
||||
if (*arg2 != 0)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x -gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y -gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if (deltaX > 95U || deltaY > 119U)
|
||||
return;
|
||||
|
||||
maskedResult = 0xFFF0 & gDusclopsBodyCollisionMap[(deltaY * 96 ) + deltaX];
|
||||
lowerNibble = 0xF & gDusclopsBodyCollisionMap[(deltaY * 96 ) + deltaX];
|
||||
|
||||
if (lowerNibble == 0)
|
||||
return;
|
||||
|
||||
//Can be hit when ready to absorb (2) or when walking (3)
|
||||
temp = gCurrentPinballGame->bossEntityState -3;
|
||||
if (temp <= 1U)
|
||||
*arg2 = 1;
|
||||
else
|
||||
*arg2 = lowerNibble;
|
||||
|
||||
gCurrentPinballGame->bossEntityState = DUSCLOPS_ENTITY_STATE_HIT;
|
||||
*arg1 = maskedResult;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(gCurrentPinballGame->boardEntityCollisionMode == DUSCLOPS_ENTITY_COLLISION_MODE_DUSKULL)
|
||||
{
|
||||
if (*arg2 != 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->minionCanCollide[0] )
|
||||
{
|
||||
deltaX = arg0->x - gCurrentPinballGame->minionCollisionPosition[0].x;
|
||||
deltaY = arg0->y - gCurrentPinballGame->minionCollisionPosition[0].y;
|
||||
|
||||
if (deltaX < 64U && deltaY < 64U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[deltaY * 64 + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[deltaY * 64 + deltaX];
|
||||
|
||||
if (lowerNibble != 0)
|
||||
gCurrentPinballGame->minionState[0] = DUSKULL_ENTITY_STATE_HIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (lowerNibble == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->minionCanCollide[1] )
|
||||
{
|
||||
deltaX = arg0->x - gCurrentPinballGame->minionCollisionPosition[1].x;
|
||||
deltaY = arg0->y - gCurrentPinballGame->minionCollisionPosition[1].y;
|
||||
|
||||
if (deltaX < 64U && deltaY < 64U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[deltaY * 64 + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[deltaY * 64 + deltaX];
|
||||
|
||||
if (lowerNibble != 0)
|
||||
gCurrentPinballGame->minionState[1] = DUSKULL_ENTITY_STATE_HIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lowerNibble == 0)
|
||||
{
|
||||
if ( gCurrentPinballGame->minionCanCollide[2] )
|
||||
{
|
||||
deltaX = arg0->x - gCurrentPinballGame->minionCollisionPosition[2].x;
|
||||
deltaY = arg0->y - gCurrentPinballGame->minionCollisionPosition[2].y;
|
||||
|
||||
if (deltaX < 64U && deltaY < 64U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[deltaY * 64 + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[deltaY * 64 + deltaX];
|
||||
|
||||
if (lowerNibble != 0)
|
||||
{
|
||||
gCurrentPinballGame->minionState[2] = DUSKULL_ENTITY_STATE_HIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lowerNibble != 0)
|
||||
{
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = 6;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckDusclopsAbsorbZoneHit(u8 arg0, u16 *arg1, u16 *arg2)
|
||||
{
|
||||
switch (arg0)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->bossEntityState = DUSCLOPS_ENTITY_STATE_HIT_ABSORB_ZONE;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
gCurrentPinballGame->boardEntityCollisionMode = DUSCLOPS_ENTITY_COLLISION_MODE_NONE;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
203
src/collision_groudon.c
Normal file
203
src/collision_groudon.c
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
s16 CollisionCheck_Groudon(struct Vector16 *arg0, u16 *arg1)
|
||||
{
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
u16 return_val;
|
||||
u32 some_enum;
|
||||
u32 switch_enum;
|
||||
|
||||
return_val = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
|
||||
if (arg0->y < 0x200)
|
||||
{
|
||||
s16 r2;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
r2 = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][r2 * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][r2 * 64 + vec2.y * 8 + vec2.x];
|
||||
}
|
||||
else
|
||||
{
|
||||
sp00 = 0;
|
||||
sp02 = 0;
|
||||
}
|
||||
|
||||
CheckGroudonEntityCollision(arg0, &sp00, &sp02);
|
||||
switch_enum = sp02 & 0xF;
|
||||
some_enum = sp02 >> 4;
|
||||
|
||||
switch (switch_enum)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 6:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00;
|
||||
if (*arg1 >= 0x3FF0 && *arg1 <= 0x4010)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < (gBoardConfig.fieldLayout.ballSpawnX - 8) || gCurrentPinballGame->ball->positionQ0.y < gBoardConfig.fieldLayout.ballSpawnY - 8)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->spinSpeed > 0)
|
||||
{
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->spinSpeed != 0)
|
||||
{
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain.systemFrameCount & 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 40;
|
||||
gCurrentPinballGame->ball->spinSpeed = 1;
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = -40;
|
||||
gCurrentPinballGame->ball->spinSpeed = -1;
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return_val = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg1 = sp00 & 0xFFF0;
|
||||
return_val = 1;
|
||||
break;
|
||||
case 5:
|
||||
some_enum = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessGroudonCollisionEvent(some_enum, &return_val, arg1);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void CheckGroudonEntityCollision(struct Vector16 *arg0, u16 *arg1, u8 *arg2)
|
||||
{
|
||||
s16 deltaX;
|
||||
s16 deltaY;
|
||||
u16 resultFromArray;
|
||||
u16 maskedResult;
|
||||
u16 lowerNibble;
|
||||
s16 i;
|
||||
|
||||
if (gCurrentPinballGame->boardEntityCollisionMode == 1)
|
||||
{
|
||||
if ((*arg2 & 0xF) == 0)
|
||||
{
|
||||
deltaX = arg0->x - gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y - gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if ((deltaX >= 0 && deltaX < 0x70) && (deltaY >= 0 && deltaY < 0x80))
|
||||
{
|
||||
resultFromArray = gGroudonBodyCollisionMap[(deltaY * 0x70) + deltaX];
|
||||
maskedResult = resultFromArray & 0xFFF0;
|
||||
lowerNibble = resultFromArray & 0xF;
|
||||
if (lowerNibble != 0)
|
||||
{
|
||||
if (gCurrentPinballGame->bossHitFlashTimer == 0)
|
||||
gCurrentPinballGame->bossHitFlashTimer = 0x27;
|
||||
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = lowerNibble;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->boulderCollisionPos[i].x <= 0)
|
||||
continue;
|
||||
if ((*arg2 & 0xF) != 0)
|
||||
continue;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->boulderCollisionPos[i].x;
|
||||
deltaY = arg0->y - gCurrentPinballGame->boulderCollisionPos[i].y;
|
||||
|
||||
if ((deltaX < 0 || deltaX >= 0x50) || (deltaY < 0 || deltaY >= 0x50))
|
||||
continue;
|
||||
|
||||
maskedResult = gGroudonProjectileCollisionMap[(deltaY * 0x50) + deltaX] & 0xFFF0;
|
||||
lowerNibble = gGroudonProjectileCollisionMap[(deltaY * 0x50) + deltaX] & 0xF;
|
||||
|
||||
if (lowerNibble == 0)
|
||||
continue;
|
||||
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = 6;
|
||||
gCurrentPinballGame->boulderHitFlag[i] = 1;
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->firePillarCollisionPos[i].x <= 0)
|
||||
continue;
|
||||
if ((*arg2 & 0xF) != 0)
|
||||
continue;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->firePillarCollisionPos[i].x;
|
||||
deltaY = arg0->y - gCurrentPinballGame->firePillarCollisionPos[i].y;
|
||||
|
||||
if ((deltaX < 0 || deltaX >= 0x50) || (deltaY < 0 || deltaY >= 0x50))
|
||||
continue;
|
||||
|
||||
maskedResult = gGroudonProjectileCollisionMap[(deltaY * 0x50) + deltaX] & 0xFFF0;
|
||||
lowerNibble = gGroudonProjectileCollisionMap[(deltaY * 0x50) + deltaX] & 0xF;
|
||||
|
||||
if (lowerNibble == 0)
|
||||
continue;
|
||||
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = 6;
|
||||
gCurrentPinballGame->firePillarHitTimer[i] = 8;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessGroudonCollisionEvent(u8 arg0, u16 *arg1, u16 *arg2)
|
||||
{
|
||||
switch (arg0)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->bossEntityState = 6;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
break;
|
||||
}
|
||||
}
|
||||
412
src/collision_kecleon.c
Normal file
412
src/collision_kecleon.c
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
#include "global.h"
|
||||
|
||||
s16 CollisionCheck_Kecleon(struct Vector16 *arg0, u16 *arg1)
|
||||
{
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
u16 return_val;
|
||||
s16 collisionTileIndex;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
|
||||
u32 some_enum;
|
||||
u32 switch_enum;
|
||||
|
||||
return_val = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
collisionTileIndex = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
|
||||
CheckKecleonEntityCollision(arg0, &sp00, &sp02);
|
||||
switch_enum = sp02 & 0xF;
|
||||
some_enum = sp02 >> 4;
|
||||
|
||||
switch (switch_enum)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 6:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00;
|
||||
return_val = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00 & 0x0000FFF0;
|
||||
return_val = 1;
|
||||
if (gCurrentPinballGame->kecleonBoardHitState == 0)
|
||||
{
|
||||
s32 kecleonActive = gCurrentPinballGame->kecleonTargetActive;
|
||||
if (kecleonActive == 0)
|
||||
{
|
||||
gCurrentPinballGame->kecleonBoardHitState = 1;
|
||||
gCurrentPinballGame->kecleonCollisionX = kecleonActive;
|
||||
}
|
||||
}
|
||||
gCurrentPinballGame->kecleonCollisionY = 40;
|
||||
break;
|
||||
case 5:
|
||||
some_enum = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessKecleonCollisionEvent(some_enum, &return_val, arg1);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void CheckKecleonEntityCollision(struct Vector16 *arg0, u16 *arg1, u8 *arg2)
|
||||
{
|
||||
s16 deltaX;
|
||||
s16 deltaY;
|
||||
u16 arrayValue;
|
||||
|
||||
if (gCurrentPinballGame->boardEntityCollisionMode == 1)
|
||||
{
|
||||
if (*arg2 & 0xF)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y - gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if ((deltaX < 0 || deltaX > 0x3F) || (deltaY < 0 || deltaY > 0x57))
|
||||
return;
|
||||
|
||||
arrayValue = (u8)(gKecleonTongueCollisionMap[(deltaY * 0x40) + deltaX]) & 0xF;
|
||||
|
||||
if (arrayValue == 0)
|
||||
return;
|
||||
if (gCurrentPinballGame->ball->ballHidden != 0)
|
||||
return;
|
||||
if (gCurrentPinballGame->bossEntityState > 8)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bossEntityState = 9;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardEntityCollisionMode == 2)
|
||||
{
|
||||
u16 maskedResult;
|
||||
|
||||
if (*arg2 & 0xF)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y - gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if ((deltaX < 0 || deltaX > 0x57) || (deltaY < 0 || deltaY > 0x3F))
|
||||
return;
|
||||
|
||||
maskedResult = gKecleonBodyCollisionMap[(deltaY * 0x58) + deltaX] & 0xFFF0;
|
||||
arrayValue = gKecleonBodyCollisionMap[(deltaY * 0x58) + deltaX] & 0xF;
|
||||
|
||||
if (arrayValue == 0)
|
||||
return;
|
||||
if (gCurrentPinballGame->ball->ballHidden != 0)
|
||||
return;
|
||||
if (gCurrentPinballGame->bossEntityState == 12)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bossEntityState = 11;
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = 6;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessKecleonCollisionEvent(u8 arg0, u16 *arg1, u16 *arg2)
|
||||
{
|
||||
s16 x, y;
|
||||
x = gCurrentPinballGame->ball->positionQ0.x;
|
||||
y = gCurrentPinballGame->ball->positionQ0.y;
|
||||
|
||||
switch (arg0)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return;
|
||||
case 8:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (y <= 0x38)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[0] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[0] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[1] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[1] = 0x18;
|
||||
}
|
||||
}
|
||||
else if (y <= 0x63)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[3] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[3] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[2] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[2] = 0x18;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[7] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[7] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[5] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[5] = 0x18;
|
||||
}
|
||||
}
|
||||
else if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[8] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[8] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[0] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[0] = 0x18;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (gCurrentPinballGame->kecleonHitboxX == 0)
|
||||
{
|
||||
gCurrentPinballGame->kecleonHitSparkTimer[0] = 0xB;
|
||||
gCurrentPinballGame->ballTrailPosition[0].x = gCurrentPinballGame->ball->positionQ0.x - 7;
|
||||
gCurrentPinballGame->ballTrailPosition[0].y = gCurrentPinballGame->ball->positionQ0.y - 7;
|
||||
}
|
||||
else if (gCurrentPinballGame->kecleonHitboxX == 3)
|
||||
{
|
||||
gCurrentPinballGame->kecleonHitSparkTimer[1] = 0xB;
|
||||
gCurrentPinballGame->ballTrailPosition[1].x = gCurrentPinballGame->ball->positionQ0.x - 7;
|
||||
gCurrentPinballGame->ballTrailPosition[1].y = gCurrentPinballGame->ball->positionQ0.y - 7;
|
||||
}
|
||||
else if (gCurrentPinballGame->kecleonHitboxX == 6)
|
||||
{
|
||||
gCurrentPinballGame->kecleonHitSparkTimer[2] = 0xB;
|
||||
gCurrentPinballGame->ballTrailPosition[2].x = gCurrentPinballGame->ball->positionQ0.x - 7;
|
||||
gCurrentPinballGame->ballTrailPosition[2].y = gCurrentPinballGame->ball->positionQ0.y - 7;
|
||||
}
|
||||
else if (gCurrentPinballGame->kecleonHitboxX == 9)
|
||||
{
|
||||
gCurrentPinballGame->kecleonHitSparkTimer[3] = 0xB;
|
||||
gCurrentPinballGame->ballTrailPosition[3].x = gCurrentPinballGame->ball->positionQ0.x - 7;
|
||||
gCurrentPinballGame->ballTrailPosition[3].y = gCurrentPinballGame->ball->positionQ0.y - 7;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[9] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[9] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[2] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[2] = 0x18;
|
||||
}
|
||||
}
|
||||
else if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[6] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[6] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[1] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[1] = 0x18;
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[4] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[4] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[3] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[3] = 0x18;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckKecleonProjectileCollision(struct Vector16 *arg0)
|
||||
{
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
s16 x, y;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
s16 collisionTileIndex;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
u32 some_enum;
|
||||
|
||||
gCurrentPinballGame->kecleonCollisionEnabled = 1;
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
collisionTileIndex = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
|
||||
some_enum = (sp02 >> 2) >> 2;
|
||||
|
||||
x = gCurrentPinballGame->kecleonCollisionPos.x;
|
||||
y = gCurrentPinballGame->kecleonCollisionPos.y;
|
||||
|
||||
switch (some_enum)
|
||||
{
|
||||
case 8:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (y <= 0x38)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[0] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[0] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[1] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[1] = 0x18;
|
||||
}
|
||||
}
|
||||
else if (y <= 0x63)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[3] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[3] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerryLargeFlashTimer[2] <= 0)
|
||||
gCurrentPinballGame->kecleonBerryLargeFlashTimer[2] = 0x18;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[7] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[7] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[5] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[5] = 0x18;
|
||||
}
|
||||
}
|
||||
else if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[8] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[8] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[0] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[0] = 0x18;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
gCurrentPinballGame->kecleonCollisionEnabled = 0;
|
||||
if (gCurrentPinballGame->kecleonHitboxY == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonCollisionPos.x != gCurrentPinballGame->kecleonBerryHitPosition[0].x || gCurrentPinballGame->kecleonCollisionPos.y != gCurrentPinballGame->kecleonBerryHitPosition[0].y)
|
||||
{
|
||||
gCurrentPinballGame->kecleonHitSparkTimer[4] = 0x11;
|
||||
gCurrentPinballGame->kecleonBerryHitPosition[0].x = gCurrentPinballGame->kecleonCollisionPos.x;
|
||||
gCurrentPinballGame->kecleonBerryHitPosition[0].y = gCurrentPinballGame->kecleonCollisionPos.y;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->kecleonHitboxY == 8)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonCollisionPos.x != gCurrentPinballGame->kecleonBerryHitPosition[1].x || gCurrentPinballGame->kecleonCollisionPos.y != gCurrentPinballGame->kecleonBerryHitPosition[1].y)
|
||||
{
|
||||
gCurrentPinballGame->kecleonHitSparkTimer[5] = 0x11;
|
||||
gCurrentPinballGame->kecleonBerryHitPosition[1].x = gCurrentPinballGame->kecleonCollisionPos.x;
|
||||
gCurrentPinballGame->kecleonBerryHitPosition[1].y = gCurrentPinballGame->kecleonCollisionPos.y;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->kecleonHitboxY == 16)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonCollisionPos.x != gCurrentPinballGame->kecleonBerryHitPosition[2].x || gCurrentPinballGame->kecleonCollisionPos.y != gCurrentPinballGame->kecleonBerryHitPosition[2].y)
|
||||
{
|
||||
gCurrentPinballGame->kecleonHitSparkTimer[6] = 0x11;
|
||||
gCurrentPinballGame->kecleonBerryHitPosition[2].x = gCurrentPinballGame->kecleonCollisionPos.x;
|
||||
gCurrentPinballGame->kecleonBerryHitPosition[2].y = gCurrentPinballGame->kecleonCollisionPos.y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[9] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[9] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[2] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[2] = 0x18;
|
||||
}
|
||||
}
|
||||
else if (y <= 0x45)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[6] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[6] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[1] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[1] = 0x18;
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
if (x <= 0x72)
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[4] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[4] = 0x18;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->kecleonBerrySmallFlashTimer[3] <= 0)
|
||||
gCurrentPinballGame->kecleonBerrySmallFlashTimer[3] = 0x18;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
198
src/collision_kyogre.c
Normal file
198
src/collision_kyogre.c
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
s16 CollisionCheck_Kyogre(struct Vector16 *arg0, u16 *arg1)
|
||||
{
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
u16 return_val;
|
||||
s16 collisionTileIndex;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
|
||||
u32 some_enum;
|
||||
u32 switch_enum;
|
||||
|
||||
return_val = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
if (arg0->y < 0x200)
|
||||
{
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
collisionTileIndex = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
}
|
||||
else
|
||||
{
|
||||
sp00 = 0;
|
||||
sp02 = 0;
|
||||
}
|
||||
|
||||
CheckKyogreEntityCollision(arg0, &sp00, &sp02);
|
||||
switch_enum = sp02 & 0xF;
|
||||
some_enum = sp02 >> 4;
|
||||
|
||||
switch (switch_enum)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 6:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00;
|
||||
if (*arg1 >= 0x3FF0 && *arg1 <= 0x4010)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < gBoardConfig.fieldLayout.ballSpawnX - 8 ||
|
||||
gCurrentPinballGame->ball->positionQ0.y < gBoardConfig.fieldLayout.ballSpawnY - 8)
|
||||
{
|
||||
|
||||
if (gCurrentPinballGame->ball->spinSpeed > 0)
|
||||
{
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->spinSpeed != 0)
|
||||
{
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain.systemFrameCount & 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0x28;
|
||||
gCurrentPinballGame->ball->spinSpeed = 1;
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0xFFD8;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0xFFFF;
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return_val = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg1 = sp00 & 0x0000FFF0;
|
||||
return_val = 1;
|
||||
break;
|
||||
case 5:
|
||||
some_enum = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessKyogreCollisionEvent(some_enum, &return_val, arg1);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void CheckKyogreEntityCollision(struct Vector16 *arg0, u16 *arg1, u8 *arg2)
|
||||
{
|
||||
s16 deltaX;
|
||||
s16 deltaY;
|
||||
u16 arrayValue;
|
||||
u16 maskedResult;
|
||||
|
||||
if (gCurrentPinballGame->boardEntityCollisionMode == 1)
|
||||
{
|
||||
if (*arg2 & 0xF)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y - gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if ((deltaX < 0 || deltaX >= 0x78) || (deltaY < 0 || deltaY >= 0x98))
|
||||
return;
|
||||
|
||||
maskedResult = gKyogreForm1CollisionMap[(deltaY * 0x78) + deltaX] & 0xFFF0;
|
||||
arrayValue = gKyogreForm1CollisionMap[(deltaY * 0x78) + deltaX] & 0xF;
|
||||
|
||||
if (arrayValue == 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bossHitFlashTimer = 8;
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = 6;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardEntityCollisionMode == 2)
|
||||
{
|
||||
if (*arg2 & 0xF)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y - gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if ((deltaX < 0 || deltaX >= 0x60) || (deltaY < 0 || deltaY >= 0x58))
|
||||
return;
|
||||
|
||||
maskedResult = gKyogreForm2CollisionMap[(deltaY * 0x60) + deltaX] & 0xFFF0;
|
||||
arrayValue = gKyogreForm2CollisionMap[(deltaY * 0x60) + deltaX] & 0xF;
|
||||
|
||||
if (arrayValue == 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bossHitFlashTimer = 8;
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = 6;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardEntityCollisionMode == 3)
|
||||
{
|
||||
if (*arg2 & 0xF)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y - gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if ((deltaX < 0 || deltaX >= 0x60) || (deltaY < 0 || deltaY >= 0x68))
|
||||
return;
|
||||
|
||||
maskedResult = gKyogreForm3CollisionMap[(deltaY * 0x60) + deltaX] & 0xFFF0;
|
||||
arrayValue = gKyogreForm3CollisionMap[(deltaY * 0x60) + deltaX] & 0xF;
|
||||
|
||||
if (arrayValue == 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bossHitFlashTimer = 8;
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = 6;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessKyogreCollisionEvent(u8 arg0, u16 *arg1, u16 *arg2)
|
||||
{
|
||||
switch (arg0)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->bossEntityState = 6;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
break;
|
||||
}
|
||||
}
|
||||
153
src/collision_rayquaza.c
Normal file
153
src/collision_rayquaza.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
//One known callsite is 080145D2 during the rayquaza bonus stage
|
||||
s16 CollisionCheck_Rayquaza(struct Vector16 *arg0, u16 *arg1)
|
||||
{
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
u16 return_val;
|
||||
u32 some_enum;
|
||||
u32 switch_enum;
|
||||
|
||||
return_val = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
|
||||
if (arg0->y < 0x200)
|
||||
{
|
||||
s16 r2;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
r2 = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][r2 * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][r2 * 64 + vec2.y * 8 + vec2.x];
|
||||
}
|
||||
else
|
||||
{
|
||||
sp00 = 0;
|
||||
sp02 = 0;
|
||||
}
|
||||
|
||||
CheckRayquazaEntityCollision(arg0, &sp00, &sp02);
|
||||
switch_enum = sp02 & 0xF;
|
||||
some_enum = sp02 >> 4;
|
||||
|
||||
switch (switch_enum)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 6:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00;
|
||||
if (*arg1 >= 0x3FF0 && *arg1 <= 0x4010)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < (gBoardConfig.fieldLayout.ballSpawnX - 8) || gCurrentPinballGame->ball->positionQ0.y < gBoardConfig.fieldLayout.ballSpawnY - 8)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->spinSpeed > 0)
|
||||
{
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->spinSpeed != 0)
|
||||
{
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain.systemFrameCount & 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 40;
|
||||
gCurrentPinballGame->ball->spinSpeed = 1;
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = -40;
|
||||
gCurrentPinballGame->ball->spinSpeed = -1;
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return_val = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg1 = sp00 & 0xFFF0;
|
||||
return_val = 1;
|
||||
break;
|
||||
case 5:
|
||||
some_enum = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessRayquazaCollisionEvent(some_enum, &return_val, arg1);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void CheckRayquazaEntityCollision(struct Vector16 *arg0, u16 *arg1, u8 *arg2)
|
||||
{
|
||||
s16 deltaX;
|
||||
s16 deltaY;
|
||||
u16 maskedResult;
|
||||
u16 lowerNibble;
|
||||
|
||||
if (gCurrentPinballGame->boardEntityCollisionMode != 1)
|
||||
return;
|
||||
if (*arg2 & 0xF)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->bossCollisionX;
|
||||
deltaY = arg0->y - gCurrentPinballGame->bossCollisionY;
|
||||
|
||||
if ((deltaX < 0 || deltaX >= 0x80) || (deltaY < 0 || deltaY >= 0x80))
|
||||
return;
|
||||
|
||||
maskedResult = gRayquazaBodyCollisionMap[(deltaY * 0x80) + deltaX] & 0xFFF0;
|
||||
lowerNibble = gRayquazaBodyCollisionMap[(deltaY * 0x80) + deltaX] & 0xF;
|
||||
|
||||
if (lowerNibble == 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bossHitFlashTimer = 9;
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = lowerNibble;
|
||||
}
|
||||
|
||||
void ProcessRayquazaCollisionEvent(u8 arg0, u16 *arg1, u16 *arg2)
|
||||
{
|
||||
switch (arg0)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->bossEntityState = 6;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
break;
|
||||
}
|
||||
}
|
||||
842
src/collision_ruby.c
Normal file
842
src/collision_ruby.c
Normal file
|
|
@ -0,0 +1,842 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/ruby_states.h"
|
||||
|
||||
extern const u16 gRubyAltEntity0CollisionMap[];
|
||||
extern const u16 gRubyAltEntity1CollisionMap[];
|
||||
extern const u16 gWhiscashCollisionMap[];
|
||||
|
||||
extern struct SongHeader se_unk_99;
|
||||
|
||||
s16 CollisionCheck_Ruby(struct Vector16 *arg0, u16* arg1) {
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
u16 return_val;
|
||||
s16 collisionTileIndex;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
|
||||
u32 some_enum;
|
||||
u32 switch_enum;
|
||||
|
||||
return_val = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
|
||||
collisionTileIndex = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
|
||||
CheckRubyPondBumperCollision(arg0, &sp00, &sp02);
|
||||
|
||||
switch_enum = sp02 & 0xF;
|
||||
some_enum = sp02 >> 4;
|
||||
|
||||
switch (switch_enum-1) {
|
||||
case 0:
|
||||
case 3:
|
||||
case 5:
|
||||
gCurrentPinballGame->collisionSurfaceType = (switch_enum - 1);
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00;
|
||||
|
||||
if (*arg1 >= 0x3FF0 && *arg1 <= 0x4010)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < gBoardConfig.fieldLayout.ballSpawnX - 8 ||
|
||||
gCurrentPinballGame->ball->positionQ0.y < gBoardConfig.fieldLayout.ballSpawnY - 8)
|
||||
{
|
||||
|
||||
if (gCurrentPinballGame->ball->spinSpeed > 0)
|
||||
{
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->spinSpeed != 0)
|
||||
{
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain.systemFrameCount & 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0x28;
|
||||
gCurrentPinballGame->ball->spinSpeed = 1;
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0xFFD8;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0xFFFF;
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return_val = 1;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg1 = sp00 & 0x0000FFF0;
|
||||
return_val = 1;
|
||||
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_ABSORB_ZONE_HIT;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
some_enum = 0;
|
||||
break;
|
||||
}
|
||||
ProcessRubyCollisionEvent((s32) some_enum, &return_val, arg1);
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
|
||||
void CheckRubyPondBumperCollision(struct Vector16* arg0, u16* arg1, u8* arg2)
|
||||
{
|
||||
s16 deltaX;
|
||||
s16 deltaY;
|
||||
u16 maskedResult;
|
||||
u8 lowerNibble;
|
||||
s32 ix;
|
||||
|
||||
maskedResult = 0;
|
||||
lowerNibble = 0;
|
||||
ix = 0;
|
||||
|
||||
if (gCurrentPinballGame->ballInLowerHalf == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->boardLayerDepth != 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->shouldProcessWhiscash)
|
||||
{
|
||||
if (gCurrentPinballGame->whiscashInvulnerable == 0)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x + gCurrentPinballGame->rubyBumperCollisionPosition[0].x;
|
||||
deltaY = arg0->y + gCurrentPinballGame->rubyBumperCollisionPosition[0].y;
|
||||
|
||||
if (deltaX > 79U)
|
||||
return;
|
||||
|
||||
if (deltaY > 87U)
|
||||
return;
|
||||
|
||||
maskedResult = 0xFFF0 & gWhiscashCollisionMap[(deltaY * 80) + deltaX];
|
||||
lowerNibble = 0xF & gWhiscashCollisionMap[(deltaY * 80) + deltaX];
|
||||
|
||||
if (lowerNibble == 0)
|
||||
return;
|
||||
|
||||
*arg1 = maskedResult;
|
||||
|
||||
// if hit, while in its base mode, processes as a hit.
|
||||
// A Ball in the area being sucked in, or already hitting it won't affect it.
|
||||
if (gCurrentPinballGame->whiscashState <= WHISCASH_STATE_SITTING)
|
||||
{
|
||||
*arg2 = lowerNibble;
|
||||
gCurrentPinballGame->whiscashState = WHISCASH_STATE_HIT;
|
||||
return;
|
||||
}
|
||||
|
||||
*arg2 = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (0xF & *arg2)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x + (u16) gCurrentPinballGame->rubyBumperCollisionPosition[0].x;
|
||||
deltaY = arg0->y + (u16) gCurrentPinballGame->rubyBumperCollisionPosition[0].y;
|
||||
|
||||
if (deltaX <= 63U && deltaY <= 63U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
|
||||
if (lowerNibble != 0)
|
||||
ix = 0;
|
||||
}
|
||||
|
||||
if (lowerNibble == 0)
|
||||
{
|
||||
deltaX = gCurrentPinballGame->rubyBumperCollisionPosition[1].x + arg0->x;
|
||||
deltaY = gCurrentPinballGame->rubyBumperCollisionPosition[1].y + arg0->y;
|
||||
|
||||
if (deltaX <= 63U && deltaY <= 63U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
if (lowerNibble != 0)
|
||||
ix = 1;
|
||||
}
|
||||
|
||||
if (lowerNibble == 0)
|
||||
{
|
||||
deltaX = gCurrentPinballGame->rubyBumperCollisionPosition[2].x + arg0->x;
|
||||
deltaY = gCurrentPinballGame->rubyBumperCollisionPosition[2].y + arg0->y;
|
||||
|
||||
if (deltaX <= 63U && deltaY <= 63U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
|
||||
if (lowerNibble == 0)
|
||||
return;
|
||||
|
||||
ix = 2;
|
||||
}
|
||||
|
||||
if (lowerNibble == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gCurrentPinballGame->rubyPondContentsChanging)
|
||||
gCurrentPinballGame->pondBumperStates[ix] = 107;
|
||||
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = lowerNibble;
|
||||
|
||||
if (gCurrentPinballGame->bumperHitCountdown > 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bumperHitCountdown = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*arg2 & 0xF) == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->sideBumperAnimPhase[0] > 0)
|
||||
{
|
||||
s16 deltaY_alt;
|
||||
deltaX = 2 * (-24 -gCurrentPinballGame->sideBumperShakeOffset[0]) + arg0->x;
|
||||
deltaY_alt = arg0->y -580;
|
||||
|
||||
if (deltaX <= 71U && deltaY_alt <= 71U)
|
||||
{
|
||||
*arg1 = 0xFFF0 & gRubyAltEntity0CollisionMap[(deltaY_alt * 72) + deltaX];
|
||||
*arg2 = 0xF & gRubyAltEntity0CollisionMap[(deltaY_alt * 72) + deltaX];
|
||||
|
||||
if (*arg2 & 1)
|
||||
{
|
||||
gCurrentPinballGame->sideBumperHitFlag = 1;
|
||||
*arg2 = 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->sideBumperAnimPhase[1] > 0)
|
||||
{
|
||||
deltaX = ((gCurrentPinballGame->sideBumperShakeOffset[1] - 180) * 2) + arg0->x;
|
||||
deltaY = arg0->y -580;
|
||||
|
||||
if (deltaX <= 71U && deltaY <= 71U)
|
||||
{
|
||||
*arg1 = 0xFFF0 & gRubyAltEntity1CollisionMap[(deltaY * 72) + deltaX];
|
||||
*arg2 = 0xF & gRubyAltEntity1CollisionMap[(deltaY * 72) + deltaX];
|
||||
|
||||
if (*arg2 & 1)
|
||||
{
|
||||
gCurrentPinballGame->sideBumperHitFlag = 2;
|
||||
*arg2 = 6;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessRubyCollisionEvent(s32 arg0, s16* arg1, u16* arg2)
|
||||
{
|
||||
s16 absVelY;
|
||||
|
||||
switch ((u8)arg0 - 1)
|
||||
{
|
||||
case 0:
|
||||
if (gCurrentPinballGame->collisionCooldownTimer == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ1.x > 359)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ1.y > 199)
|
||||
gCurrentPinballGame->ballCatchState = 1;
|
||||
else
|
||||
gCurrentPinballGame->ballCatchState = 3;
|
||||
}
|
||||
else
|
||||
gCurrentPinballGame->ballCatchState= 2;
|
||||
|
||||
DispatchRubyCatchModeInit();
|
||||
gCurrentPinballGame->collisionResponseType = 7;
|
||||
*arg1 = 1;
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
case 1:
|
||||
if (gCurrentPinballGame->boardLayerDepth == 0)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 2;
|
||||
gCurrentPinballGame->boardLayerDepth = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->boardLayerDepth == 2)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 2;
|
||||
gCurrentPinballGame->boardLayerDepth = 3;
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
if (gCurrentPinballGame->boardLayerDepth == 2)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 3;
|
||||
gCurrentPinballGame->boardLayerDepth = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardLayerDepth == 3)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 2;
|
||||
gCurrentPinballGame->boardLayerDepth = 2;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->nuzleafAnimState == 6)
|
||||
gCurrentPinballGame->nuzleafAnimState = 7;
|
||||
|
||||
if (gCurrentPinballGame->shopDoorTargetFrame & 0xF0 )
|
||||
gCurrentPinballGame->shopDoorTargetFrame = 0;
|
||||
|
||||
if (gCurrentPinballGame->shopDoorOpenLevel & 0xF0)
|
||||
gCurrentPinballGame->shopDoorOpenLevel = 0;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (gCurrentPinballGame->mainBoardCountdownTimer == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x > 131)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
if (gCurrentPinballGame->progressLevel <= 98)
|
||||
gCurrentPinballGame->progressLevel++;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->positionQ0.x > 91)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
gCurrentPinballGame->rubyPondChangeTimer = 0;
|
||||
gCurrentPinballGame->rubyPondContentsChanging = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
if (gCurrentPinballGame->chikoritaFlashActive == 0)
|
||||
{
|
||||
gCurrentPinballGame->chikoritaFlashActive = 1;
|
||||
gCurrentPinballGame->chikoritaFlashTimer = 0;
|
||||
}
|
||||
}
|
||||
gCurrentPinballGame->mainBoardCountdownTimer = 45;
|
||||
|
||||
m4aSongNumStart(SE_TRIGGER_BUTTON_HIT);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->ballInLaunchChute = 1;
|
||||
gCurrentPinballGame->ballTouchingSpoink = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 0;
|
||||
return;
|
||||
case 5:
|
||||
if (gCurrentPinballGame->ballInLowerHalf == 0)
|
||||
{
|
||||
SetBoardCollisionConfig(1);
|
||||
gCurrentPinballGame->boardCollisionConfigChanged = 1;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < 50)
|
||||
{
|
||||
if (gCurrentPinballGame->nuzleafHitFlag == 0)
|
||||
{
|
||||
gCurrentPinballGame->nuzleafHitFlag = 1;
|
||||
gCurrentPinballGame->nuzleafAnimState = 1;
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xB000;
|
||||
*arg1 = 1;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->nuzleafHitFlag == 1)
|
||||
{
|
||||
gCurrentPinballGame->nuzleafHitFlag = 2;
|
||||
gCurrentPinballGame->nuzleafAnimState = 3;
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xA000;
|
||||
*arg1 = 1;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
|
||||
memcpy(&gCurrentPinballGame->ballStates[1], gCurrentPinballGame->ballStates, 0x44U);
|
||||
|
||||
gCurrentPinballGame->secondaryBall = &gCurrentPinballGame->ballStates[1];
|
||||
gCurrentPinballGame->ballLaunchTimer = 120;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 14;
|
||||
return;
|
||||
case 7:
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 50)
|
||||
{
|
||||
if (gCurrentPinballGame->ballCollisionZone == 8)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState <= 2 && gCurrentPinballGame->evoArrowProgress <= 2)
|
||||
{
|
||||
if (gCurrentPinballGame->evoArrowProgress == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
else if (gCurrentPinballGame->evoArrowProgress == 1)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
else
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10000;
|
||||
|
||||
gCurrentPinballGame->evoArrowProgress++;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0x99);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->travelRouletteSlotHitType = 1;
|
||||
}
|
||||
gCurrentPinballGame->ballCollisionZone = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 100)
|
||||
{
|
||||
if (gCurrentPinballGame->ballCollisionZone == 7)
|
||||
{
|
||||
gCurrentPinballGame->coinRewardAmount = 10;
|
||||
|
||||
if(gCurrentPinballGame->coinRewardLevel <= 2)
|
||||
{
|
||||
if(gCurrentPinballGame->coinRewardLevel == 0)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
gCurrentPinballGame->coinRewardAmount = 1;
|
||||
}
|
||||
else if(gCurrentPinballGame->coinRewardLevel == 1)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
gCurrentPinballGame->coinRewardAmount = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10000;
|
||||
gCurrentPinballGame->coinRewardAmount = 10;
|
||||
}
|
||||
gCurrentPinballGame->coinRewardLevel++;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->coinRewardTimer = 0;
|
||||
gCurrentPinballGame->coinRewardLevelTimer = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 126)
|
||||
{
|
||||
if (gCurrentPinballGame->ballPowerUpLight[0] == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpLight[0] = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 3;
|
||||
|
||||
if (gCurrentPinballGame->ballPowerUpAnimActive == 0)
|
||||
{
|
||||
if (!(gCurrentPinballGame->ballPowerUpLight[1] &
|
||||
gCurrentPinballGame->ballPowerUpLight[2]))
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpAnimActive = 1;
|
||||
gCurrentPinballGame->ballShadowTimer = 60;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 148)
|
||||
{
|
||||
if (gCurrentPinballGame->ballPowerUpLight[1] == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpLight[1] = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 4;
|
||||
|
||||
if (gCurrentPinballGame->ballPowerUpAnimActive != 0)
|
||||
return;
|
||||
|
||||
if (!(gCurrentPinballGame->ballPowerUpLight[0] &
|
||||
gCurrentPinballGame->ballPowerUpLight[2]))
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpAnimActive = 1;
|
||||
gCurrentPinballGame->ballShadowTimer = 60;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 172)
|
||||
{
|
||||
if (gCurrentPinballGame->ballPowerUpLight[2] == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpLight[2] = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 5;
|
||||
|
||||
if (gCurrentPinballGame->ballPowerUpAnimActive != 0)
|
||||
return;
|
||||
|
||||
if (!(gCurrentPinballGame->ballPowerUpLight[0] &
|
||||
gCurrentPinballGame->ballPowerUpLight[1]))
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpAnimActive = 1;
|
||||
gCurrentPinballGame->ballShadowTimer = 60;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ballCollisionZone == 9)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState <= 2 && gCurrentPinballGame->catchArrowProgress <= 2)
|
||||
{
|
||||
if (gCurrentPinballGame->catchArrowProgress == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
else if (gCurrentPinballGame->catchArrowProgress == 1)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
else
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10000;
|
||||
|
||||
gCurrentPinballGame->catchArrowProgress++;
|
||||
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_unk_99);
|
||||
|
||||
if (gCurrentPinballGame->catchArrowProgress > 1)
|
||||
gCurrentPinballGame->catchProgressFlashing = 1;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->travelRouletteSlotHitType = 2;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 6;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 50)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 8;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 100)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 7;
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 9;
|
||||
return;
|
||||
case 9:
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 46)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 10;
|
||||
|
||||
if (gCurrentPinballGame->holeIndicators[0] != 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[0] = 1;
|
||||
|
||||
if (gCurrentPinballGame->allHolesLit != 0)
|
||||
return;
|
||||
|
||||
if (!(gCurrentPinballGame->holeIndicators[1] &
|
||||
gCurrentPinballGame->holeIndicators[2] &
|
||||
gCurrentPinballGame->holeIndicators[3]))
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 120)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 11;
|
||||
|
||||
if (gCurrentPinballGame->holeIndicators[1] != 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[1] = 1;
|
||||
|
||||
if (gCurrentPinballGame->allHolesLit != 0)
|
||||
return;
|
||||
|
||||
if (!(gCurrentPinballGame->holeIndicators[0] &
|
||||
gCurrentPinballGame->holeIndicators[2] &
|
||||
gCurrentPinballGame->holeIndicators[3]))
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 193)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 12;
|
||||
|
||||
if (gCurrentPinballGame->holeIndicators[2] != 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[2] = 1;
|
||||
|
||||
if (gCurrentPinballGame->allHolesLit != 0)
|
||||
return;
|
||||
|
||||
if (!(gCurrentPinballGame->holeIndicators[0] &
|
||||
gCurrentPinballGame->holeIndicators[1] &
|
||||
gCurrentPinballGame->holeIndicators[3]))
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 13;
|
||||
|
||||
if (gCurrentPinballGame->holeIndicators[3] != 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[3] = 1;
|
||||
|
||||
if (gCurrentPinballGame->allHolesLit != 0)
|
||||
return;
|
||||
|
||||
if (!(gCurrentPinballGame->holeIndicators[0] &
|
||||
gCurrentPinballGame->holeIndicators[1] &
|
||||
gCurrentPinballGame->holeIndicators[2]))
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
return;
|
||||
case 10:
|
||||
if (gCurrentPinballGame->ballInLowerHalf == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x > 170)
|
||||
{
|
||||
if (gCurrentPinballGame->shopDoorTargetFrame > 2U)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xB000;
|
||||
*arg1 = 1;
|
||||
|
||||
if (gCurrentPinballGame->boardState <= 2 && gCurrentPinballGame->shopDoorOpenLevel <= 2)
|
||||
{
|
||||
gCurrentPinballGame->shopDoorOpenLevel = 3;
|
||||
gCurrentPinballGame->shopDoorAnimDelay = 5;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->scoreAddedInFrame = 50000;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->nuzleafAnimState <= 4)
|
||||
{
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xF800;
|
||||
*arg1 = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->nuzleafAnimState == 5)
|
||||
gCurrentPinballGame->nuzleafAnimState = 6;
|
||||
|
||||
if (gCurrentPinballGame->rampPrizeType == 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->rampPrizeType == 1)
|
||||
gCurrentPinballGame->oneUpAnimTimer = 90;
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ballPowerUpOverride = 1;
|
||||
gCurrentPinballGame->ballPowerUpAnimActive = 1;
|
||||
gCurrentPinballGame->ballShadowTimer = 60;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xD8);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->rampPrizeType = 0;
|
||||
gCurrentPinballGame->rampPrizeRespawnTimer = 600;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pikaKickbackTimer != 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 120)
|
||||
gCurrentPinballGame->outLaneSide = 1;
|
||||
else
|
||||
gCurrentPinballGame->outLaneSide = 2;
|
||||
|
||||
if (gCurrentPinballGame->outLanePikaPosition <= 1)
|
||||
{
|
||||
if (gCurrentPinballGame->outLanePikaPosition != gCurrentPinballGame->outLaneSide - 1)
|
||||
return;
|
||||
else
|
||||
gCurrentPinballGame->pikaKickbackTimer = 120;
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->pikaKickbackTimer = 120;
|
||||
return;
|
||||
|
||||
case 11:
|
||||
if (gCurrentPinballGame->pikaSpinCooldownTimer != 0)
|
||||
return;
|
||||
|
||||
absVelY = gCurrentPinballGame->ball->velocity.y;
|
||||
gCurrentPinballGame->pikaSpinMomentum = gCurrentPinballGame->ball->velocity.y;
|
||||
|
||||
if (absVelY < 0) {
|
||||
absVelY = -absVelY;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->pikaChargeTarget += (absVelY) / 3;
|
||||
|
||||
if (gCurrentPinballGame->pikaChargeTarget > 168)
|
||||
gCurrentPinballGame->pikaChargeTarget = 168;
|
||||
|
||||
gCurrentPinballGame->pikaSpinCooldownTimer = 20;
|
||||
return;
|
||||
case 12:
|
||||
if (gCurrentPinballGame->cyndaquilCollisionEnabled == 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->collisionCooldownTimer != 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->eggCaveState != 0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->eggCaveState++;
|
||||
|
||||
gCurrentPinballGame->cyndaquilCollisionEnabled = 0;
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
|
||||
*arg2 = 0xD000;
|
||||
*arg1 = 1;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
PlayRumble(7);
|
||||
return;
|
||||
case 13:
|
||||
if (gCurrentPinballGame->cyndaquilCollisionEnabled == 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->collisionCooldownTimer != 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->eggCaveState != 1)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->eggCaveState++;
|
||||
gCurrentPinballGame->cyndaquilCollisionEnabled = 0;
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xCC00;
|
||||
*arg1 = 1;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
PlayRumble(7);
|
||||
return;
|
||||
case 14:
|
||||
if ((gCurrentPinballGame->boardState > 2) && (gCurrentPinballGame->boardState != 5))
|
||||
{
|
||||
if (gCurrentPinballGame->eggCaveExitDelayTimer == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->eggCaveState == 2)
|
||||
{
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xC800;
|
||||
*arg1 = 1;
|
||||
gCurrentPinballGame->eggCaveState++;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
PlayRumble(7);
|
||||
return;
|
||||
}
|
||||
else if (gCurrentPinballGame->eggCaveState == 3)
|
||||
{
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xC800;
|
||||
*arg1 = 1;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
gCurrentPinballGame->eggCaveReEntryFlag = 1;
|
||||
PlayRumble(7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->cyndaquilCollisionEnabled != 0 && gCurrentPinballGame->eggCaveState == 2)
|
||||
{
|
||||
gCurrentPinballGame->eggCaveState++;
|
||||
gCurrentPinballGame->cyndaquilCollisionEnabled = 0;
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xC800;
|
||||
*arg1 = 1;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
PlayRumble(7);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
645
src/collision_sapphire.c
Normal file
645
src/collision_sapphire.c
Normal file
|
|
@ -0,0 +1,645 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern u16 gSapphireTargetBumperIndexMap[];
|
||||
|
||||
s16 CollisionCheck_Sapphire(struct Vector16 *arg0, u16* arg1) {
|
||||
struct Vector16 vec1;
|
||||
struct Vector16 vec2;
|
||||
u16 sp00;
|
||||
u8 sp02;
|
||||
u16 return_val;
|
||||
s16 collisionTileIndex;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
|
||||
u32 some_enum;
|
||||
u8 switch_enum;
|
||||
|
||||
return_val = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
|
||||
vec1.x = arg0->x / 8;
|
||||
vec1.y = arg0->y / 8;
|
||||
vec2.x = arg0->x % 8;
|
||||
vec2.y = arg0->y % 8;
|
||||
tileMapPage = vec1.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
vec1.y %= 64;
|
||||
|
||||
collisionTileIndex = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][vec1.y * 64 + vec1.x];
|
||||
sp00 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
sp02 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][collisionTileIndex * 64 + vec2.y * 8 + vec2.x];
|
||||
|
||||
CheckSapphireBumperCollision(arg0, &sp00, &sp02);
|
||||
|
||||
switch_enum = sp02 & 0xF;
|
||||
some_enum = sp02 >> 4;
|
||||
|
||||
switch (switch_enum)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp00;
|
||||
if (*arg1 >= 0x3FF0 && *arg1 <= 0x4010)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < gBoardConfig.fieldLayout.ballSpawnX - 8 ||
|
||||
gCurrentPinballGame->ball->positionQ0.y < gBoardConfig.fieldLayout.ballSpawnY - 8)
|
||||
{
|
||||
|
||||
if (gCurrentPinballGame->ball->spinSpeed > 0)
|
||||
{
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->spinSpeed != 0)
|
||||
{
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain.systemFrameCount & 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0x28;
|
||||
gCurrentPinballGame->ball->spinSpeed = 1;
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0xFFD8;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0xFFFF;
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return_val = 1;
|
||||
break;
|
||||
case 3:
|
||||
case 2:
|
||||
gCurrentPinballGame->collisionSurfaceType = switch_enum - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg1 = sp00 & 0x0000FFF0;
|
||||
return_val = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessSapphireCollisionEvent((s32) some_enum, &return_val, arg1);
|
||||
return return_val;
|
||||
}
|
||||
|
||||
void CheckSapphireBumperCollision(struct Vector16 *arg0, s16 *arg1, u8 *arg2) {
|
||||
|
||||
s16 deltaX;
|
||||
s16 deltaY;
|
||||
u16 maskedResult = 0;
|
||||
u8 lowerNibble = 0;
|
||||
s32 ix = 0;
|
||||
|
||||
if (gCurrentPinballGame->ballInLowerHalf == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->boardLayerDepth != 0)
|
||||
return;
|
||||
|
||||
deltaX = arg0->x + gCurrentPinballGame->rubyBumperCollisionPosition[0].x;
|
||||
deltaY = arg0->y + gCurrentPinballGame->rubyBumperCollisionPosition[0].y;
|
||||
|
||||
if (deltaX <= 63U && deltaY <= 63U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
ix = 0;
|
||||
}
|
||||
if (lowerNibble == 0)
|
||||
{
|
||||
deltaX = gCurrentPinballGame->rubyBumperCollisionPosition[1].x + arg0->x;
|
||||
deltaY = gCurrentPinballGame->rubyBumperCollisionPosition[1].y + arg0->y;
|
||||
|
||||
if (deltaX <= 63U && deltaY <= 63U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
ix = 1;
|
||||
}
|
||||
|
||||
if (lowerNibble == 0)
|
||||
{
|
||||
deltaX = gCurrentPinballGame->rubyBumperCollisionPosition[2].x + arg0->x;
|
||||
deltaY = gCurrentPinballGame->rubyBumperCollisionPosition[2].y + arg0->y;
|
||||
|
||||
if (deltaX <= 63U && deltaY <= 63U)
|
||||
{
|
||||
maskedResult = 0xFFF0 & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
lowerNibble = 0xF & gSharedBumperCollisionMap[(deltaY * 64) + deltaX];
|
||||
ix = 2;
|
||||
}
|
||||
|
||||
if (lowerNibble == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
gCurrentPinballGame->pondBumperStates[ix] = 6;
|
||||
|
||||
*arg1 = maskedResult;
|
||||
*arg2 = lowerNibble;
|
||||
|
||||
if (gCurrentPinballGame->bumperHitCountdown <= 0)
|
||||
gCurrentPinballGame->bumperHitCountdown = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ProcessSapphireCollisionEvent(u8 arg0, u16* arg1, u16* arg2)
|
||||
{
|
||||
s16 absVelY;
|
||||
s16 x0Position;
|
||||
s16 modRes;
|
||||
s16 index;
|
||||
u16 angle;
|
||||
int squaredMagnitude;
|
||||
|
||||
switch (arg0)
|
||||
{
|
||||
case 1:
|
||||
if (gCurrentPinballGame->collisionCooldownTimer == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ1.x >= 200)
|
||||
gCurrentPinballGame->ballCatchState = 1;
|
||||
else
|
||||
gCurrentPinballGame->ballCatchState = 3;
|
||||
|
||||
DispatchSapphireCatchModeInit();
|
||||
gCurrentPinballGame->collisionResponseType = 7;
|
||||
*arg1 = 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (gCurrentPinballGame->boardLayerDepth == 0)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 2;
|
||||
gCurrentPinballGame->boardLayerDepth = 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardLayerDepth == 2)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 2;
|
||||
gCurrentPinballGame->boardLayerDepth = 3;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardLayerDepth == 3)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 1;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (gCurrentPinballGame->boardLayerDepth == 2)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 3;
|
||||
gCurrentPinballGame->boardLayerDepth = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardLayerDepth == 3)
|
||||
{
|
||||
gCurrentPinballGame->ball->oamPriority = 2;
|
||||
gCurrentPinballGame->boardLayerDepth = 2;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (gCurrentPinballGame->mainBoardCountdownTimer == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.y < 260)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < 74)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 3 && gCurrentPinballGame->sapphireBumperState[1] < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperState[1] == 1)
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[1] = 6;
|
||||
else
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[1] = 4;
|
||||
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[1] = 0;
|
||||
gCurrentPinballGame->sapphireBumperState[1] = 1;
|
||||
PlayRumble(7);
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x /= 2;
|
||||
gCurrentPinballGame->ball->velocity.y /= 2;
|
||||
|
||||
memcpy(&gCurrentPinballGame->ballStates[1], &gCurrentPinballGame->ballStates[0], sizeof(*gCurrentPinballGame->ballStates));
|
||||
|
||||
gCurrentPinballGame->secondaryBall = &gCurrentPinballGame->ballStates[1];
|
||||
gCurrentPinballGame->ballLaunchTimer = 25;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->positionQ0.x < 116)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 3 && gCurrentPinballGame->sapphireBumperState[0] < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireBumperState[0] == 1)
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[0] = 6;
|
||||
else
|
||||
gCurrentPinballGame->sapphireBumperAnimKeyframe[0] = 4;
|
||||
|
||||
gCurrentPinballGame->sapphireBumperAnimSubTimer[0] = 0;
|
||||
gCurrentPinballGame->sapphireBumperState[0] = 1;
|
||||
|
||||
PlayRumble(7);
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x /= 2;
|
||||
gCurrentPinballGame->ball->velocity.y /= 2;
|
||||
|
||||
memcpy(&gCurrentPinballGame->ballStates[1], &gCurrentPinballGame->ballStates[0], sizeof(*gCurrentPinballGame->ballStates));
|
||||
|
||||
gCurrentPinballGame->secondaryBall = &gCurrentPinballGame->ballStates[1];
|
||||
gCurrentPinballGame->ballLaunchTimer = 25;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pelipperFrameTimer = 1800;
|
||||
gCurrentPinballGame->pelipperState = 1;
|
||||
|
||||
if (gCurrentPinballGame->progressLevel < 99)
|
||||
gCurrentPinballGame->progressLevel++;
|
||||
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < 110)
|
||||
{
|
||||
gCurrentPinballGame->seedotCollisionTrigger = 1;
|
||||
gCurrentPinballGame->ball->velocity.y /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->zigzagoonState == 0)
|
||||
gCurrentPinballGame->zigzagoonState = 1;
|
||||
else
|
||||
gCurrentPinballGame->zigzagoonState = 0;
|
||||
|
||||
gCurrentPinballGame->ball->velocity.y /=2;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 3000;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->mainBoardCountdownTimer = 45;
|
||||
m4aSongNumStart(SE_TRIGGER_BUTTON_HIT);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
gCurrentPinballGame->ballTouchingSpoink = 1;
|
||||
gCurrentPinballGame->ballInLaunchChute = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 0;
|
||||
gCurrentPinballGame->hatchMachineActive = 0;
|
||||
break;
|
||||
case 6:
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < 120)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->velocity.y > 0)
|
||||
{
|
||||
angle = 0xDA00;
|
||||
squaredMagnitude =
|
||||
gCurrentPinballGame->ball->velocity.x * gCurrentPinballGame->ball->velocity.x +
|
||||
gCurrentPinballGame->ball->velocity.y * gCurrentPinballGame->ball->velocity.y;
|
||||
|
||||
squaredMagnitude = Sqrt(squaredMagnitude * 4) / 2;
|
||||
gCurrentPinballGame->ball->velocity.x = squaredMagnitude * Cos(angle) / 20000;
|
||||
gCurrentPinballGame->ball->velocity.y = -squaredMagnitude * Sin(angle) / 20000;
|
||||
}
|
||||
}
|
||||
else
|
||||
gCurrentPinballGame->hatchMachineActive = 1;
|
||||
break;
|
||||
case 7:
|
||||
if (gCurrentPinballGame->shopShockWallAnimState != 3)
|
||||
{
|
||||
gCurrentPinballGame->shopBumperHitTimer = 17;
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 2;
|
||||
*arg2 = 0xD800;
|
||||
*arg1 = 1;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
x0Position = gCurrentPinballGame->ball->positionQ0.x;
|
||||
if (gCurrentPinballGame->boardLayerDepth > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->ballCollisionZone == 7)
|
||||
{
|
||||
gCurrentPinballGame->coinRewardAmount = 10;
|
||||
if (gCurrentPinballGame->coinRewardLevel < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->coinRewardLevel == 0)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
gCurrentPinballGame->coinRewardAmount = 1;
|
||||
}
|
||||
else if (gCurrentPinballGame->coinRewardLevel == 1)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
gCurrentPinballGame->coinRewardAmount = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10000;
|
||||
gCurrentPinballGame->coinRewardAmount = 10;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->coinRewardLevel++;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->coinRewardTimer = 0;
|
||||
gCurrentPinballGame->coinRewardLevelTimer = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x0Position <= 72)
|
||||
{
|
||||
if (gCurrentPinballGame->ballCollisionZone == 8)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 3 && gCurrentPinballGame->evoArrowProgress < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->evoArrowProgress == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
else if (gCurrentPinballGame->evoArrowProgress == 1)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
else
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10000;
|
||||
|
||||
gCurrentPinballGame->evoArrowProgress++;
|
||||
m4aSongNumStart(SE_UNKNOWN_0x99);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->travelRouletteSlotHitType = 1;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 2;
|
||||
}
|
||||
else if (x0Position <= 98)
|
||||
{
|
||||
if (gCurrentPinballGame->ballPowerUpLight[0] == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpLight[0] = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 3;
|
||||
|
||||
if (gCurrentPinballGame->ballPowerUpAnimActive == 0 && (gCurrentPinballGame->ballPowerUpLight[1] & gCurrentPinballGame->ballPowerUpLight[2]))
|
||||
{
|
||||
gCurrentPinballGame->ballPowerUpAnimActive = 1;
|
||||
gCurrentPinballGame->ballShadowTimer = 60;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
}
|
||||
else if (x0Position <= 118)
|
||||
{
|
||||
if (gCurrentPinballGame->ballPowerUpLight[1] == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpLight[1] = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 4;
|
||||
|
||||
if (gCurrentPinballGame->ballPowerUpAnimActive == 0 && (gCurrentPinballGame->ballPowerUpLight[0] & gCurrentPinballGame->ballPowerUpLight[2]))
|
||||
{
|
||||
gCurrentPinballGame->ballPowerUpAnimActive = 1;
|
||||
gCurrentPinballGame->ballShadowTimer = 60;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
}
|
||||
else if (x0Position <= 146)
|
||||
{
|
||||
if (gCurrentPinballGame->ballPowerUpLight[2] == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
|
||||
gCurrentPinballGame->ballPowerUpLight[2] = 1;
|
||||
gCurrentPinballGame->ballCollisionZone = 5;
|
||||
|
||||
if (gCurrentPinballGame->ballPowerUpAnimActive == 0 && (gCurrentPinballGame->ballPowerUpLight[0] & gCurrentPinballGame->ballPowerUpLight[1]))
|
||||
{
|
||||
gCurrentPinballGame->ballPowerUpAnimActive = 1;
|
||||
gCurrentPinballGame->ballShadowTimer = 60;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->ballCollisionZone == 9)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState <= 2 && gCurrentPinballGame->catchArrowProgress < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->catchArrowProgress == 0)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 2000;
|
||||
else if (gCurrentPinballGame->catchArrowProgress == 1)
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
else
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10000;
|
||||
|
||||
gCurrentPinballGame->catchArrowProgress++;
|
||||
|
||||
if (gCurrentPinballGame->chargeFillValue == 13)
|
||||
m4aSongNumStart(SE_UNKNOWN_0x99);
|
||||
|
||||
if (gCurrentPinballGame->catchArrowProgress > 1)
|
||||
gCurrentPinballGame->catchProgressFlashing = 1;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->travelRouletteSlotHitType = 2;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballCollisionZone = 6;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
x0Position = gCurrentPinballGame->ball->positionQ0.x;
|
||||
if (gCurrentPinballGame->boardLayerDepth > 0)
|
||||
gCurrentPinballGame->ballCollisionZone = 7;
|
||||
else if (x0Position <= 50)
|
||||
gCurrentPinballGame->ballCollisionZone = 8;
|
||||
else
|
||||
gCurrentPinballGame->ballCollisionZone = 9;
|
||||
break;
|
||||
case 10:
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 46)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 10;
|
||||
if (gCurrentPinballGame->holeIndicators[0] == 0)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[0] = 1;
|
||||
if (gCurrentPinballGame->allHolesLit == 0 && (
|
||||
gCurrentPinballGame->holeIndicators[1] &
|
||||
gCurrentPinballGame->holeIndicators[2] &
|
||||
gCurrentPinballGame->holeIndicators[3]))
|
||||
{
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->positionQ0.x <= 120)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 11;
|
||||
|
||||
if (gCurrentPinballGame->holeIndicators[1] == 0)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[1] = 1;
|
||||
if (gCurrentPinballGame->allHolesLit == 0 && (
|
||||
gCurrentPinballGame->holeIndicators[0] &
|
||||
gCurrentPinballGame->holeIndicators[2] &
|
||||
gCurrentPinballGame->holeIndicators[3]))
|
||||
{
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->positionQ0.x <= 193)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 12;
|
||||
if (gCurrentPinballGame->holeIndicators[2] == 0)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[2] = 1;
|
||||
|
||||
if (gCurrentPinballGame->allHolesLit == 0 && (
|
||||
gCurrentPinballGame->holeIndicators[0] &
|
||||
gCurrentPinballGame->holeIndicators[1] &
|
||||
gCurrentPinballGame->holeIndicators[3]))
|
||||
{
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 13;
|
||||
if (gCurrentPinballGame->holeIndicators[3] == 0)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 1000;
|
||||
gCurrentPinballGame->holeIndicators[3] = 1;
|
||||
if (gCurrentPinballGame->allHolesLit == 0 && (
|
||||
gCurrentPinballGame->holeIndicators[0] &
|
||||
gCurrentPinballGame->holeIndicators[1] &
|
||||
gCurrentPinballGame->holeIndicators[2]))
|
||||
{
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
if (gCurrentPinballGame->pikaKickbackTimer == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x <= 120)
|
||||
gCurrentPinballGame->outLaneSide = 1;
|
||||
else
|
||||
gCurrentPinballGame->outLaneSide = 2;
|
||||
|
||||
if (gCurrentPinballGame->outLanePikaPosition < 2)
|
||||
{
|
||||
if (gCurrentPinballGame->outLanePikaPosition == gCurrentPinballGame->outLaneSide - 1)
|
||||
gCurrentPinballGame->pikaKickbackTimer = 120;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pikaKickbackTimer = 120;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
if (gCurrentPinballGame->pikaSpinCooldownTimer == 0)
|
||||
{
|
||||
absVelY = gCurrentPinballGame->ball->velocity.y;
|
||||
gCurrentPinballGame->pikaSpinMomentum = absVelY;
|
||||
if (absVelY < 0)
|
||||
absVelY = -absVelY;
|
||||
|
||||
gCurrentPinballGame->pikaChargeTarget = gCurrentPinballGame->pikaChargeTarget + (absVelY / 3);
|
||||
if (gCurrentPinballGame->pikaChargeTarget > 168)
|
||||
gCurrentPinballGame->pikaChargeTarget = 168;
|
||||
|
||||
gCurrentPinballGame->pikaSpinCooldownTimer = 20;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
if (gCurrentPinballGame->ballCollisionZone != 14)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 14;
|
||||
index = gSapphireTargetBumperIndexMap[gCurrentPinballGame->targetBumperHitCounter];
|
||||
gCurrentPinballGame->targetBumperAnimTimers[index] = 10;
|
||||
gCurrentPinballGame->targetBumperHitCounter++;
|
||||
if (gCurrentPinballGame->targetBumperHitCounter == 3)
|
||||
{
|
||||
memcpy(&gCurrentPinballGame->ballStates[1], &gCurrentPinballGame->ballStates[0], sizeof(*gCurrentPinballGame->ballStates));
|
||||
gCurrentPinballGame->secondaryBall = &gCurrentPinballGame->ballStates[1];
|
||||
if (gCurrentPinballGame->hatchMachineActive)
|
||||
gCurrentPinballGame->hatchMachineNewHit = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->targetBumperHitCounter == 11)
|
||||
gCurrentPinballGame->secondaryBall = gCurrentPinballGame->ballStates;
|
||||
|
||||
modRes = (gCurrentPinballGame->targetBumperHitCounter - 1) % 4;
|
||||
gMain.spriteGroups[modRes + 47].available = 1;
|
||||
gCurrentPinballGame->splashEffectFrameIndex[modRes] = 0;
|
||||
gCurrentPinballGame->splashEffectFrameTimer[modRes] = 0;
|
||||
gCurrentPinballGame->splashEffectPositionIndex[modRes] = gCurrentPinballGame->targetBumperHitCounter - 1;
|
||||
|
||||
if (gCurrentPinballGame->targetBumperHitCounter > 12)
|
||||
gCurrentPinballGame->targetBumperHitCounter = 0;
|
||||
|
||||
if (index == 0 && gCurrentPinballGame->ball->velocity.y > -120)
|
||||
gCurrentPinballGame->ball->velocity.y = -120;
|
||||
|
||||
if (index == 2 && gCurrentPinballGame->ball->velocity.y > -180)
|
||||
gCurrentPinballGame->ball->velocity.y = -180;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
if (gCurrentPinballGame->ballCollisionZone != 15)
|
||||
{
|
||||
gCurrentPinballGame->ballCollisionZone = 15;
|
||||
index = gSapphireTargetBumperIndexMap[gCurrentPinballGame->targetBumperHitCounter];
|
||||
gCurrentPinballGame->targetBumperAnimTimers[index] = 10;
|
||||
gCurrentPinballGame->targetBumperHitCounter++;
|
||||
|
||||
modRes = (gCurrentPinballGame->targetBumperHitCounter -1) % 4;
|
||||
gMain.spriteGroups[modRes + 47].available = 1;
|
||||
gCurrentPinballGame->splashEffectFrameIndex[modRes] = 0;
|
||||
gCurrentPinballGame->splashEffectFrameTimer[modRes] = 0;
|
||||
gCurrentPinballGame->splashEffectPositionIndex[modRes] = gCurrentPinballGame->targetBumperHitCounter - 1;
|
||||
if (index == 1 && gCurrentPinballGame->ball->velocity.y > -150)
|
||||
gCurrentPinballGame->ball->velocity.y = -150;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
if (gCurrentPinballGame->ball->positionQ0.y < 80)
|
||||
{
|
||||
if (gCurrentPinballGame->pelipperState == 1)
|
||||
gCurrentPinballGame->pelipperState = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->pelipperState == 2)
|
||||
{
|
||||
gCurrentPinballGame->pelipperState = 3;
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
195
src/collision_spheal.c
Normal file
195
src/collision_spheal.c
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
s16 CollisionCheck_Spheal(struct Vector16 *arg0, u16 *arg1)
|
||||
{
|
||||
u16 sp0;
|
||||
u8 sp2;
|
||||
u16 sp4_return;
|
||||
|
||||
struct Vector16 div_result;
|
||||
struct Vector16 div_remainder;
|
||||
s32 tileMapPage;
|
||||
s32 boardLayer;
|
||||
s16 collisionTileIndex;
|
||||
u8 enum1, enum2;
|
||||
|
||||
sp4_return = 0;
|
||||
gCurrentPinballGame->ball->spinAcceleration = 0;
|
||||
|
||||
div_result.x = arg0->x / 8;
|
||||
div_result.y = arg0->y / 8;
|
||||
div_remainder.x = arg0->x % 8;
|
||||
div_remainder.y = arg0->y % 8;
|
||||
tileMapPage = div_result.y / 64;
|
||||
boardLayer = gCurrentPinballGame->boardLayerDepth;
|
||||
div_result.y %= 64;
|
||||
|
||||
collisionTileIndex = gBoardConfig.fieldLayout.collisionTileMap[boardLayer + tileMapPage][div_result.y * 64 + div_result.x];
|
||||
sp0 = gBoardConfig.fieldLayout.collisionAngleMap[boardLayer + tileMapPage][collisionTileIndex * 64 + div_remainder.y * 8 + div_remainder.x];
|
||||
sp2 = gBoardConfig.fieldLayout.collisionTypeMap[boardLayer + tileMapPage][collisionTileIndex * 64 + div_remainder.y * 8 + div_remainder.x];
|
||||
|
||||
CheckSphealEntityCollision(arg0, &sp0, &sp2);
|
||||
|
||||
enum1 = sp2 & 0xF;
|
||||
enum2 = sp2 >> 4;
|
||||
switch (enum1)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 6:
|
||||
gCurrentPinballGame->collisionSurfaceType = enum1 - 1;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp0;
|
||||
if (*arg1 >= 0x3FF0 && *arg1 <= 0x4010)
|
||||
{
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < (gBoardConfig.fieldLayout.ballSpawnX - 8) ||
|
||||
gCurrentPinballGame->ball->positionQ0.y < (gBoardConfig.fieldLayout.ballSpawnY - 8))
|
||||
{
|
||||
if (gCurrentPinballGame->ball->spinSpeed > 0)
|
||||
{
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else if (gCurrentPinballGame->ball->spinSpeed != 0)
|
||||
{
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain.systemFrameCount & 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = 40;
|
||||
gCurrentPinballGame->ball->spinSpeed = 1;
|
||||
*arg1 = 0x3E00;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->spinAcceleration = -40;
|
||||
gCurrentPinballGame->ball->spinSpeed = -1;
|
||||
*arg1 = 0x4100;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sp4_return = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gCurrentPinballGame->collisionSurfaceType = 0;
|
||||
gCurrentPinballGame->collisionResponseType = 1;
|
||||
*arg1 = sp0 & 0x0000FFF0;
|
||||
|
||||
if (gCurrentPinballGame->ball->positionQ0.x < 120)
|
||||
gCurrentPinballGame->minionHitFlashTimer[0] = 24;
|
||||
else
|
||||
gCurrentPinballGame->minionHitFlashTimer[1] = 24;
|
||||
|
||||
sp4_return = 1;
|
||||
break;
|
||||
case 5:
|
||||
enum2 = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessSphealCollisionEvent(enum2, &sp4_return, arg1);
|
||||
return sp4_return;
|
||||
}
|
||||
|
||||
void CheckSphealEntityCollision(struct Vector16 *arg0, u16 *arg1, u8 *arg2)
|
||||
{
|
||||
s16 i;
|
||||
s16 deltaX, deltaY;
|
||||
u16 lowerReadFromRom;
|
||||
u16 upperReadFromRom;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
|
||||
if (gCurrentPinballGame->flyingEnemyCollisionType[i] == 1)
|
||||
{
|
||||
if ((arg2[0] & 0xf) != 0)
|
||||
continue;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->flyingEnemyCollisionPos[i].x;
|
||||
deltaY = arg0->y - gCurrentPinballGame->flyingEnemyCollisionPos[i].y;
|
||||
if ((deltaX >= 64 || deltaX < 0) || (deltaY >= 64 || deltaY < 0))
|
||||
continue;
|
||||
|
||||
upperReadFromRom = gSphealFrozenIceCollisionMap[(deltaY * 64) + deltaX] & 0xFFF0;
|
||||
lowerReadFromRom = gSphealFrozenIceCollisionMap[(deltaY * 64) + deltaX] & 0xF;
|
||||
if (lowerReadFromRom == 0)
|
||||
continue;
|
||||
|
||||
if (gCurrentPinballGame->ballRespawnState != 0)
|
||||
continue;
|
||||
|
||||
arg1[0] = upperReadFromRom;
|
||||
arg2[0] = lowerReadFromRom;
|
||||
arg2[0] = 6;
|
||||
gCurrentPinballGame->flyingEnemyState[i] = 4;
|
||||
}
|
||||
else if (gCurrentPinballGame->flyingEnemyCollisionType[i] != 0)
|
||||
{
|
||||
if ((arg2[0] & 0xf) != 0)
|
||||
continue;
|
||||
|
||||
deltaX = arg0->x - gCurrentPinballGame->flyingEnemyCollisionPos[i].x;
|
||||
deltaY = arg0->y - gCurrentPinballGame->flyingEnemyCollisionPos[i].y;
|
||||
if ((deltaX >= 64 || deltaX < 0) || (deltaY >= 64 || deltaY < 0))
|
||||
continue;
|
||||
|
||||
upperReadFromRom = gSphealCrackedIceCollisionMap[(deltaY * 64) + deltaX] & 0xFFF0;
|
||||
lowerReadFromRom = gSphealCrackedIceCollisionMap[(deltaY * 64) + deltaX] & 0xF;
|
||||
if (lowerReadFromRom == 0)
|
||||
continue;
|
||||
|
||||
arg1[0] = upperReadFromRom;
|
||||
arg2[0] = lowerReadFromRom;
|
||||
arg2[0] = 6;
|
||||
if (gCurrentPinballGame->flyingEnemyCollisionType[i] == 2)
|
||||
{
|
||||
gCurrentPinballGame->flyingEnemyState[i] = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->flyingEnemyHitCooldown[i] = 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessSphealCollisionEvent(u8 arg0_enum, u16 *arg1, u16 *arg2)
|
||||
{
|
||||
switch (arg0_enum)
|
||||
{
|
||||
case 2:
|
||||
gCurrentPinballGame->knockdownTargetIndex[2] = 0;
|
||||
gCurrentPinballGame->knockdownPhase[2] = 2;
|
||||
break;
|
||||
case 3:
|
||||
gCurrentPinballGame->knockdownTargetIndex[2] = 1;
|
||||
gCurrentPinballGame->knockdownPhase[2] = 2;
|
||||
break;
|
||||
case 8:
|
||||
gCurrentPinballGame->knockdownTargetIndex[2] = 0;
|
||||
gCurrentPinballGame->knockdownPhase[2] = 1;
|
||||
gCurrentPinballGame->knockdownStunTimer[2] = 100;
|
||||
break;
|
||||
case 9:
|
||||
gCurrentPinballGame->knockdownTargetIndex[2] = 1;
|
||||
gCurrentPinballGame->knockdownPhase[2] = 1;
|
||||
gCurrentPinballGame->knockdownStunTimer[2] = 100;
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
break;
|
||||
}
|
||||
}
|
||||
416
src/display.c
Normal file
416
src/display.c
Normal file
|
|
@ -0,0 +1,416 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
void FadeInFromWhite(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void*)PLTT, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaFill16(3, 0x7FFF, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void*)PLTT, PLTT_SIZE);
|
||||
|
||||
UnblankLCD();
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FadeOutToWhite(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void*)PLTT, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaFill16(3, 0x7FFF, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
ForceBlankLCD();
|
||||
MainLoopIter();
|
||||
ClearGraphicsMemory();
|
||||
}
|
||||
|
||||
void FadeInWithCustomPalettes(u8 * arg0, u8 * arg1, void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, arg0, gPaletteFadeBuffers[1], 0x200);
|
||||
DmaCopy16(3, arg1, gPaletteFadeBuffers[2], 0x200);
|
||||
DmaFill16(3, 0, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void*)PLTT, PLTT_SIZE);
|
||||
|
||||
UnblankLCD();
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FadeOutToBlack(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void*)PLTT, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaFill16(3, 0, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
MainLoopIter();
|
||||
}
|
||||
|
||||
void InterpolatePaletteStep(u16 arg0)
|
||||
{
|
||||
u16 var0;
|
||||
u16 var1;
|
||||
u16 b[2];
|
||||
u16 g[2];
|
||||
u16 r[2];
|
||||
u16 spC[4];
|
||||
|
||||
spC[0] = 0;
|
||||
spC[1] = 2;
|
||||
spC[2] = 1;
|
||||
spC[3] = 3;
|
||||
var0 = spC[arg0 & 3] * 128;
|
||||
var1 = var0 + 128;
|
||||
|
||||
arg0 &= ~3;
|
||||
arg0 += 4;
|
||||
|
||||
while(var0 < var1)
|
||||
{
|
||||
r[0] = gPaletteFadeBuffers[0][var0] & 0x1F;
|
||||
g[0] = (gPaletteFadeBuffers[0][var0] & 0x3E0) >> 5;
|
||||
b[0] = (gPaletteFadeBuffers[0][var0] & 0x7C00) >> 10;
|
||||
|
||||
r[1] = gPaletteFadeBuffers[1][var0] & 0x1F;
|
||||
g[1] = (gPaletteFadeBuffers[1][var0] & 0x3E0) >> 5;
|
||||
b[1] = (gPaletteFadeBuffers[1][var0] & 0x7C00) >> 10;
|
||||
|
||||
if(b[0] < b[1])
|
||||
b[0] += ((b[1] - b[0]) * arg0) >> 5;
|
||||
else
|
||||
b[0] -= ((b[0] - b[1]) * arg0) >> 5;
|
||||
|
||||
if(g[0] < g[1])
|
||||
g[0] += ((g[1] - g[0]) * arg0) >> 5;
|
||||
else
|
||||
g[0] -= ((g[0] - g[1]) * arg0) >> 5;
|
||||
|
||||
if(r[0] < r[1])
|
||||
r[0] += ((r[1] - r[0]) * arg0) >> 5;
|
||||
else
|
||||
r[0] -= ((r[0] - r[1]) * arg0) >> 5;
|
||||
|
||||
gPaletteFadeBuffers[2][var0] = (b[0] << 10) | (g[0] << 5) | r[0];
|
||||
var0++;
|
||||
}
|
||||
}
|
||||
|
||||
void DarkenPalette(u8 * pal, u8 * dest, u16 arg2, u16 arg3)
|
||||
{
|
||||
u16 i;
|
||||
u16 b[2];
|
||||
u16 g[2];
|
||||
u16 r[2];
|
||||
DmaCopy16(3, pal, gPaletteFadeBuffers[0], arg2);
|
||||
DmaFill16(3, 0, gPaletteFadeBuffers[1], arg2);
|
||||
|
||||
for(i = 0; i < arg2; i++)
|
||||
{
|
||||
r[0] = gPaletteFadeBuffers[0][i] & 0x1F;
|
||||
g[0] = (gPaletteFadeBuffers[0][i] & 0x3E0) >> 5;
|
||||
b[0] = (gPaletteFadeBuffers[0][i] & 0x7C00) >> 10;
|
||||
|
||||
r[1] = gPaletteFadeBuffers[1][i] & 0x1F;
|
||||
g[1] = (gPaletteFadeBuffers[1][i] & 0x3E0) >> 5;
|
||||
b[1] = (gPaletteFadeBuffers[1][i] & 0x7C00) >> 10;
|
||||
|
||||
if(b[0] > b[1])
|
||||
b[0] -= (b[0] * arg3) >> 5;
|
||||
else
|
||||
b[0] = b[1];
|
||||
|
||||
if(g[0] > g[1])
|
||||
g[0] -= (g[0] * arg3) >> 5;
|
||||
else
|
||||
g[0] = g[1];
|
||||
|
||||
if(r[0] > r[1])
|
||||
r[0] -= (r[0] * arg3) >> 5;
|
||||
else
|
||||
r[0] = r[1];
|
||||
|
||||
gPaletteFadeBuffers[2][i] = (b[0] << 10) | (g[0] << 5) | r[0];
|
||||
}
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], dest, arg2);
|
||||
}
|
||||
|
||||
void BrightenPalette(u8 * pal, u8 * dest, u16 arg2, u16 arg3)
|
||||
{
|
||||
u16 i;
|
||||
u16 b[2];
|
||||
u16 g[2];
|
||||
u16 r[2];
|
||||
DmaCopy16(3, pal, gPaletteFadeBuffers[0], arg2);
|
||||
DmaFill16(3, 0x7FFF, gPaletteFadeBuffers[1], arg2);
|
||||
|
||||
for(i = 0; i < arg2; i++)
|
||||
{
|
||||
r[0] = gPaletteFadeBuffers[0][i] & 0x1F;
|
||||
g[0] = (gPaletteFadeBuffers[0][i] & 0x3E0) >> 5;
|
||||
b[0] = (gPaletteFadeBuffers[0][i] & 0x7C00) >> 10;
|
||||
|
||||
r[1] = gPaletteFadeBuffers[1][i] & 0x1F;
|
||||
g[1] = (gPaletteFadeBuffers[1][i] & 0x3E0) >> 5;
|
||||
b[1] = (gPaletteFadeBuffers[1][i] & 0x7C00) >> 10;
|
||||
|
||||
if(b[0] < b[1])
|
||||
b[0] += ((b[1] - b[0]) * arg3) >> 5;
|
||||
else
|
||||
b[0] -= ((b[0] - b[1]) * arg3) >> 5;
|
||||
|
||||
if(g[0] < g[1])
|
||||
g[0] += ((g[1] - g[0]) * arg3) >> 5;
|
||||
else
|
||||
g[0] -= ((g[0] - g[1]) * arg3) >> 5;
|
||||
|
||||
if(r[0] < r[1])
|
||||
r[0] += ((r[1] - r[0]) * arg3) >> 5;
|
||||
else
|
||||
r[0] -= ((r[0] - r[1]) * arg3) >> 5;
|
||||
|
||||
gPaletteFadeBuffers[2][i] = (b[0] << 10) | (g[0] << 5) | r[0];
|
||||
}
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], dest, arg2);
|
||||
}
|
||||
|
||||
void FlashWhiteTransitionIn(void)
|
||||
{
|
||||
REG_BLDY = 0x10;
|
||||
REG_BLDCNT = ((REG_DISPCNT & (DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON)) >> 8) | BLDCNT_EFFECT_LIGHTEN | BLDCNT_TGT1_BD;
|
||||
REG_DISPCNT &= ~DISPCNT_FORCED_BLANK;
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
REG_BLDY = 0x10;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0x8;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0;
|
||||
MainLoopIter();
|
||||
REG_BLDCNT = 0;
|
||||
}
|
||||
|
||||
void FlashWhiteTransitionOut(void)
|
||||
{
|
||||
REG_BLDY = 0;
|
||||
REG_BLDCNT = ((REG_DISPCNT & (DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON)) >> 8) | BLDCNT_EFFECT_LIGHTEN | BLDCNT_TGT1_BD;
|
||||
REG_BLDY = 0;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0x8;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0x10;
|
||||
MainLoopIter();
|
||||
DmaFill16(3, 0, (void*)VRAM, VRAM_SIZE);
|
||||
REG_BG0HOFS = 0;
|
||||
REG_BG0VOFS = 0;
|
||||
REG_BG1HOFS = 0;
|
||||
REG_BG1VOFS = 0;
|
||||
REG_BG2HOFS = 0;
|
||||
REG_BG2VOFS = 0;
|
||||
REG_BG3HOFS = 0;
|
||||
REG_BG3VOFS = 0;
|
||||
MainLoopIter();
|
||||
}
|
||||
|
||||
void UnblankLCD(void)
|
||||
{
|
||||
REG_DISPCNT &= ~DISPCNT_FORCED_BLANK;
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
}
|
||||
|
||||
void ForceBlankLCD(void)
|
||||
{
|
||||
gMain.dispcntBackup |= DISPCNT_FORCED_BLANK;
|
||||
REG_DISPCNT |= DISPCNT_FORCED_BLANK;
|
||||
}
|
||||
|
||||
void DisableDisplayInterrupts(void)
|
||||
{
|
||||
REG_DISPSTAT &= ~DISPSTAT_VBLANK_INTR;
|
||||
REG_DISPSTAT &= ~DISPSTAT_VCOUNT_INTR;
|
||||
REG_IE &= 0x3FFF;
|
||||
REG_IE &= 0x3FFE;
|
||||
if(REG_IE == 0)
|
||||
REG_IME = 0;
|
||||
REG_IF |= 1;
|
||||
}
|
||||
|
||||
void PrintString(u16 glyph, u16 palette, int x, int y, int width, int height)
|
||||
{
|
||||
u16 i, j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
for (i = 0; i < width; i++)
|
||||
gBG0TilemapBuffer[y * 0x20 + x + j * 0x20 + i] = (glyph + j * 0x20 + i) | (palette << 12);
|
||||
}
|
||||
|
||||
void CopyString(int srcX, int srcY, int destX, int destY, int width, int height)
|
||||
{
|
||||
u16 i, j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
for (i = 0; i < width; i++)
|
||||
gBG0TilemapBuffer[destY * 0x20 + destX + j * 0x20 + i] = gBG0TilemapBuffer[srcY * 0x20 + srcX + j * 0x20 + i];
|
||||
}
|
||||
|
||||
void SetStringPalette(int x, int y, int width, int height, u16 palette)
|
||||
{
|
||||
u16 i, j;
|
||||
u16 index;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
index = y * 0x20 + x + j * 0x20 + i;
|
||||
gBG0TilemapBuffer[index] = (gBG0TilemapBuffer[index] & 0xFFF) | (palette << 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This requires volatile parameters to match. There is no reason, *ever*, to do this.
|
||||
void CopyBgTilesRect(void *volatile src, void *volatile dest, s16 width, s16 height)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
DmaCopy16(3, (u8 *)src + 0x400 * j, (u8 *)dest + 0x400 * j, width * 0x20);
|
||||
}
|
||||
}
|
||||
|
||||
// This function is unused. It appears to operates on a pixel canvas where each "tile" is represented by
|
||||
// 2 bytes.
|
||||
void CopyPixelCanvasRect(void *volatile src, void *volatile dest, s16 width, s16 height)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
DmaCopy16(3, (u8 *)src + 0x40 * j, (u8 *)dest + 0x40 * j, width * 2);
|
||||
}
|
||||
}
|
||||
|
||||
// This function is unused.
|
||||
void Unused_FadeInWithCustomPalettes(void *src1, void *src2, void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, src1, gPaletteFadeBuffers[1], BG_PLTT_SIZE);
|
||||
DmaCopy16(3, src2, gPaletteFadeBuffers[2], BG_PLTT_SIZE);
|
||||
DmaFill16(3, RGB_WHITE, gPaletteFadeBuffers, PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, PLTT_SIZE);
|
||||
|
||||
UnblankLCD();
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
|
||||
for (i = 0; i <= 0x20; i += 0x10)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 0x20)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function is unused.
|
||||
void Unused_FadeOutToWhite(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void *)PLTT, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaFill16(3, RGB_WHITE, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
|
||||
for (i = 0; i <= 0x20; i += 0x10)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 0x20)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
}
|
||||
MainLoopIter();
|
||||
}
|
||||
473
src/evolution_mode.c
Normal file
473
src/evolution_mode.c
Normal file
|
|
@ -0,0 +1,473 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern struct SongHeader se_evo_item_appear;
|
||||
extern struct SongHeader se_evo_item_finish_appear;
|
||||
extern struct SongHeader se_evo_item_collected;
|
||||
|
||||
extern const u8 gDefaultBallPalette[];
|
||||
extern const u8 *gEvoItemAppear_GfxList[];
|
||||
extern const u8 gEvoItemPalettes[][0x20];
|
||||
extern const s16 gEvoItemAppearFrameThresholds[];
|
||||
extern const u16 gEvoItemAnimOamFramesets[58][15];
|
||||
extern const struct Vector16 gEvoItemPositions[][8];
|
||||
|
||||
void CleanupEvolutionModeState(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
LoadPortraitGraphics(0, 0);
|
||||
gCurrentPinballGame->portraitDisplayState = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (i < gCurrentPinballGame->evoItemCount)
|
||||
gCurrentPinballGame->catchLights[i] = 1;
|
||||
else
|
||||
gCurrentPinballGame->catchLights[i] = 0;
|
||||
}
|
||||
|
||||
gMain.fieldSpriteGroups[13]->available = 0;
|
||||
gCurrentPinballGame->trapAnimState = 0;
|
||||
gCurrentPinballGame->bonusTrapEnabled = 0;
|
||||
ResetEventState();
|
||||
}
|
||||
|
||||
void InitEvolutionMode(void)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->boardModeType = 2;
|
||||
gCurrentPinballGame->eventTimer = gCurrentPinballGame->timerBonus + 7200;
|
||||
gCurrentPinballGame->timerBonus = 0;
|
||||
gCurrentPinballGame->saverTimeRemaining = 3600;
|
||||
if (gCurrentPinballGame->currentSpecies == SPECIES_WURMPLE)
|
||||
{
|
||||
gCurrentPinballGame->evoItemGfxIndex = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_GLOOM)
|
||||
{
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
gCurrentPinballGame->evoItemGfxIndex = 1;
|
||||
else
|
||||
gCurrentPinballGame->evoItemGfxIndex = 7;
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_CLAMPERL)
|
||||
{
|
||||
gCurrentPinballGame->evoItemGfxIndex = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->evoItemGfxIndex = gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionMethod - 1;
|
||||
if (gCurrentPinballGame->evoItemGfxIndex < 0)
|
||||
gCurrentPinballGame->evoItemGfxIndex = 0;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gDefaultBallPalette, (void *)0x05000180, 0x20);
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->rouletteSlotActive = 0;
|
||||
gCurrentPinballGame->catchModeEventTimer = 0;
|
||||
gCurrentPinballGame->evoItemSlotIndex = 0;
|
||||
gCurrentPinballGame->evoItemsCaught = 0;
|
||||
gCurrentPinballGame->evoModeResetFlag = 0;
|
||||
gCurrentPinballGame->evoItemAppearTimer = 0;
|
||||
LoadPortraitGraphics(3, 0);
|
||||
}
|
||||
|
||||
void UpdateEvolutionMode(void)
|
||||
{
|
||||
s16 i, j;
|
||||
s16 var0;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
if (gCurrentPinballGame->boardModeType && gCurrentPinballGame->eventTimer < 2 && gCurrentPinballGame->boardSubState < 8)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
m4aSongNumStart(MUS_END_OF_BALL2);
|
||||
gCurrentPinballGame->stageTimer = 200;
|
||||
gCurrentPinballGame->boardSubState = 8;
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 0:
|
||||
if (gCurrentPinballGame->evoModeShuffleRound < 2)
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
gCurrentPinballGame->evoItemShufflePool[i] = i;
|
||||
|
||||
index = (Random() + gMain.systemFrameCount) % 5;
|
||||
gCurrentPinballGame->evoShuffledSlots[0] = gCurrentPinballGame->evoItemShufflePool[index];
|
||||
for (i = index; i < 7; i++)
|
||||
gCurrentPinballGame->evoItemShufflePool[i] = gCurrentPinballGame->evoItemShufflePool[i + 1];
|
||||
|
||||
index = (Random() + gMain.systemFrameCount) % 4;
|
||||
gCurrentPinballGame->evoShuffledSlots[1] = gCurrentPinballGame->evoItemShufflePool[index];
|
||||
for (i = index; i < 6; i++)
|
||||
gCurrentPinballGame->evoItemShufflePool[i] = gCurrentPinballGame->evoItemShufflePool[i + 1];
|
||||
|
||||
index = (Random() + gMain.systemFrameCount) % 3;
|
||||
gCurrentPinballGame->evoShuffledSlots[2] = gCurrentPinballGame->evoItemShufflePool[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
gCurrentPinballGame->evoItemShufflePool[i] = i;
|
||||
|
||||
index = (Random() + gMain.systemFrameCount) % 6;
|
||||
gCurrentPinballGame->evoShuffledSlots[0] = gCurrentPinballGame->evoItemShufflePool[index];
|
||||
for (i = index; i < 7; i++)
|
||||
gCurrentPinballGame->evoItemShufflePool[i] = gCurrentPinballGame->evoItemShufflePool[i + 1];
|
||||
|
||||
index = (Random() + gMain.systemFrameCount) % 7;
|
||||
gCurrentPinballGame->evoShuffledSlots[1] = gCurrentPinballGame->evoItemShufflePool[index];
|
||||
for (i = index; i < 6; i++)
|
||||
gCurrentPinballGame->evoItemShufflePool[i] = gCurrentPinballGame->evoItemShufflePool[i + 1];
|
||||
|
||||
index = (Random() + gMain.systemFrameCount) % 6;
|
||||
gCurrentPinballGame->evoShuffledSlots[2] = gCurrentPinballGame->evoItemShufflePool[index];
|
||||
for (i = index; i < 5; i++)
|
||||
gCurrentPinballGame->evoItemShufflePool[i] = gCurrentPinballGame->evoItemShufflePool[i + 1];
|
||||
|
||||
if (gMain.selectedField == FIELD_SAPPHIRE && gCurrentPinballGame->numCompletedBonusStages < 5)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->evoShuffledSlots[i] == 5)
|
||||
{
|
||||
index = (Random() + gMain.systemFrameCount) % 5;
|
||||
gCurrentPinballGame->evoShuffledSlots[i] = gCurrentPinballGame->evoItemShufflePool[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->evoModeShuffleRound++;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 1:
|
||||
gCurrentPinballGame->evoItemSlotIndex = gCurrentPinballGame->evoShuffledSlots[gCurrentPinballGame->evoItemsCaught];
|
||||
gCurrentPinballGame->evoItemPosX = gEvoItemPositions[gMain.selectedField][gCurrentPinballGame->evoItemSlotIndex].x;
|
||||
gCurrentPinballGame->evoItemPosY = gEvoItemPositions[gMain.selectedField][gCurrentPinballGame->evoItemSlotIndex].y;
|
||||
gCurrentPinballGame->evoItemAppearTimer = 80;
|
||||
gMain.fieldSpriteGroups[40]->available = 1;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 2:
|
||||
UpdateEvolutionItemAnimation();
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
break;
|
||||
case 3:
|
||||
gCurrentPinballGame->trapAnimState = 1;
|
||||
if (gCurrentPinballGame->stageTimer < 8)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowBonusTrapSprite();
|
||||
gCurrentPinballGame->trapAnimState = 2;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
AnimateBonusTrapSprite();
|
||||
if (gCurrentPinballGame->ballCatchState == 4)
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 5:
|
||||
gCurrentPinballGame->boardModeType = 3;
|
||||
gCurrentPinballGame->preEvoSpecies = gCurrentPinballGame->currentSpecies;
|
||||
RegisterCaptureOrEvolution(1);
|
||||
gCurrentPinballGame->postEvoSpecies = gCurrentPinballGame->currentSpecies;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 6:
|
||||
if (gCurrentPinballGame->modeAnimTimer == 148)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
if (gMain.spriteGroups[13].available)
|
||||
{
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer >= 80)
|
||||
{
|
||||
RunEvolutionCutscene();
|
||||
if (gCurrentPinballGame->boardSubState == 6)
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RunEvolutionCutscene();
|
||||
if (gCurrentPinballGame->boardSubState == 6)
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (gCurrentPinballGame->modeAnimTimer == 148)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
if (gCurrentPinballGame->stageTimer < 280)
|
||||
{
|
||||
if (gCurrentPinballGame->stageTimer == 0)
|
||||
{
|
||||
InitEvolutionSuccessDisplay();
|
||||
m4aSongNumStart(MUS_SUCCESS2);
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimateEvolutionSuccessScreen();
|
||||
if (gCurrentPinballGame->stageTimer < 230)
|
||||
{
|
||||
if (gCurrentPinballGame->nameRevealAnimFrame == 150)
|
||||
gCurrentPinballGame->nameRevealAnimFrame--;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 270)
|
||||
{
|
||||
LoadPortraitGraphics(0, 0);
|
||||
gCurrentPinballGame->portraitDisplayState = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->scoreCounterAnimationEnabled)
|
||||
gCurrentPinballGame->stageTimer = 181;
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 180) {
|
||||
gCurrentPinballGame->scoreCounterAnimationEnabled = TRUE;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000000;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer < 30)
|
||||
{
|
||||
gMain.scoreOverlayActive = 1;
|
||||
var0 = gCurrentPinballGame->stageTimer;
|
||||
gCurrentPinballGame->cutsceneTilemapColumn = gCurrentPinballGame->stageTimer;
|
||||
for (i = 0; i <= var0; i++)
|
||||
{
|
||||
for (j = 2; j < 12; j++)
|
||||
gBG0TilemapBuffer[((j + 15) * 0x20) + i] = 0xC100;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x06002000, 0x800);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer >= 240 && gCurrentPinballGame->stageTimer < 270)
|
||||
{
|
||||
var0 = gCurrentPinballGame->stageTimer - 240;
|
||||
for (i = 0; i <= var0; i ++)
|
||||
{
|
||||
for (j = 2; j < 12; j++)
|
||||
gBG0TilemapBuffer[((j + 15) << 5) + i] = 0x1FF;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x06002000, 0x800);
|
||||
if (gCurrentPinballGame->stageTimer == 269)
|
||||
{
|
||||
gMain.scoreOverlayActive = 0;
|
||||
gMain.blendControl = 0;
|
||||
gMain.blendBrightness = 0;
|
||||
gMain.blendAlpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 40;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 24)
|
||||
{
|
||||
if (gCurrentPinballGame->evoItemCount < 3)
|
||||
{
|
||||
gCurrentPinballGame->evoCatchLightSlot1 = gCurrentPinballGame->evoItemCount;
|
||||
gCurrentPinballGame->evoCatchLightSlot2 = gCurrentPinballGame->evoItemCount;
|
||||
gCurrentPinballGame->catchLights[gCurrentPinballGame->evoCatchLightSlot1] = 1;
|
||||
gCurrentPinballGame->evoBlinkTimer = 120;
|
||||
gCurrentPinballGame->evoItemCount++;
|
||||
if (gCurrentPinballGame->evoItemCount < 3)
|
||||
{
|
||||
gCurrentPinballGame->evoCatchLightSlot2 = gCurrentPinballGame->evoItemCount;
|
||||
gCurrentPinballGame->catchLights[gCurrentPinballGame->evoCatchLightSlot2] = 1;
|
||||
gCurrentPinballGame->evoBlinkTimer = 120;
|
||||
gCurrentPinballGame->evoItemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->currentSpecies == SPECIES_NINJASK)
|
||||
{
|
||||
gCurrentPinballGame->caughtMonCount++;
|
||||
if (gCurrentPinballGame->bonusMonCatchCount < 99)
|
||||
gCurrentPinballGame->bonusMonCatchCount++;
|
||||
|
||||
if (gCurrentPinballGame->caughtMonCount == 15)
|
||||
gCurrentPinballGame->oneUpAnimTimer = 92;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->caughtMonCount++;
|
||||
if (gCurrentPinballGame->caughtMonCount == 15)
|
||||
gCurrentPinballGame->oneUpAnimTimer = 92;
|
||||
|
||||
if (gCurrentPinballGame->bonusMonCatchCount < 99)
|
||||
gCurrentPinballGame->bonusMonCatchCount++;
|
||||
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
group = gMain.fieldSpriteGroups[32];
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset - 56;
|
||||
|
||||
gMain.fieldSpriteGroups[32]->available = 0;
|
||||
UpdateEvolutionItemAnimation();
|
||||
gMain.fieldSpriteGroups[40]->available = 0;
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
AnimateBonusTrapSprite();
|
||||
gMain.fieldSpriteGroups[13]->available = 0;
|
||||
gCurrentPinballGame->shopTransitionActive = 1;
|
||||
gCurrentPinballGame->shopAnimTimer = 0;
|
||||
gCurrentPinballGame->evolutionShopActive = 0;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
if (gCurrentPinballGame->allHolesLit)
|
||||
gCurrentPinballGame->allHolesLitDelayTimer = 120;
|
||||
break;
|
||||
case 9:
|
||||
CleanupEvolutionModeState();
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 10:
|
||||
if (gCurrentPinballGame->stageTimer)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->catchLights[2] == 1)
|
||||
RequestBoardStateTransition(3);
|
||||
else
|
||||
RequestBoardStateTransition(1);
|
||||
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEvolutionItemAnimation(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const u16 *src;
|
||||
struct Vector32 tempVector;
|
||||
int xx, yy;
|
||||
int squaredMagnitude;
|
||||
s16 index;
|
||||
|
||||
index = (gMain.systemFrameCount % 75) / 3;
|
||||
group = gMain.fieldSpriteGroups[32];
|
||||
if (gCurrentPinballGame->evoItemAppearTimer)
|
||||
{
|
||||
group = gMain.fieldSpriteGroups[40];
|
||||
if (gCurrentPinballGame->evoItemAppearTimer == 80)
|
||||
{
|
||||
gCurrentPinballGame->activePortraitType = 15;
|
||||
DmaCopy16(3, gEvoItemAppear_GfxList[gCurrentPinballGame->evoItemGfxIndex], (void *)0x06015800, 0x1C00);
|
||||
DmaCopy16(3, &gEvoItemPalettes[gCurrentPinballGame->evoItemGfxIndex], (void *)0x050003E0, 0x20);
|
||||
gCurrentPinballGame->evoItemAnimFrame = 0;
|
||||
gCurrentPinballGame->evoItemAnimFrameTimer = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->evoItemAppearTimer == 60)
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_evo_item_appear);
|
||||
|
||||
if (gEvoItemAppearFrameThresholds[gCurrentPinballGame->evoItemAnimFrame] > gCurrentPinballGame->evoItemAnimFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->evoItemAnimFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->evoItemAnimFrameTimer = 1;
|
||||
gCurrentPinballGame->evoItemAnimFrame++;
|
||||
if (gCurrentPinballGame->evoItemAnimFrame == 29)
|
||||
{
|
||||
gCurrentPinballGame->evoItemAnimFrame = 28;
|
||||
gCurrentPinballGame->evoItemAppearTimer = 1;
|
||||
gMain.fieldSpriteGroups[40]->available = 0;
|
||||
gMain.fieldSpriteGroups[32]->available = 1;
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_evo_item_finish_appear);
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
group->baseX = gCurrentPinballGame->evoItemPosX - gCurrentPinballGame->cameraXOffset + 8;
|
||||
group->baseY = gCurrentPinballGame->evoItemPosY - gCurrentPinballGame->cameraYOffset + 8;
|
||||
if (group->baseY < -30)
|
||||
group->baseY = -30;
|
||||
if (group->baseY > 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gEvoItemAnimOamFramesets[gCurrentPinballGame->evoItemAnimFrame][i * 3 + 0];
|
||||
*dst++ = gEvoItemAnimOamFramesets[gCurrentPinballGame->evoItemAnimFrame][i * 3 + 1];
|
||||
*dst++ = gEvoItemAnimOamFramesets[gCurrentPinballGame->evoItemAnimFrame][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->evoItemAppearTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempVector.x = gCurrentPinballGame->ball->positionQ0.x - (gCurrentPinballGame->evoItemPosX + 8);
|
||||
tempVector.y = gCurrentPinballGame->ball->positionQ0.y - (gCurrentPinballGame->evoItemPosY + 8);
|
||||
xx = tempVector.x * tempVector.x;
|
||||
yy = tempVector.y * tempVector.y;
|
||||
squaredMagnitude = xx + yy;
|
||||
if (squaredMagnitude < 82 &&
|
||||
((gCurrentPinballGame->boardLayerDepth == 0 && gCurrentPinballGame->evoItemSlotIndex <= 5) || (gCurrentPinballGame->boardLayerDepth == 2 && gCurrentPinballGame->evoItemSlotIndex > 5)) &&
|
||||
gCurrentPinballGame->evoItemsCaught < 3)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 10000;
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_evo_item_collected);
|
||||
gCurrentPinballGame->boardSubState = 1;
|
||||
gCurrentPinballGame->catchLights[gCurrentPinballGame->evoItemsCaught] = 5;
|
||||
gCurrentPinballGame->evoItemsCaught++;
|
||||
gMain.fieldSpriteGroups[32]->available = 0;
|
||||
if (gCurrentPinballGame->evoItemsCaught == 3)
|
||||
{
|
||||
gCurrentPinballGame->evoItemsCaught = 0;
|
||||
gCurrentPinballGame->boardSubState = 3;
|
||||
}
|
||||
}
|
||||
|
||||
group->baseX = gCurrentPinballGame->evoItemPosX - gCurrentPinballGame->cameraXOffset - 8;
|
||||
group->baseY = gCurrentPinballGame->evoItemPosY - gCurrentPinballGame->cameraYOffset - 8;
|
||||
if (group->baseY < -30)
|
||||
group->baseY = -30;
|
||||
if (group->baseY > 200)
|
||||
group->baseY = 200;
|
||||
|
||||
if (index > 14)
|
||||
index = 14;
|
||||
|
||||
DmaCopy16(3, gEvoItemTilesGfxPtrs[gCurrentPinballGame->evoItemGfxIndex] + index * 0x200, (void *)0x060116C0, 0x200);
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
|
@ -2389,301 +2389,3 @@ s8 CheckAllPokemonCaught(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void FadeInFromWhite(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void*)PLTT, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaFill16(3, 0x7FFF, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void*)PLTT, PLTT_SIZE);
|
||||
|
||||
UnblankLCD();
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FadeOutToWhite(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void*)PLTT, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaFill16(3, 0x7FFF, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
ForceBlankLCD();
|
||||
MainLoopIter();
|
||||
ClearGraphicsMemory();
|
||||
}
|
||||
|
||||
void FadeInWithCustomPalettes(u8 * arg0, u8 * arg1, void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, arg0, gPaletteFadeBuffers[1], 0x200);
|
||||
DmaCopy16(3, arg1, gPaletteFadeBuffers[2], 0x200);
|
||||
DmaFill16(3, 0, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void*)PLTT, PLTT_SIZE);
|
||||
|
||||
UnblankLCD();
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FadeOutToBlack(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void*)PLTT, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaFill16(3, 0, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 31)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, 0x400);
|
||||
}
|
||||
}
|
||||
MainLoopIter();
|
||||
}
|
||||
|
||||
void InterpolatePaletteStep(u16 arg0)
|
||||
{
|
||||
u16 var0;
|
||||
u16 var1;
|
||||
u16 b[2];
|
||||
u16 g[2];
|
||||
u16 r[2];
|
||||
u16 spC[4];
|
||||
|
||||
spC[0] = 0;
|
||||
spC[1] = 2;
|
||||
spC[2] = 1;
|
||||
spC[3] = 3;
|
||||
var0 = spC[arg0 & 3] * 128;
|
||||
var1 = var0 + 128;
|
||||
|
||||
arg0 &= ~3;
|
||||
arg0 += 4;
|
||||
|
||||
while(var0 < var1)
|
||||
{
|
||||
r[0] = gPaletteFadeBuffers[0][var0] & 0x1F;
|
||||
g[0] = (gPaletteFadeBuffers[0][var0] & 0x3E0) >> 5;
|
||||
b[0] = (gPaletteFadeBuffers[0][var0] & 0x7C00) >> 10;
|
||||
|
||||
r[1] = gPaletteFadeBuffers[1][var0] & 0x1F;
|
||||
g[1] = (gPaletteFadeBuffers[1][var0] & 0x3E0) >> 5;
|
||||
b[1] = (gPaletteFadeBuffers[1][var0] & 0x7C00) >> 10;
|
||||
|
||||
if(b[0] < b[1])
|
||||
b[0] += ((b[1] - b[0]) * arg0) >> 5;
|
||||
else
|
||||
b[0] -= ((b[0] - b[1]) * arg0) >> 5;
|
||||
|
||||
if(g[0] < g[1])
|
||||
g[0] += ((g[1] - g[0]) * arg0) >> 5;
|
||||
else
|
||||
g[0] -= ((g[0] - g[1]) * arg0) >> 5;
|
||||
|
||||
if(r[0] < r[1])
|
||||
r[0] += ((r[1] - r[0]) * arg0) >> 5;
|
||||
else
|
||||
r[0] -= ((r[0] - r[1]) * arg0) >> 5;
|
||||
|
||||
gPaletteFadeBuffers[2][var0] = (b[0] << 10) | (g[0] << 5) | r[0];
|
||||
var0++;
|
||||
}
|
||||
}
|
||||
|
||||
void DarkenPalette(u8 * pal, u8 * dest, u16 arg2, u16 arg3)
|
||||
{
|
||||
u16 i;
|
||||
u16 b[2];
|
||||
u16 g[2];
|
||||
u16 r[2];
|
||||
DmaCopy16(3, pal, gPaletteFadeBuffers[0], arg2);
|
||||
DmaFill16(3, 0, gPaletteFadeBuffers[1], arg2);
|
||||
|
||||
for(i = 0; i < arg2; i++)
|
||||
{
|
||||
r[0] = gPaletteFadeBuffers[0][i] & 0x1F;
|
||||
g[0] = (gPaletteFadeBuffers[0][i] & 0x3E0) >> 5;
|
||||
b[0] = (gPaletteFadeBuffers[0][i] & 0x7C00) >> 10;
|
||||
|
||||
r[1] = gPaletteFadeBuffers[1][i] & 0x1F;
|
||||
g[1] = (gPaletteFadeBuffers[1][i] & 0x3E0) >> 5;
|
||||
b[1] = (gPaletteFadeBuffers[1][i] & 0x7C00) >> 10;
|
||||
|
||||
if(b[0] > b[1])
|
||||
b[0] -= (b[0] * arg3) >> 5;
|
||||
else
|
||||
b[0] = b[1];
|
||||
|
||||
if(g[0] > g[1])
|
||||
g[0] -= (g[0] * arg3) >> 5;
|
||||
else
|
||||
g[0] = g[1];
|
||||
|
||||
if(r[0] > r[1])
|
||||
r[0] -= (r[0] * arg3) >> 5;
|
||||
else
|
||||
r[0] = r[1];
|
||||
|
||||
gPaletteFadeBuffers[2][i] = (b[0] << 10) | (g[0] << 5) | r[0];
|
||||
}
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], dest, arg2);
|
||||
}
|
||||
|
||||
void BrightenPalette(u8 * pal, u8 * dest, u16 arg2, u16 arg3)
|
||||
{
|
||||
u16 i;
|
||||
u16 b[2];
|
||||
u16 g[2];
|
||||
u16 r[2];
|
||||
DmaCopy16(3, pal, gPaletteFadeBuffers[0], arg2);
|
||||
DmaFill16(3, 0x7FFF, gPaletteFadeBuffers[1], arg2);
|
||||
|
||||
for(i = 0; i < arg2; i++)
|
||||
{
|
||||
r[0] = gPaletteFadeBuffers[0][i] & 0x1F;
|
||||
g[0] = (gPaletteFadeBuffers[0][i] & 0x3E0) >> 5;
|
||||
b[0] = (gPaletteFadeBuffers[0][i] & 0x7C00) >> 10;
|
||||
|
||||
r[1] = gPaletteFadeBuffers[1][i] & 0x1F;
|
||||
g[1] = (gPaletteFadeBuffers[1][i] & 0x3E0) >> 5;
|
||||
b[1] = (gPaletteFadeBuffers[1][i] & 0x7C00) >> 10;
|
||||
|
||||
if(b[0] < b[1])
|
||||
b[0] += ((b[1] - b[0]) * arg3) >> 5;
|
||||
else
|
||||
b[0] -= ((b[0] - b[1]) * arg3) >> 5;
|
||||
|
||||
if(g[0] < g[1])
|
||||
g[0] += ((g[1] - g[0]) * arg3) >> 5;
|
||||
else
|
||||
g[0] -= ((g[0] - g[1]) * arg3) >> 5;
|
||||
|
||||
if(r[0] < r[1])
|
||||
r[0] += ((r[1] - r[0]) * arg3) >> 5;
|
||||
else
|
||||
r[0] -= ((r[0] - r[1]) * arg3) >> 5;
|
||||
|
||||
gPaletteFadeBuffers[2][i] = (b[0] << 10) | (g[0] << 5) | r[0];
|
||||
}
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], dest, arg2);
|
||||
}
|
||||
|
||||
void FlashWhiteTransitionIn(void)
|
||||
{
|
||||
REG_BLDY = 0x10;
|
||||
REG_BLDCNT = ((REG_DISPCNT & (DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON)) >> 8) | BLDCNT_EFFECT_LIGHTEN | BLDCNT_TGT1_BD;
|
||||
REG_DISPCNT &= ~DISPCNT_FORCED_BLANK;
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
REG_BLDY = 0x10;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0x8;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0;
|
||||
MainLoopIter();
|
||||
REG_BLDCNT = 0;
|
||||
}
|
||||
|
||||
void FlashWhiteTransitionOut(void)
|
||||
{
|
||||
REG_BLDY = 0;
|
||||
REG_BLDCNT = ((REG_DISPCNT & (DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON)) >> 8) | BLDCNT_EFFECT_LIGHTEN | BLDCNT_TGT1_BD;
|
||||
REG_BLDY = 0;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0x8;
|
||||
MainLoopIter();
|
||||
REG_BLDY = 0x10;
|
||||
MainLoopIter();
|
||||
DmaFill16(3, 0, (void*)VRAM, VRAM_SIZE);
|
||||
REG_BG0HOFS = 0;
|
||||
REG_BG0VOFS = 0;
|
||||
REG_BG1HOFS = 0;
|
||||
REG_BG1VOFS = 0;
|
||||
REG_BG2HOFS = 0;
|
||||
REG_BG2VOFS = 0;
|
||||
REG_BG3HOFS = 0;
|
||||
REG_BG3VOFS = 0;
|
||||
MainLoopIter();
|
||||
}
|
||||
|
||||
void UnblankLCD(void)
|
||||
{
|
||||
REG_DISPCNT &= ~DISPCNT_FORCED_BLANK;
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
}
|
||||
|
||||
void ForceBlankLCD(void)
|
||||
{
|
||||
gMain.dispcntBackup |= DISPCNT_FORCED_BLANK;
|
||||
REG_DISPCNT |= DISPCNT_FORCED_BLANK;
|
||||
}
|
||||
|
||||
void DisableDisplayInterrupts(void)
|
||||
{
|
||||
REG_DISPSTAT &= ~DISPSTAT_VBLANK_INTR;
|
||||
REG_DISPSTAT &= ~DISPSTAT_VCOUNT_INTR;
|
||||
REG_IE &= 0x3FFF;
|
||||
REG_IE &= 0x3FFE;
|
||||
if(REG_IE == 0)
|
||||
REG_IME = 0;
|
||||
REG_IF |= 1;
|
||||
}
|
||||
|
|
|
|||
862
src/launcher_and_cutscenes.c
Normal file
862
src/launcher_and_cutscenes.c
Normal file
|
|
@ -0,0 +1,862 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern const u8 gRubyTravelVolbeat_Gfx[][0x480];
|
||||
extern const u8 gSapphireTravelIllumise_Gfx[][0x480];
|
||||
extern const u8 gRubyBoardBonusGfx[];
|
||||
extern const u8 gRubyBoardBonusObjPalette[];
|
||||
extern const u8 gSapphireBoardBonusGfx[];
|
||||
extern const u8 gSapphireBoardBonusObjPalette[];
|
||||
extern const s16 gTravelEventAnimData[][3];
|
||||
extern const s16 gAreaToSpeciesTable[];
|
||||
extern const s16 gAreaRouletteTable[][7];
|
||||
extern u16 gTravelEventSpritesheetOam[][18];
|
||||
extern const s16 gHatchRevealFinalTimings[];
|
||||
extern const u16 gHatchSequentialOamFramesets[22][12];
|
||||
extern const u8 gBoardActionTilesGfx[];
|
||||
extern const u8 gBoardActionObjPal[];
|
||||
extern const u16 gEvolutionSparkleSpritesheetOam[20][12];
|
||||
extern const u8 gHatchFinalTilesGfx[];
|
||||
extern const u8 gHatchFinalPalette[];
|
||||
extern const s16 gSpoinkAnimFrameset[][2];
|
||||
extern const u8 gSpoinkEntity_Gfx[][0x1C0];
|
||||
extern const u8 gOneUpBannerSprite_Gfx[][0x200];
|
||||
extern const u8 gLifeCountDigit_Gfx[][0x40];
|
||||
extern const u8 gOneUpSpritePalette[];
|
||||
|
||||
extern struct SongHeader se_unk_fc;
|
||||
extern struct SongHeader se_pika_full_charge_1_up;
|
||||
|
||||
extern u8 gPaletteFadeRGBCache[][3];
|
||||
|
||||
void AnimateOneUpSprite(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 var0;
|
||||
s16 var1;
|
||||
s16 index;
|
||||
s16 scale;
|
||||
|
||||
var0 = 0;
|
||||
group = gMain.fieldSpriteGroups[50];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 202;
|
||||
if (gCurrentPinballGame->oneUpAnimTimer > 48)
|
||||
{
|
||||
var1 = gCurrentPinballGame->oneUpAnimTimer - 48;
|
||||
if (var1 >= 34)
|
||||
{
|
||||
group->baseY = 146 - (42 - var1) * 2;
|
||||
index = 0;
|
||||
}
|
||||
else if (var1 >= 24)
|
||||
{
|
||||
group->baseY = 130;
|
||||
index = 1;
|
||||
var0 = -9;
|
||||
}
|
||||
else if (var1 > 7)
|
||||
{
|
||||
group->baseY = 130;
|
||||
index = 2;
|
||||
var0 = -4;
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseY = 146 - var1 * 2;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gOneUpBannerSprite_Gfx[index], (void *)0x060152A0, 0x200);
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseY = 180;
|
||||
}
|
||||
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
|
||||
if (gCurrentPinballGame->oneUpAnimTimer > 56)
|
||||
{
|
||||
scale = 0x100;
|
||||
}
|
||||
else
|
||||
{
|
||||
var1 = gCurrentPinballGame->oneUpAnimTimer - 36;
|
||||
if (var1 >= 0)
|
||||
{
|
||||
scale = (var1 * 0x80) / 20 + 0x80;
|
||||
group->baseY = 130;
|
||||
var0 = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = 0x80;
|
||||
group->baseY = 180;
|
||||
var0 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
oamSimple = &group->oam[1];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY + var0;
|
||||
gOamBuffer[oamSimple->oamId].affineMode = ST_OAM_AFFINE_NORMAL;
|
||||
gOamBuffer[oamSimple->oamId].matrixNum = 6;
|
||||
SetMatrixScale(scale, scale, 6);
|
||||
|
||||
if (gCurrentPinballGame->oneUpAnimTimer < 58)
|
||||
{
|
||||
index = gCurrentPinballGame->numLives - 1 + (((gCurrentPinballGame->oneUpAnimTimer % 16) / 8) * 9);
|
||||
DmaCopy16(3, gLifeCountDigit_Gfx[index], (void *)0x06015520, 0x40);
|
||||
oamSimple = &group->oam[2];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + 216;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset - 112;
|
||||
}
|
||||
else
|
||||
{
|
||||
oamSimple = &group->oam[2];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + 216;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset - 76;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->oneUpAnimTimer)
|
||||
{
|
||||
if (gCurrentPinballGame->oneUpAnimTimer == 90)
|
||||
{
|
||||
group->available = 1;
|
||||
DmaCopy16(3, gOneUpSpritePalette, (void *)0x05000380, 0x20);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->oneUpAnimTimer == 85)
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_unk_fc);
|
||||
|
||||
if (gCurrentPinballGame->oneUpAnimTimer == 58)
|
||||
{
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_pika_full_charge_1_up);
|
||||
if (gCurrentPinballGame->numLives < 9)
|
||||
gCurrentPinballGame->numLives++;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->oneUpAnimTimer--;
|
||||
if (gCurrentPinballGame->oneUpAnimTimer == 0)
|
||||
group->available = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateBannerSlide(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
|
||||
group = gMain.fieldSpriteGroups[10];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->bannerSlideX;
|
||||
group->baseY = 44;
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->bannerDisplayDuration > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->bannerDisplayDuration == 120)
|
||||
gMain.fieldSpriteGroups[10]->available = 1;
|
||||
|
||||
gCurrentPinballGame->bannerSlideX = 270 - ((120 - gCurrentPinballGame->bannerDisplayDuration) * 3);
|
||||
if (gCurrentPinballGame->bannerDisplayDuration == 1)
|
||||
gMain.fieldSpriteGroups[10]->available = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSpoinkAnimation(void)
|
||||
{
|
||||
if (gCurrentPinballGame->cameraYViewport < 170)
|
||||
{
|
||||
DmaCopy16(3, gFieldPaletteVariants[gMain.selectedField][gCurrentPinballGame->activePaletteIndex * 2], (void *)OBJ_PLTT + 0x160, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gFieldPaletteVariants[gMain.selectedField][gCurrentPinballGame->activePaletteIndex * 2 + 1], (void *)OBJ_PLTT + 0x160, 0x20);
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->spoinkEntityState)
|
||||
{
|
||||
case 0:
|
||||
gCurrentPinballGame->spoinkAnimFrameIx = 0;
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer = 0;
|
||||
if (gCurrentPinballGame->ballTouchingSpoink)
|
||||
gCurrentPinballGame->spoinkPullbackYDistance = (gCurrentPinballGame->globalAnimFrameCounter % 30) / 15;
|
||||
else
|
||||
gCurrentPinballGame->spoinkPullbackYDistance = 0;
|
||||
|
||||
gCurrentPinballGame->ballTouchingSpoink = 0;
|
||||
break;
|
||||
case 1:
|
||||
if (gCurrentPinballGame->spoinkAnimFrameTimer < 5)
|
||||
{
|
||||
if (gCurrentPinballGame->spoinkAnimFrameTimer < 2)
|
||||
{
|
||||
gCurrentPinballGame->spoinkAnimFrameIx = 2;
|
||||
gCurrentPinballGame->spoinkPullbackYDistance = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->spoinkAnimFrameIx = 3;
|
||||
gCurrentPinballGame->spoinkPullbackYDistance = 5;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->spoinkAnimFrameTimer == 0)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xCC);
|
||||
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->spoinkEntityState = 2;
|
||||
gCurrentPinballGame->spoinkAnimFrameIx = 4;
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (gSpoinkAnimFrameset[gCurrentPinballGame->spoinkAnimFrameIx][1] <= gCurrentPinballGame->spoinkAnimFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->spoinkAnimFrameIx++;
|
||||
if (gCurrentPinballGame->spoinkAnimFrameIx > 7)
|
||||
gCurrentPinballGame->spoinkAnimFrameIx = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
gCurrentPinballGame->spoinkAnimFrameIx = 8;
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->spoinkEntityState = 4;
|
||||
gCurrentPinballGame->spoinkPullbackYDistance = 0;
|
||||
break;
|
||||
case 4:
|
||||
if (gSpoinkAnimFrameset[gCurrentPinballGame->spoinkAnimFrameIx][1] > gCurrentPinballGame->spoinkAnimFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->spoinkAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->spoinkAnimFrameIx++;
|
||||
if (gCurrentPinballGame->spoinkAnimFrameIx > 0x13)
|
||||
{
|
||||
gCurrentPinballGame->spoinkAnimFrameIx = 0;
|
||||
gCurrentPinballGame->spoinkEntityState = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSpoinkSprite(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
group = gMain.fieldSpriteGroups[44];
|
||||
if (group->available)
|
||||
{
|
||||
if (gCurrentPinballGame->spoinkAnimFrameIx == 0)
|
||||
index = (gCurrentPinballGame->globalAnimFrameCounter % 30) / 15;
|
||||
else
|
||||
index = gSpoinkAnimFrameset[gCurrentPinballGame->spoinkAnimFrameIx][0];
|
||||
|
||||
DmaCopy16(3, gSpoinkEntity_Gfx[index], (void *)0x060120E0, 0x1C0);
|
||||
group->baseX = 231 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 376 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunEvolutionCutscene(void)
|
||||
{
|
||||
s16 i, j;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
s16 var0;
|
||||
s16 index;
|
||||
s16 sp0[0xD8];
|
||||
s16 sp1B0[0x30];
|
||||
u8 sp210[3];
|
||||
|
||||
if (gCurrentPinballGame->stageTimer <= 360)
|
||||
{
|
||||
if (gCurrentPinballGame->stageTimer == 0)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
DmaCopy16(3, (void *)0x05000200, gCurrentPinballGame->pauseObjPalette, 0x200);
|
||||
gCurrentPinballGame->creatureOamPriority = 0;
|
||||
gCurrentPinballGame->boardEntityActive = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 10)
|
||||
{
|
||||
gCurrentPinballGame->activePortraitType = 16;
|
||||
DmaCopy16(3, gBoardActionTilesGfx, (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gBoardActionObjPal, (void *)0x050003C0, 0x20);
|
||||
gMain.fieldSpriteGroups[24]->available = 1;
|
||||
gMain.fieldSpriteGroups[25]->available = 1;
|
||||
gMain.fieldSpriteGroups[26]->available = 1;
|
||||
gMain.fieldSpriteGroups[27]->available = 1;
|
||||
gMain.fieldSpriteGroups[28]->available = 1;
|
||||
gMain.fieldSpriteGroups[15]->available = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->scrollEffectY < 236)
|
||||
gCurrentPinballGame->cameraYAdjust = gCurrentPinballGame->stageTimer / 2;;
|
||||
|
||||
if (gCurrentPinballGame->stageTimer > 35)
|
||||
{
|
||||
if (gCurrentPinballGame->stageTimer < 68)
|
||||
{
|
||||
var0 = gCurrentPinballGame->stageTimer - 36;
|
||||
for (j = 0; j <= var0; j++)
|
||||
{
|
||||
for (i = 1; i < 11; i++)
|
||||
gBG0TilemapBuffer[(i + 15) * 0x20 + j] = 0xC100;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x06002000, 0x800);
|
||||
if (var0 == 30)
|
||||
m4aSongNumStart(MUS_EVOLUTION);
|
||||
|
||||
if (gMain.selectedField == FIELD_SAPPHIRE && gCurrentPinballGame->stageTimer == 67)
|
||||
gCurrentPinballGame->sapphireBumperTimer = 120;
|
||||
}
|
||||
else if (gCurrentPinballGame->stageTimer <= 344)
|
||||
{
|
||||
for (j = 0; j <= 30; j++)
|
||||
{
|
||||
for (i = 1; i < 11; i++)
|
||||
gBG0TilemapBuffer[(i + 15) * 32 + j] = 0xC100;
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x06002000, 0x800);
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer - 270 >= 0 && gCurrentPinballGame->stageTimer - 270 <= 30)
|
||||
{
|
||||
var0 = gCurrentPinballGame->stageTimer - 270;
|
||||
if (var0 == 0)
|
||||
{
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
gPaletteFadeRGBCache[i][0] = gCurrentPinballGame->pauseObjPalette[13][i] & 0x1F;
|
||||
gPaletteFadeRGBCache[i][1] = (gCurrentPinballGame->pauseObjPalette[13][i] & 0x3E0) >> 5;
|
||||
gPaletteFadeRGBCache[i][2] = (gCurrentPinballGame->pauseObjPalette[13][i] & 0x7C00) >> 10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 *destColor;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
destColor = sp1B0;
|
||||
sp210[0] = gPaletteFadeRGBCache[i][0] + ((0x1F - gPaletteFadeRGBCache[i][0]) * var0) / 30;
|
||||
sp210[1] = gPaletteFadeRGBCache[i][1] + ((0x1F - gPaletteFadeRGBCache[i][1]) * var0) / 30;
|
||||
sp210[2] = gPaletteFadeRGBCache[i][2] + ((0x1F - gPaletteFadeRGBCache[i][2]) * var0) / 30;
|
||||
destColor[i] = sp210[0] | (sp210[1] << 5) | (sp210[2] << 0xA);
|
||||
}
|
||||
|
||||
DmaCopy16(3, destColor, (void *)0x050003A0, 0x20);
|
||||
}
|
||||
|
||||
if (var0 == 10)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB0);
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->stageTimer - 300;
|
||||
if (var0 >= 0 && var0 <= 16)
|
||||
{
|
||||
gCurrentPinballGame->startButtonDisabled = 1;
|
||||
var0 = gCurrentPinballGame->stageTimer - 300;
|
||||
gMain.blendControl = 0x9F;
|
||||
gMain.blendBrightness = var0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer > 10)
|
||||
{
|
||||
group = gMain.fieldSpriteGroups[24];
|
||||
var0 = -120 + gCurrentPinballGame->stageTimer;
|
||||
if (var0 >= 22)
|
||||
sp0[0] = ((var0 - 22) % 102) * 3 - 160;
|
||||
else
|
||||
sp0[0] = -162;
|
||||
|
||||
if (var0 >= 0)
|
||||
sp0[1] = (var0 % 102) * 3 - 162;
|
||||
else
|
||||
sp0[1] = -162;
|
||||
|
||||
if (var0 >= 72)
|
||||
sp0[2] = ((var0 - 72) % 102) * 3 - 162;
|
||||
else
|
||||
sp0[2] = -162;
|
||||
|
||||
if (var0 >= 51)
|
||||
sp0[3] = ((var0 - 51) % 102) * 3 - 161;
|
||||
else
|
||||
sp0[3] = -161;
|
||||
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 308 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = group->baseX + sp0[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
var0 = -60 + gCurrentPinballGame->stageTimer;
|
||||
if (var0 >= 22)
|
||||
sp0[0] = ((var0 - 22) % 102) * 3 - 160;
|
||||
else
|
||||
sp0[0] = -162;
|
||||
|
||||
if (var0 >= 0)
|
||||
sp0[1] = (var0 % 102) * 3 - 162;
|
||||
else
|
||||
sp0[1] = -162;
|
||||
|
||||
if (var0 >= 72)
|
||||
sp0[2] = ((var0 - 72) % 102) * 3 - 162;
|
||||
else
|
||||
sp0[2] = -162;
|
||||
|
||||
if (var0 >= 51)
|
||||
sp0[3] = ((var0 - 51) % 102) * 3 - 161;
|
||||
else
|
||||
sp0[3] = -161;
|
||||
|
||||
group = gMain.fieldSpriteGroups[25];
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 308 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = group->baseX + sp0[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[26];
|
||||
var0 = -100 + gCurrentPinballGame->stageTimer;
|
||||
if (var0 >= 0)
|
||||
sp0[0] = (var0 % 152) * 2 - 160;
|
||||
else
|
||||
sp0[0] = -160;
|
||||
|
||||
if (var0 >= 38)
|
||||
sp0[1] = ((var0 - 38) % 152) * 2 - 160;
|
||||
else
|
||||
sp0[1] = -160;
|
||||
|
||||
if (var0 >= 76)
|
||||
sp0[2] = ((var0 - 76) % 152) * 2 - 160;
|
||||
else
|
||||
sp0[2] = -160;
|
||||
|
||||
if (var0 >= 114)
|
||||
sp0[3] = ((var0 - 114) % 152) * 2 - 160;
|
||||
else
|
||||
sp0[3] = -160;
|
||||
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 308 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = group->baseX + sp0[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[27];
|
||||
var0 = -80 + gCurrentPinballGame->stageTimer;
|
||||
if (var0 >= 0)
|
||||
sp0[0] = (var0 % 152) * 2 - 160;
|
||||
else
|
||||
sp0[0] = -160;
|
||||
|
||||
if (var0 >= 38)
|
||||
sp0[1] = ((var0 - 38) % 152) * 2 - 160;
|
||||
else
|
||||
sp0[1] = -160;
|
||||
|
||||
if (var0 >= 76)
|
||||
sp0[2] = ((var0 - 76) % 152) * 2 - 160;
|
||||
else
|
||||
sp0[2] = -160;
|
||||
|
||||
if (var0 >= 114)
|
||||
sp0[3] = ((var0 - 114) % 152) * 2 - 160;
|
||||
else
|
||||
sp0[3] = -160;
|
||||
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 308 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = group->baseX + sp0[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
var0 = -90 + gCurrentPinballGame->stageTimer;
|
||||
if (var0 >= 236)
|
||||
sp0[0] = (var0 - 236) % 272 - 128;
|
||||
else
|
||||
sp0[0] = -128;
|
||||
|
||||
if (var0 >= 204)
|
||||
sp0[1] = (var0 - 204) % 272 - 128;
|
||||
else
|
||||
sp0[1] = -128;
|
||||
|
||||
if (var0 >= 168)
|
||||
sp0[2] = (var0 - 168) % 272 - 128;
|
||||
else
|
||||
sp0[2] = -128;
|
||||
|
||||
if (var0 >= 136)
|
||||
sp0[3] = (var0 - 136) % 272 - 128;
|
||||
else
|
||||
sp0[3] = -128;
|
||||
|
||||
if (var0 >= 100)
|
||||
sp0[4] = (var0 - 100) % 272 - 128;
|
||||
else
|
||||
sp0[4] = -128;
|
||||
|
||||
if (var0 >= 68)
|
||||
sp0[5] = (var0 - 68) % 272 - 128;
|
||||
else
|
||||
sp0[5] = -128;
|
||||
|
||||
if (var0 >= 32)
|
||||
sp0[6] = (var0 - 32) % 272 - 128;
|
||||
else
|
||||
sp0[6] = -128;
|
||||
|
||||
if (var0 >= 0)
|
||||
sp0[7] = (var0 % 272) - 128;
|
||||
else
|
||||
sp0[7] = -128;
|
||||
|
||||
group = gMain.fieldSpriteGroups[28];
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 308 - gCurrentPinballGame->cameraYOffset;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = group->baseX + sp0[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[15];
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 308 - gCurrentPinballGame->cameraYOffset;
|
||||
var0 = -120 + gCurrentPinballGame->stageTimer;
|
||||
if (var0 > 0)
|
||||
{
|
||||
sp0[0] = 0;
|
||||
index = (var0 % 70) / 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = -160;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gEvolutionSparkleSpritesheetOam[index][i * 3 + 0];
|
||||
*dst++ = gEvolutionSparkleSpritesheetOam[index][i * 3 + 1];
|
||||
*dst++ = gEvolutionSparkleSpritesheetOam[index][i * 3 + 2];
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX + sp0[0];
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 350)
|
||||
{
|
||||
for (i = 0x1E0; i < 0x340; i++)
|
||||
gBG0TilemapBuffer[i] = 0x1FF;
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x06002000, 0x800);
|
||||
if (gMain.selectedField == FIELD_SAPPHIRE)
|
||||
gCurrentPinballGame->sapphireBumperTimer = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 360)
|
||||
{
|
||||
gMain.fieldSpriteGroups[24]->available = 0;
|
||||
gMain.fieldSpriteGroups[25]->available = 0;
|
||||
gMain.fieldSpriteGroups[26]->available = 0;
|
||||
gMain.fieldSpriteGroups[27]->available = 0;
|
||||
gMain.fieldSpriteGroups[28]->available = 0;
|
||||
gMain.fieldSpriteGroups[15]->available = 0;
|
||||
gCurrentPinballGame->currentSpecies = gCurrentPinballGame->postEvoSpecies;
|
||||
LoadPortraitGraphics(3, 0);
|
||||
gCurrentPinballGame->activePortraitType = 17;
|
||||
DmaCopy16(3, gHatchFinalTilesGfx, (void *)0x06015800, 0x1800);
|
||||
DmaCopy16(3, gHatchFinalPalette, (void *)0x050003C0, 0x20);
|
||||
gCurrentPinballGame->creatureOamPriority = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 = gCurrentPinballGame->stageTimer - 360;
|
||||
if (var0 <= 64)
|
||||
{
|
||||
if (var0 == 1)
|
||||
m4aMPlayStop(&gMPlayInfo_BGM);
|
||||
|
||||
gMain.blendControl = 0x9F;
|
||||
gMain.blendBrightness = 16 - (var0 / 4);
|
||||
if (var0 == 32)
|
||||
{
|
||||
gCurrentPinballGame->bgmFadeTimer = 140;
|
||||
PlayCry_Normal(gSpeciesInfo[gCurrentPinballGame->currentSpecies].speciesIdRS, 0);
|
||||
}
|
||||
|
||||
if (var0 == 64)
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex = 0;
|
||||
gMain.fieldSpriteGroups[37]->available = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->startButtonDisabled = 0;
|
||||
if (gHatchRevealFinalTimings[gCurrentPinballGame->revealFramesetIndex] > gCurrentPinballGame->revealAnimFrameCounter)
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->revealAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex++;
|
||||
if (gCurrentPinballGame->revealFramesetIndex > 10)
|
||||
{
|
||||
gMain.fieldSpriteGroups[37]->available = 0;
|
||||
gCurrentPinballGame->revealFramesetIndex = 10;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
DmaCopy16(3, gCurrentPinballGame->pauseObjPalette, (void *)0x05000200, 0x180);
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
index = gCurrentPinballGame->revealFramesetIndex;
|
||||
group = gMain.fieldSpriteGroups[37];
|
||||
group->baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 300 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gHatchSequentialOamFramesets[index][i * 3 + 0];
|
||||
*dst++ = gHatchSequentialOamFramesets[index][i * 3 + 1];
|
||||
*dst++ = gHatchSequentialOamFramesets[index][i * 3 + 2];
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunTravelEventCutscene(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
s16 index;
|
||||
s16 var0;
|
||||
|
||||
index = 0;
|
||||
if (gCurrentPinballGame->stageTimer == 0)
|
||||
{
|
||||
gMain.fieldSpriteGroups[16]->available = 1;
|
||||
gCurrentPinballGame->travelPainterPosX = 1400;
|
||||
gCurrentPinballGame->travelPainterPosY = -600;
|
||||
gCurrentPinballGame->activePortraitType = 21;
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
DmaCopy16(3, gRubyBoardBonusGfx, (void *)0x06015800, 0x1800);
|
||||
DmaCopy16(3, gRubyBoardBonusObjPalette, (void *)0x050003C0, 0x20);
|
||||
DmaCopy16(3, gRubyTravelVolbeat_Gfx, (void *)0x06015800, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gSapphireBoardBonusGfx, (void *)0x06015800, 0x1800);
|
||||
DmaCopy16(3, gSapphireBoardBonusObjPalette, (void *)0x050003C0, 0x20);
|
||||
DmaCopy16(3, gSapphireTravelIllumise_Gfx, (void *)0x06015800, 0x480);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->stageTimer < 60)
|
||||
{
|
||||
u16 angle = (gCurrentPinballGame->stageTimer * 0x4000) / 60;
|
||||
gCurrentPinballGame->travelPainterPosX = (Cos(angle) * 900) / 20000 + 487;
|
||||
gCurrentPinballGame->travelPainterPosY = (Sin(angle) * 600) / 20000 - 629;
|
||||
gCurrentPinballGame->travelPainterVelX = -17;
|
||||
gCurrentPinballGame->travelPainterVelY = -30;
|
||||
index = (gCurrentPinballGame->stageTimer % 4) / 2;
|
||||
if (gCurrentPinballGame->stageTimer % 10 == 0)
|
||||
m4aSongNumStart(SE_TRAVEL_PAINTER_FLIGHT);
|
||||
}
|
||||
else if (gCurrentPinballGame->stageTimer < 90)
|
||||
{
|
||||
var0 = gCurrentPinballGame->stageTimer - 60;
|
||||
if (var0 < 12)
|
||||
{
|
||||
index = (var0 % 12) / 2 + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 -= 12;
|
||||
index = (var0 % 18) / 3 + 2;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->travelPainterVelY += 2;
|
||||
gCurrentPinballGame->travelPainterPosX += gCurrentPinballGame->travelPainterVelX;
|
||||
gCurrentPinballGame->travelPainterPosY += gCurrentPinballGame->travelPainterVelY;
|
||||
gCurrentPinballGame->travelAnimKeyframeIndex = 0;
|
||||
gCurrentPinballGame->travelAnimSubTimer = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->stageTimer < 190)
|
||||
{
|
||||
if (gTravelEventAnimData[gCurrentPinballGame->travelAnimKeyframeIndex][2] > gCurrentPinballGame->travelAnimSubTimer)
|
||||
{
|
||||
gCurrentPinballGame->travelAnimSubTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->travelAnimSubTimer = 0;
|
||||
gCurrentPinballGame->travelAnimKeyframeIndex++;
|
||||
if (gCurrentPinballGame->travelAnimKeyframeIndex == 7)
|
||||
{
|
||||
gCurrentPinballGame->area = gAreaRouletteTable[gMain.selectedField][gCurrentPinballGame->areaRouletteSlotIndex];
|
||||
gCurrentPinballGame->rouletteAreaIndex[0] = gAreaToSpeciesTable[gCurrentPinballGame->area];
|
||||
LoadPortraitGraphics(0, 0);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->travelAnimKeyframeIndex == 11)
|
||||
gCurrentPinballGame->stageTimer = 189;
|
||||
}
|
||||
|
||||
index = gTravelEventAnimData[gCurrentPinballGame->travelAnimKeyframeIndex][1];
|
||||
if (gTravelEventAnimData[gCurrentPinballGame->travelAnimKeyframeIndex][2] == 5 && gCurrentPinballGame->travelAnimSubTimer == 1)
|
||||
m4aSongNumStart(SE_TRAVEL_PAINTER_PAINTS);
|
||||
|
||||
if (index == 16)
|
||||
gCurrentPinballGame->travelPainterPosX = -80;
|
||||
else
|
||||
gCurrentPinballGame->travelPainterPosX = 0;
|
||||
|
||||
gCurrentPinballGame->travelPainterVelX = -24;
|
||||
gCurrentPinballGame->travelPainterVelY = 14;
|
||||
}
|
||||
else if (gCurrentPinballGame->stageTimer < 430)
|
||||
{
|
||||
var0 = gCurrentPinballGame->stageTimer - 190;
|
||||
if (var0 < 24)
|
||||
{
|
||||
gCurrentPinballGame->travelPainterPosX = var0 * -14;
|
||||
index = (var0 % 24) / 4 + 2;
|
||||
}
|
||||
else if (var0 < 30)
|
||||
{
|
||||
index = 12;
|
||||
if (var0 == 24)
|
||||
m4aSongNumStart(MUS_SUCCESS);
|
||||
}
|
||||
else if (var0 < 42)
|
||||
{
|
||||
var0 -= 30;
|
||||
index = (var0 % 12) / 6 + 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = 15;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->stageTimer < 490)
|
||||
{
|
||||
index = (gCurrentPinballGame->stageTimer % 4) / 2;
|
||||
gCurrentPinballGame->travelPainterVelY--;
|
||||
gCurrentPinballGame->travelPainterPosX += gCurrentPinballGame->travelPainterVelX;
|
||||
gCurrentPinballGame->travelPainterPosY += gCurrentPinballGame->travelPainterVelY;
|
||||
if (gCurrentPinballGame->stageTimer % 10 == 0)
|
||||
m4aSongNumStart(SE_TRAVEL_PAINTER_FLIGHT);
|
||||
}
|
||||
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
DmaCopy16(3, gRubyTravelVolbeat_Gfx[index], (void *) 0x06015800, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gSapphireTravelIllumise_Gfx[index], (void *) 0x06015800, 0x480);
|
||||
}
|
||||
|
||||
index = gTravelEventAnimData[gCurrentPinballGame->travelAnimKeyframeIndex][0];
|
||||
group = gMain.fieldSpriteGroups[16];
|
||||
group->baseX = gCurrentPinballGame->travelPainterPosX / 10 + 96u - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->travelPainterPosY / 10 + 300u - gCurrentPinballGame->cameraYOffset;
|
||||
|
||||
for( i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst =(u16*) &gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gTravelEventSpritesheetOam[index][i * 3 + 0];
|
||||
*dst++ = gTravelEventSpritesheetOam[index][i * 3 + 1];
|
||||
*dst++ = gTravelEventSpritesheetOam[index][i * 3 + 2];
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 489)
|
||||
{
|
||||
gMain.fieldSpriteGroups[16]->available = 0;
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
83
src/link.c
83
src/link.c
|
|
@ -737,3 +737,86 @@ static void ResetRecvBuffer(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
s16 LoadSpriteSetsWithCpuCopy(const struct SpriteSet *const *spriteSets, u16 numSpriteSets, struct SpriteGroup *spriteGroups)
|
||||
{
|
||||
struct SpriteGroup *spriteGroup;
|
||||
struct OamDataSimple *simple;
|
||||
u16 *oamData;
|
||||
u16 i;
|
||||
u16 j;
|
||||
u16 pos;
|
||||
u16 numSpritesInGroup;
|
||||
|
||||
oamData = (u16 *)gOamBuffer;
|
||||
pos = 0;
|
||||
CpuCopy16(gEmptyOamData, oamData, sizeof(gOamBuffer));
|
||||
|
||||
for (i = 0; i < numSpriteSets; i++) {
|
||||
spriteGroup = &spriteGroups[i];
|
||||
if (!spriteGroup->available) {
|
||||
continue;
|
||||
}
|
||||
numSpritesInGroup = spriteSets[i]->count;
|
||||
CpuCopy16(spriteSets[i]->oamData, &gOamBuffer[pos], numSpritesInGroup * sizeof(struct OamData));
|
||||
for (j = 0; j < numSpritesInGroup; j++) {
|
||||
oamData = (u16 *)&gOamBuffer[pos];
|
||||
simple = &spriteGroup->oam[j];
|
||||
|
||||
simple->oamId = pos++;
|
||||
simple->xOffset = oamData[1] & 0x1FF;
|
||||
simple->yOffset = oamData[0] & 0xFF;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
void nullsub_16(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ResetSerialIO(void)
|
||||
{
|
||||
REG_RCNT = 0;
|
||||
REG_SIOCNT = 0;
|
||||
|
||||
REG_SIOMLT_SEND = 0;
|
||||
REG_SIOMULTI0 = 0;
|
||||
REG_SIOMLT_SEND = 0;
|
||||
REG_SIOMULTI0 = 0;
|
||||
|
||||
REG_SIOMULTI0 = 0;
|
||||
REG_SIOMULTI1 = 0;
|
||||
REG_SIOMULTI2 = 0;
|
||||
REG_SIOMULTI3 = 0;
|
||||
}
|
||||
|
||||
void SetupDefaultInterrupts(void)
|
||||
{
|
||||
REG_IME = 0;
|
||||
REG_IE = INTR_FLAG_GAMEPAK | INTR_FLAG_VBLANK;
|
||||
REG_DISPSTAT = DISPSTAT_VBLANK_INTR;
|
||||
REG_IME = 1;
|
||||
}
|
||||
|
||||
void ResetLinkState(void)
|
||||
{
|
||||
gLinkStatusResult = 0;
|
||||
gLinkTimeoutCounter = 0;
|
||||
gLinkConnectionState = 0;
|
||||
gLinkPlayerCount = 0;
|
||||
gLinkNegotiationFlags = 0;
|
||||
}
|
||||
|
||||
void ResetSerialAndInterrupts(void)
|
||||
{
|
||||
ResetSerialIO();
|
||||
REG_IME = 0;
|
||||
ResetMainCallback();
|
||||
ResetVBlankIntrFunc();
|
||||
REG_IE = INTR_FLAG_GAMEPAK | INTR_FLAG_VCOUNT | INTR_FLAG_VBLANK;
|
||||
REG_DISPSTAT = DISPSTAT_VCOUNT_INTR | DISPSTAT_VBLANK_INTR;
|
||||
REG_IME = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,408 +4,6 @@
|
|||
#include "constants/bg_music.h"
|
||||
#include "constants/ruby_states.h"
|
||||
|
||||
void AnimateSharpedoCatchSequence(void);
|
||||
void InitSharpedoCatchMode(void);
|
||||
void AnimateEggHatchSequence(void);
|
||||
void InitRubyEvolutionShopMode(void);
|
||||
void AnimateRubyEvolutionShopSequence(void);
|
||||
void InitCenterTrapMode(void);
|
||||
void AnimateCenterTrapSequence(void);
|
||||
void RequestBoardStateTransition(u8);
|
||||
void AnimateTotodileEggDelivery(void);
|
||||
void InitAerodactylEggDelivery(void);
|
||||
void AnimateAerodactylEggDelivery(void);
|
||||
|
||||
|
||||
void DispatchRubyCatchModeInit(void)
|
||||
{
|
||||
if (gMain.modeChangeFlags != MODE_CHANGE_NONE)
|
||||
return;
|
||||
|
||||
switch (gCurrentPinballGame->ballCatchState)
|
||||
{
|
||||
case TRAP_CATCH_HOLE:
|
||||
InitSharpedoCatchMode();
|
||||
break;
|
||||
case TRAP_EGG_HOLE:
|
||||
InitEggHatchMode();
|
||||
break;
|
||||
case TRAP_EVO_SHOP_HOLE:
|
||||
InitRubyEvolutionShopMode();
|
||||
break;
|
||||
case TRAP_CENTER_HOLE:
|
||||
InitCenterTrapMode();
|
||||
break;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->collisionCooldownTimer = 60;
|
||||
}
|
||||
|
||||
void UpdateRubyCatchModeAnimation(void)
|
||||
{
|
||||
if (gCurrentPinballGame->collisionCooldownTimer > 0)
|
||||
gCurrentPinballGame->collisionCooldownTimer--;
|
||||
|
||||
switch (gCurrentPinballGame->ballCatchState)
|
||||
{
|
||||
case TRAP_CATCH_HOLE:
|
||||
AnimateSharpedoCatchSequence(); // Catch hole
|
||||
break;
|
||||
case TRAP_EGG_HOLE:
|
||||
AnimateEggHatchSequence(); //Hatch hole
|
||||
break;
|
||||
case TRAP_EVO_SHOP_HOLE:
|
||||
AnimateRubyEvolutionShopSequence(); //Mart / Evo hole
|
||||
break;
|
||||
case TRAP_CENTER_HOLE:
|
||||
AnimateCenterTrapSequence(); //Center Hole
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitSharpedoCatchMode(void)
|
||||
{
|
||||
if (gCurrentPinballGame->catchArrowProgress > 1)
|
||||
{
|
||||
RequestBoardStateTransition(4);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->cameraScrollOffset = 0;
|
||||
gCurrentPinballGame->cameraScrollEnabled = 0;
|
||||
gCurrentPinballGame->cameraScrollTarget = 0;
|
||||
gCurrentPinballGame->modeAnimTimer = 113;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xCE);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 50000;
|
||||
|
||||
PlayRumble(8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ruby board Sharpedo; during the initation of the catch mode
|
||||
* Echoes UpdateSapphireWailmerCatchSequence, which is the equivalent 'catch hole' on the sapphire board.
|
||||
*
|
||||
* Note: this *does not* affect the start of the catch mode itself.
|
||||
* When this function is nulled out at UpdateRubyCatchModeAnimation, the banner *doesn't* show, and
|
||||
* the ball bounces off the sharpedo. However, the grid still shows a picked mon,
|
||||
* and the mode otherwise works mostly normally, with the exception of affecting
|
||||
* the 'tilt' behavior, and the collision with the cyndaquil pushback.
|
||||
*/
|
||||
void AnimateSharpedoCatchSequence(void)
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer) //Countdown timer; ball grabbed/held while banner shows
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
if (gCurrentPinballGame->modeAnimTimer > 100)
|
||||
{
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 108)
|
||||
{
|
||||
gCurrentPinballGame->boardEntityActive = 1;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 110)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 195;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 222;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 196;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 221;
|
||||
}
|
||||
//Presumed controling either the message board 'state'/'tile'
|
||||
// or the sharpedo animation 'state'/tile.
|
||||
gCurrentPinballGame->catchHoleAnimFrame =6;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 104)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 197;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 219;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 8;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 20)
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer > 77)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 9;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer < 80)
|
||||
{
|
||||
if (gCurrentPinballGame->catchHolePauseTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->catchHolePauseTimer--;
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 72)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 10;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 67)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 11;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 44)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 12;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 38)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 13;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 28)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 14;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 23)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 15;
|
||||
}
|
||||
else {
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 16;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 18)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 193;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 226;
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 17;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 16)
|
||||
{
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->cameraScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraScrollEnabled = 1;
|
||||
gCurrentPinballGame->boardEntityActive = 0;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ball->velocity.x = 0xFF56;
|
||||
gCurrentPinballGame->ball->velocity.y = 220;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 190;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 232;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 18;
|
||||
if (gCurrentPinballGame->modeAnimTimer == 18)
|
||||
{
|
||||
m4aSongNumStart(194);
|
||||
PlayRumble(7);
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 12)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 19;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 8)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 20;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 4)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 21;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 22;
|
||||
}
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
|
||||
gCurrentPinballGame->ball->prevPositionQ1 = gCurrentPinballGame->ball->positionQ1;
|
||||
gCurrentPinballGame->ball->positionQ8.x= gCurrentPinballGame->ball->positionQ0.x << 8;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y << 8;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->collisionCooldownTimer = 30;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ballCatchState = NOT_TRAPPED;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InitEggHatchMode(void)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 100000;
|
||||
if (gCurrentPinballGame->eggCaveState == 3)
|
||||
{
|
||||
gCurrentPinballGame->eggCaveState = 4;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
PlayRumble(7);
|
||||
gCurrentPinballGame->modeAnimTimer = 500;
|
||||
}
|
||||
else if (gCurrentPinballGame->eggDeliveryState !=0)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 300;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 120;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
}
|
||||
|
||||
void AnimateEggHatchSequence(void)
|
||||
{
|
||||
u16 modeAnimTimer = gCurrentPinballGame->modeAnimTimer;
|
||||
|
||||
if (modeAnimTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0x58;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0x94;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
|
||||
if (gCurrentPinballGame->eggDeliveryState != 1)
|
||||
return;
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0xC8)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer == 0xC8)
|
||||
{
|
||||
if (gCurrentPinballGame->activePortraitType != 0)
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->scoreHi != 0 && gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_LOTAD)
|
||||
InitTotodileEggDelivery();
|
||||
else
|
||||
InitAerodactylEggDelivery();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->scoreHi != 0 && gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_LOTAD)
|
||||
AnimateTotodileEggDelivery();
|
||||
else
|
||||
AnimateAerodactylEggDelivery();
|
||||
}
|
||||
if (gCurrentPinballGame->modeAnimTimer <= 9)
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->ballCatchState = NOT_TRAPPED;
|
||||
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0x58;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0xA2;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
|
||||
if (gCurrentPinballGame->eggDeliveryState == 2)
|
||||
{
|
||||
gCurrentPinballGame->eggCaveState = 3;
|
||||
gCurrentPinballGame->eggCaveLiftTimer = 0x30;
|
||||
gCurrentPinballGame->eggCaveExitDelayTimer = 0x1E;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->collisionCooldownTimer = 0x3C;
|
||||
gCurrentPinballGame->ball->velocity.x = 0x14;
|
||||
gCurrentPinballGame->ball->velocity.y = 0xC8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitRubyEvolutionShopMode(void)
|
||||
{
|
||||
gCurrentPinballGame->shopAnimSlideTimer = 0;
|
||||
gCurrentPinballGame->shopUISlideOffset = 0;
|
||||
gCurrentPinballGame->modeAnimTimer = 0xB4;
|
||||
gCurrentPinballGame->shopEntryTimer = 0xB4;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 500000;
|
||||
gMain.blendControl = 0xCE;
|
||||
gMain.blendBrightness = 0;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
}
|
||||
|
||||
void AnimateRubyEvolutionShopSequence(void)
|
||||
{
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0x18)
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0xDC;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0x62;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ0.x * 256;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y * 256;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0x9B)
|
||||
gCurrentPinballGame->shopDoorTargetFrame = (gCurrentPinballGame->modeAnimTimer - 0x9C) / 8;
|
||||
if (gCurrentPinballGame->modeAnimTimer <= 0x31)
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
|
||||
UpdateShopEntryAnimation(gCurrentPinballGame->evolutionShopActive);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
gCurrentPinballGame->shopDoorTargetFrame = (0x18 - gCurrentPinballGame->modeAnimTimer) / 8;
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->collisionCooldownTimer = 0x3C;
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x = 0x60;
|
||||
gCurrentPinballGame->ball->velocity.y = 0xC0;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0xDF;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0x63;
|
||||
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ballCatchState = NOT_TRAPPED;
|
||||
gCurrentPinballGame->shopDoorTargetFrame = 0x13;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xC3);
|
||||
|
||||
if (gCurrentPinballGame->evoArrowProgress > 2 && gCurrentPinballGame->evolvablePartySize > 0)
|
||||
{
|
||||
RequestBoardStateTransition(6);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateShopEntryAnimation(s16 arg0)
|
||||
{
|
||||
int var_r7 = 0;
|
||||
329
src/main_portrait_display.c
Normal file
329
src/main_portrait_display.c
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
extern const u16 gPortraitGenericPalettes[];
|
||||
extern const u16 gPortraitPaletteSlots[2];
|
||||
extern const u16 gPortraitIdleCycleData[];
|
||||
extern const u16 gPortraitAnimPalettes[];
|
||||
|
||||
extern const s16 gRouletteOutcomeFrameOffsets[];
|
||||
|
||||
/*
|
||||
File is used for the center screen display on the main board.
|
||||
Can contain travel location picture, catch mon, roulette wheel
|
||||
*/
|
||||
|
||||
void LoadPortraitGraphics(s16 arg0, s16 arg1)
|
||||
{
|
||||
s16 i;
|
||||
s16 var0;
|
||||
s16 sp0[16];
|
||||
s16 rgb[3];
|
||||
u16 index;
|
||||
const u16 *ptr;
|
||||
const u16 *ptr2;
|
||||
u16 index2;
|
||||
|
||||
switch (arg0)
|
||||
{
|
||||
case 0:
|
||||
gCurrentPinballGame->creatureOamPriority = 3;
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = gCurrentPinballGame->rouletteAreaIndex[arg1];
|
||||
DmaCopy16(3, gPortraitGenericGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
index = gCurrentPinballGame->rouletteAreaIndex[arg1] * 0x10;
|
||||
DmaCopy16(3, &gPortraitGenericPalettes[index], (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
break;
|
||||
case 1:
|
||||
ptr = gPortraitIdleCycleData;
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = ptr[(gCurrentPinballGame->portraitCycleFrame % 48) / 24];
|
||||
index = ptr[2] * 0x10;
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
DmaCopy16(3, &gPortraitAnimPalettes[index], (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
break;
|
||||
case 2:
|
||||
ptr = gShopItemData[gCurrentPinballGame->modeOutcomeValues[arg1]];
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = ptr[0];
|
||||
index = ptr[2] * 0x10;
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
DmaCopy16(3, &gPortraitAnimPalettes[index], (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
break;
|
||||
case 3:
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = gCurrentPinballGame->currentSpecies;
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[arg1] / 15] + (gCurrentPinballGame->portraitGfxIndex[arg1] % 15) * 0x300,
|
||||
(void *)0x06010CA0 + arg1 * 24,
|
||||
0x300);
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[arg1] / 15] + (gCurrentPinballGame->portraitGfxIndex[arg1] % 15) * 0x20,
|
||||
(void *)0x050003A0 ,
|
||||
0x20);
|
||||
DmaCopy16(3, gMonPortraitGroupPals[0] + 15 * 0x20, (void *)0x050003E0, 0x20);
|
||||
break;
|
||||
case 9:
|
||||
if (gCurrentPinballGame->evoChainPosition > 0)
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[gCurrentPinballGame->evoTargetSpecies] == SPECIES_UNSEEN)
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = SPECIES_NONE;
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[arg1] / 15] + (gCurrentPinballGame->portraitGfxIndex[arg1] % 15) * 0x20,
|
||||
(void *)0x050003A0,
|
||||
0x20);
|
||||
}
|
||||
else if (gMain_saveData.pokedexFlags[gCurrentPinballGame->evoTargetSpecies] < SPECIES_CAUGHT)
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = gCurrentPinballGame->evoTargetSpecies;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[0] + 15 * 0x20, (void *)0x050003A0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = gCurrentPinballGame->evoTargetSpecies;
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[arg1] / 15] + (gCurrentPinballGame->portraitGfxIndex[arg1] % 15) * 0x20,
|
||||
(void *)0x050003A0,
|
||||
0x20);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = gCurrentPinballGame->currentSpecies;
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[arg1] / 15] + (gCurrentPinballGame->portraitGfxIndex[arg1] % 15) * 0x20,
|
||||
(void *)0x050003A0,
|
||||
0x20);
|
||||
}
|
||||
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[arg1] / 15] + (gCurrentPinballGame->portraitGfxIndex[arg1] % 15) * 0x300,
|
||||
(void *)0x06010CA0 + arg1 * 0x18,
|
||||
0x300);
|
||||
break;
|
||||
case 4:
|
||||
if (gCurrentPinballGame->boardSubState == 2)
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = gShopItemData[15][(gCurrentPinballGame->portraitCycleFrame % 48) / 24];
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
|
||||
// !!!!! BUG: this should be multiplied by 16 !!
|
||||
index = gShopItemData[15][2];
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = gShopItemData[16][(gCurrentPinballGame->portraitCycleFrame % 48) / 24];
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
index = gShopItemData[16][2] * 16;
|
||||
}
|
||||
DmaCopy16(3, &gPortraitAnimPalettes[index], (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
break;
|
||||
case 6:
|
||||
ptr = gShopItemData[gCurrentPinballGame->shopSelectedItemId];
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = ptr[0];
|
||||
index = ptr[2] * 16;
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
if (gCurrentPinballGame->coins < ptr[3] ||
|
||||
(
|
||||
(gShopCursorToItemMap[gCurrentPinballGame->shopItemCursor] == 3 && gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
||
|
||||
(gShopCursorToItemMap[gCurrentPinballGame->shopItemCursor] == 4 && gCurrentPinballGame->shopBonusStageAlreadyBought)
|
||||
))
|
||||
{
|
||||
DmaCopy16(3, &gPortraitAnimPalettes[index], sp0, 0x20);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
rgb[0] = ((sp0[i] & 0x1F) * 2) / 3;
|
||||
rgb[1] = ((sp0[i] & 0x3E0) >> 4) / 3;
|
||||
rgb[2] = ((sp0[i] & 0x7C00) >> 9) / 3;
|
||||
sp0[i] = rgb[0] | (rgb[1] << 5) | (rgb[2] << 10);
|
||||
}
|
||||
|
||||
DmaCopy16(3, sp0, (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, &gPortraitAnimPalettes[index], (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
// TODO: fake match
|
||||
ptr2 = ptr = gShopItemData[gCurrentPinballGame->modeOutcomeValues[arg1]];
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = *(ptr2 += (gCurrentPinballGame->portraitCycleFrame % 48) / 24);
|
||||
index = ptr[2] * 16;
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
DmaCopy16(3, &gPortraitAnimPalettes[index], (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
break;
|
||||
case 8:
|
||||
// TODO: fake match
|
||||
ptr2 = ptr = gShopItemData[gCurrentPinballGame->rouletteOutcomeId];
|
||||
gCurrentPinballGame->portraitGfxIndex[arg1] = *(ptr2 += gRouletteOutcomeFrameOffsets[gCurrentPinballGame->outcomeFrameCounter / 12]);
|
||||
index = ptr[2] * 16;
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[arg1]], (void *)0x06010CA0 + arg1 * 0x300, 0x300);
|
||||
DmaCopy16(3, &gPortraitAnimPalettes[index], (void *)0x05000200 + gPortraitPaletteSlots[arg1] * 0x20, 0x20);
|
||||
break;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->portraitRenderMode[arg1] = arg0;
|
||||
gCurrentPinballGame->portraitCycleFrame++;
|
||||
}
|
||||
|
||||
void UpdatePortraitSpritePositions(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 baseX;
|
||||
s16 var1;
|
||||
s16 var2;
|
||||
|
||||
if (gCurrentPinballGame->portraitDisplayState == 3)
|
||||
{
|
||||
baseX = 0;
|
||||
var1 = 180;
|
||||
var2 = 180;
|
||||
}
|
||||
else if (gCurrentPinballGame->portraitDisplayState == 2)
|
||||
{
|
||||
if (gMain.shopPanelSlideOffset < 20)
|
||||
{
|
||||
var1 = 180;
|
||||
var2 = 180;
|
||||
}
|
||||
else
|
||||
{
|
||||
var1 = 88 + gCurrentPinballGame->rouletteSubOffset;
|
||||
var2 = 88;
|
||||
}
|
||||
|
||||
baseX = 48;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseX = 96 - gCurrentPinballGame->cameraXOffset;
|
||||
var1 = gCurrentPinballGame->rouletteSubOffset + 300u - gCurrentPinballGame->cameraYOffset;
|
||||
var2 = 300 - gCurrentPinballGame->cameraYOffset;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[22];
|
||||
group->baseX = baseX;
|
||||
group->baseY = var1;
|
||||
gCurrentPinballGame->rouletteBasePos.x = baseX;
|
||||
gCurrentPinballGame->rouletteBasePos.y = group->baseY;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].paletteNum = gCurrentPinballGame->hatchTilePalette[i];
|
||||
gOamBuffer[oamSimple->oamId].priority = gCurrentPinballGame->creatureOamPriority;
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->portraitDisplayState == 1)
|
||||
{
|
||||
group = gMain.fieldSpriteGroups[23];
|
||||
group->baseX = baseX;
|
||||
group->baseY = var1 - 0x20;
|
||||
if (group->baseY >= 180)
|
||||
group->baseY = 180;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].paletteNum = 12;
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[20];
|
||||
group->baseX = baseX;
|
||||
group->baseY = 267 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[21];
|
||||
group->baseX = baseX;
|
||||
group->baseY = 333 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[19];
|
||||
group->baseX = baseX - 8;
|
||||
group->baseY = var2 - 8;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].priority = gCurrentPinballGame->creatureOamPriority;
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
void ClampPortraitSpritesToOffscreen(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
|
||||
if (gCurrentPinballGame->portraitDisplayState == 1)
|
||||
{
|
||||
group = gMain.fieldSpriteGroups[22];
|
||||
group->baseY = 180;
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[23];
|
||||
group->baseY = 300 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 180)
|
||||
group->baseY = 180;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[20];
|
||||
group->baseY = 180;
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
|
||||
group = gMain.fieldSpriteGroups[21];
|
||||
group->baseY = 180;
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
421
src/pichu_entity.c
Normal file
421
src/pichu_entity.c
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern struct SongHeader se_pika_no_kickback;
|
||||
extern struct SongHeader se_pichu_kickback;
|
||||
extern struct SongHeader se_pikachu_kickback;
|
||||
|
||||
extern s16 gPikaSaverAnimFrameTable[100];
|
||||
extern s16 gOutlaneCenterXPositions[3];
|
||||
extern u16 gCatchOverlayAnimData[][2];
|
||||
extern s16 gCatchOverlayOamData[28][12];
|
||||
extern const struct Vector32 gPikaSaverWaypoints[];
|
||||
extern const u16 gAngleToDirectionTable[];
|
||||
extern const u8 gPikachuSaverTilesGfx[];
|
||||
|
||||
void UpdateKickbackLogic(void)
|
||||
{
|
||||
s16 outlaneChuteIx;
|
||||
s16 j;
|
||||
s16 r5;
|
||||
s16 oamIx;
|
||||
s16 tempY;
|
||||
struct SpriteGroup *spriteGroup;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const u16 *src;
|
||||
|
||||
PichuArrivalSequence();
|
||||
|
||||
if (gCurrentPinballGame->pikaChargeTarget > 167)
|
||||
{
|
||||
gCurrentPinballGame->pikaSaverTileIndex[0] = gPikaSaverAnimFrameTable[(gMain.fieldFrameCount % 160) / 5];
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
gCurrentPinballGame->pikaSaverTileIndex[1] = gCurrentPinballGame->pikaSaverTileIndex[0] + 6;
|
||||
else
|
||||
gCurrentPinballGame->pikaSaverTileIndex[1] = gCurrentPinballGame->pikaSaverTileIndex[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pikaSaverTileIndex[0] = (gMain.fieldFrameCount % 50) / 25;
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
gCurrentPinballGame->pikaSaverTileIndex[1] = gCurrentPinballGame->pikaSaverTileIndex[0] + 9;
|
||||
else
|
||||
gCurrentPinballGame->pikaSaverTileIndex[1] = gCurrentPinballGame->pikaSaverTileIndex[0];
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
{
|
||||
gCurrentPinballGame->kickbackOccupied[0] = 1;
|
||||
gCurrentPinballGame->kickbackOccupied[1] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->kickbackOccupied[0 + gCurrentPinballGame->outLanePikaPosition] = 1;
|
||||
gCurrentPinballGame->kickbackOccupied[1 - gCurrentPinballGame->outLanePikaPosition] = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pikaKickbackTimer != 0)
|
||||
{
|
||||
if (gCurrentPinballGame->pikaKickbackTimer == 120)
|
||||
{
|
||||
// gCurrentPinballGame->outLaneSide + gCurrentPinballGame->outLanePikaPosition
|
||||
// Note: this can be && chained off of the previous if, once we have this line deciphered.
|
||||
if (gCurrentPinballGame->kickbackOccupied[gCurrentPinballGame->outLaneSide - 1] != 0)
|
||||
{
|
||||
if (gCurrentPinballGame->pikaChargeTarget > 167)
|
||||
{
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
gCurrentPinballGame->kickbackFiring = 1;
|
||||
gCurrentPinballGame->kickbackAnimProgress = 120;
|
||||
gCurrentPinballGame->kickbackAnimDuration = 120;
|
||||
gCurrentPinballGame->kickbackLaunchTimer = gCurrentPinballGame->kickbackAnimProgress;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
gCurrentPinballGame->kickbackAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->kickbackFrameId = 0;
|
||||
|
||||
if (gCurrentPinballGame->outLanePikaPosition != 2)
|
||||
{
|
||||
gCurrentPinballGame->pikaChargeTarget = 0;
|
||||
gCurrentPinballGame->pikaChargeProgress = 0;
|
||||
gCurrentPinballGame->prevChargeFillValue = 0;
|
||||
gCurrentPinballGame->chargeFillValue = 0;
|
||||
gCurrentPinballGame->chargeIndicatorXOffset = 0;
|
||||
gCurrentPinballGame->chargeIndicatorYOffset = -4;
|
||||
gCurrentPinballGame->chargeIndicatorScaleX = 256;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 256;
|
||||
gCurrentPinballGame->chargeFillAnimTimer = 0;
|
||||
gCurrentPinballGame->fullChargeSlideAnimTimer = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->kickbackBallHoverPos = gCurrentPinballGame->ball->positionQ1;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 30000;
|
||||
|
||||
if (gCurrentPinballGame->bonusPikaSaverCount <= 98)
|
||||
gCurrentPinballGame->bonusPikaSaverCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pikaKickbackTimer = 60;
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_pika_no_kickback);
|
||||
}
|
||||
|
||||
outlaneChuteIx = gCurrentPinballGame->outLaneSide - 1;
|
||||
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
gCurrentPinballGame->pikaSaverTileIndex[outlaneChuteIx] = (outlaneChuteIx) * 7 + 2;
|
||||
else
|
||||
gCurrentPinballGame->pikaSaverTileIndex[outlaneChuteIx] = 2;
|
||||
|
||||
DmaCopy16(3, gPikaSaverTilesGfx + (gCurrentPinballGame->pikaSaverTileIndex[outlaneChuteIx] * 0x180), 0x06010480 + ((outlaneChuteIx) * 0x180), 0x180);
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
gCurrentPinballGame->pikaSaverTileIndex[gCurrentPinballGame->outLaneSide - 1] = (gCurrentPinballGame->outLaneSide - 1) * 7 + 2;
|
||||
else
|
||||
gCurrentPinballGame->pikaSaverTileIndex[gCurrentPinballGame->outLaneSide - 1] = 2;
|
||||
|
||||
gCurrentPinballGame->pikaKickbackTimer--;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->kickbackFiring != 0)
|
||||
{
|
||||
if (gCurrentPinballGame->kickbackLaunchTimer > 1)
|
||||
{
|
||||
r5 = (gCurrentPinballGame->kickbackAnimProgress * 0x10000) / 10;
|
||||
gCurrentPinballGame->kickbackLaunchTimer--;
|
||||
if (gCurrentPinballGame->kickbackAnimProgress != 0)
|
||||
{
|
||||
gCurrentPinballGame->kickbackAnimProgress--;
|
||||
if (gCurrentPinballGame->kickbackAnimProgress == 40 && gCurrentPinballGame->kickbackLaunchTimer > 40)
|
||||
{
|
||||
gCurrentPinballGame->kickbackAnimProgress = 60;
|
||||
}
|
||||
}
|
||||
if (gCurrentPinballGame->kickbackLaunchTimer == 116)
|
||||
{
|
||||
if (gCurrentPinballGame->activePortraitType)
|
||||
gCurrentPinballGame->kickbackLaunchTimer = 120;
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->activePortraitType = 1;
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
{
|
||||
if (gCurrentPinballGame->outLaneSide == 1)
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_pikachu_kickback);
|
||||
else
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_pichu_kickback);
|
||||
m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_pikachu_kickback);
|
||||
m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x40);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gCurrentPinballGame->kickbackLaunchTimer == 115 && gCurrentPinballGame->activePortraitType == 1)
|
||||
m4aMPlayVolumeControl(&gMPlayInfo_SE1, 0xFFFF, 0x200);
|
||||
|
||||
// used for the horizontal 'floaty' movement when electric builds pre-launch.
|
||||
gCurrentPinballGame->ball->positionQ1.x =
|
||||
gCurrentPinballGame->kickbackBallHoverPos.x + ((Sin(r5) * 6) / 20000) +
|
||||
((gOutlaneCenterXPositions[gCurrentPinballGame->outLaneSide - 1] * 2 - gCurrentPinballGame->kickbackBallHoverPos.x) * (gCurrentPinballGame->kickbackAnimDuration - gCurrentPinballGame->kickbackAnimProgress)) / gCurrentPinballGame->kickbackAnimDuration;
|
||||
|
||||
tempY = ((gCurrentPinballGame->kickbackAnimDuration - gCurrentPinballGame->kickbackAnimProgress) * 40) / gCurrentPinballGame->kickbackAnimDuration;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->kickbackBallHoverPos.y - tempY;
|
||||
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ1.x * 128;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ1.y * 128;
|
||||
}
|
||||
else if (gCurrentPinballGame->kickbackLaunchTimer == 1)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ1.x = gOutlaneCenterXPositions[gCurrentPinballGame->outLaneSide - 1] * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = 702;
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ1.x * 128;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ1.y * 128;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
// fly me to the moon
|
||||
gCurrentPinballGame->ball->velocity.y = -300;
|
||||
m4aSongNumStart(SE_KICKBACK_THUNDERWAVE);
|
||||
gCurrentPinballGame->kickbackLaunchTimer = 0;
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
gCurrentPinballGame->holeIndicators[(gCurrentPinballGame->outLaneSide - 1) * 3] = 1;
|
||||
|
||||
if (gCurrentPinballGame->allHolesLit == 0 &&
|
||||
(gCurrentPinballGame->holeIndicators[0] &
|
||||
gCurrentPinballGame->holeIndicators[1] &
|
||||
gCurrentPinballGame->holeIndicators[2] &
|
||||
gCurrentPinballGame->holeIndicators[3]))
|
||||
{
|
||||
gCurrentPinballGame->allHolesLit = 1;
|
||||
gCurrentPinballGame->allHolesLitBlinkTimer = 126;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 4000;
|
||||
}
|
||||
|
||||
PlayRumble(11);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->kickbackLaunchTimer >= 100)
|
||||
{
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
gCurrentPinballGame->pikaSaverTileIndex[gCurrentPinballGame->outLaneSide - 1] = (gCurrentPinballGame->outLaneSide - 1) * 7 + 2;
|
||||
else
|
||||
gCurrentPinballGame->pikaSaverTileIndex[gCurrentPinballGame->outLaneSide - 1] = 2;
|
||||
|
||||
if (gCurrentPinballGame->kickbackLaunchTimer == 100)
|
||||
{
|
||||
gMain.fieldSpriteGroups[38]->available = 1;
|
||||
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2 && gCurrentPinballGame->outLaneSide == 2)
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverFullCoverageGfx, 0x06015800, 0x2400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverPartialCoverageGfx, 0x06015800, 0x2400);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCatchOverlayAnimData[gCurrentPinballGame->kickbackFrameId][1] > gCurrentPinballGame->kickbackAnimFrameTimer)
|
||||
gCurrentPinballGame->kickbackAnimFrameTimer++;
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->kickbackAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->kickbackFrameId++;
|
||||
|
||||
if (gCurrentPinballGame->kickbackFrameId == 23)
|
||||
{
|
||||
m4aSongNumStop(SE_KICKBACK_THUNDERWAVE);
|
||||
m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->kickbackFrameId > 25)
|
||||
{
|
||||
gCurrentPinballGame->kickbackFrameId = 25;
|
||||
gCurrentPinballGame->kickbackFiring = 0;
|
||||
gMain.fieldSpriteGroups[38]->available = 0;
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
|
||||
outlaneChuteIx = gCurrentPinballGame->outLaneSide - 1;
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2)
|
||||
gCurrentPinballGame->pikaSaverTileIndex[outlaneChuteIx] = outlaneChuteIx * 9;
|
||||
else
|
||||
gCurrentPinballGame->pikaSaverTileIndex[outlaneChuteIx] = 0;
|
||||
|
||||
DmaCopy16(3, gPikaSaverTilesGfx + (gCurrentPinballGame->pikaSaverTileIndex[outlaneChuteIx] * 0x180), 0x06010480 + (outlaneChuteIx * 0x180), 0x180);
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->kickbackFrameId >= 17 && gCurrentPinballGame->kickbackFrameId <= 23)
|
||||
{
|
||||
if ((gMain.systemFrameCount & 3) >> 1)
|
||||
gCurrentPinballGame->cameraBaseX = -3;
|
||||
else
|
||||
gCurrentPinballGame->cameraBaseX = 3;
|
||||
}
|
||||
|
||||
oamIx = gCatchOverlayAnimData[gCurrentPinballGame->kickbackFrameId][0];
|
||||
outlaneChuteIx = gCurrentPinballGame->outLaneSide - 1;
|
||||
|
||||
spriteGroup = gMain.fieldSpriteGroups[38];
|
||||
spriteGroup->baseX = (outlaneChuteIx * 177) - (gCurrentPinballGame->cameraXOffset - 16);
|
||||
if (gCurrentPinballGame->kickbackFiring)
|
||||
{
|
||||
spriteGroup->baseY = 380 - gCurrentPinballGame->cameraYOffset;
|
||||
gCurrentPinballGame->kickbackOccupied[outlaneChuteIx] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteGroup->baseY = 180;
|
||||
gCurrentPinballGame->kickbackOccupied[outlaneChuteIx] = 1;
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
oamSimple = &spriteGroup->oam[j];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gCatchOverlayOamData[oamIx][j * 3 + 0];
|
||||
*dst++ = gCatchOverlayOamData[oamIx][j * 3 + 1];
|
||||
*dst++ = gCatchOverlayOamData[oamIx][j * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += spriteGroup->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += spriteGroup->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
spriteGroup = gMain.fieldSpriteGroups[29];
|
||||
|
||||
if (spriteGroup->available)
|
||||
{
|
||||
for (outlaneChuteIx = 0; outlaneChuteIx <= 1; outlaneChuteIx++)
|
||||
{
|
||||
spriteGroup = gMain.fieldSpriteGroups[29 + outlaneChuteIx];
|
||||
spriteGroup->baseX = (outlaneChuteIx * 177) - (gCurrentPinballGame->cameraXOffset - 16);
|
||||
if (gCurrentPinballGame->kickbackOccupied[outlaneChuteIx])
|
||||
{
|
||||
if ((gMain.fieldFrameCount % 5) == 0)
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverTilesGfx + (gCurrentPinballGame->pikaSaverTileIndex[outlaneChuteIx] * 0x180), 0x06010480 + (outlaneChuteIx * 0x180), 0x180);
|
||||
}
|
||||
|
||||
tempY = 380 - gCurrentPinballGame->cameraYOffset;
|
||||
spriteGroup->baseY = tempY;
|
||||
}
|
||||
else
|
||||
spriteGroup->baseY = 200;
|
||||
|
||||
for (j = 0; j <= 1; j++)
|
||||
{
|
||||
oamSimple = &spriteGroup->oam[j];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + spriteGroup->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + spriteGroup->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PichuArrivalSequence(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
struct Vector32 tempVec;
|
||||
struct Vector32 tempVec2;
|
||||
u16 angle;
|
||||
int xx, yy;
|
||||
int squaredMagnitude;
|
||||
s16 index;
|
||||
|
||||
group = gMain.fieldSpriteGroups[41];
|
||||
if (gCurrentPinballGame->pichuEntranceTimer == 0)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->pichuEntranceTimer == 800)
|
||||
{
|
||||
group->available = 1;
|
||||
if (gCurrentPinballGame->pichuWalkMode == 1)
|
||||
{
|
||||
//Start entrance
|
||||
gCurrentPinballGame->walkMonXPos = 1090;
|
||||
gCurrentPinballGame->walkMonYPos = 4680;
|
||||
gCurrentPinballGame->creatureWaypointIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Start exit
|
||||
gCurrentPinballGame->walkMonXPos = 2000;
|
||||
gCurrentPinballGame->walkMonYPos = 3820;
|
||||
gCurrentPinballGame->creatureWaypointIndex = 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->pichuEntranceTimer == 799)
|
||||
{
|
||||
if (gCurrentPinballGame->pichuWalkMode != 1)
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverTilesGfx, (void *)0x06010600, 0x180);
|
||||
}
|
||||
}
|
||||
tempVec.x = gPikaSaverWaypoints[gCurrentPinballGame->creatureWaypointIndex].x - 120 - gCurrentPinballGame->walkMonXPos;
|
||||
tempVec.y = gPikaSaverWaypoints[gCurrentPinballGame->creatureWaypointIndex].y - 160 - gCurrentPinballGame->walkMonYPos;
|
||||
xx = tempVec.x * tempVec.x;
|
||||
yy = tempVec.y * tempVec.y;
|
||||
squaredMagnitude = xx + yy;
|
||||
angle = ArcTan2(tempVec.x, -tempVec.y);
|
||||
tempVec2.x = (Cos(angle) * 7) / 20000;
|
||||
tempVec2.y = (Sin(angle) * -7) / 20000;
|
||||
index = gAngleToDirectionTable[angle / 0x2000] + (gMain.systemFrameCount % 24) / 8;
|
||||
gCurrentPinballGame->walkMonXPos += tempVec2.x;
|
||||
gCurrentPinballGame->walkMonYPos += tempVec2.y;
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->walkMonXPos / 10 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->walkMonYPos / 10 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY > 180)
|
||||
group->baseY = 180;
|
||||
else if (group->baseY < -30)
|
||||
group->baseY = -30;
|
||||
|
||||
DmaCopy16(3, gMonHatchSpriteGroup5_Gfx + (index + 30) * 0x120 , (void *)0x060112A0, 0x120);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].priority = 1;
|
||||
gOamBuffer[oamSimple->oamId].paletteNum = 3;
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
if (squaredMagnitude < 2500)
|
||||
{
|
||||
gCurrentPinballGame->creatureWaypointIndex++;
|
||||
if (gCurrentPinballGame->pichuWalkMode == 1)
|
||||
{
|
||||
if (gCurrentPinballGame->creatureWaypointIndex == 4)
|
||||
{
|
||||
DmaCopy16(3, gPikachuSaverTilesGfx, (void *)0x06010600, 0x180);
|
||||
gCurrentPinballGame->outLanePikaPosition = 2;
|
||||
gMain.fieldSpriteGroups[41]->available = 0;
|
||||
gCurrentPinballGame->pichuEntranceTimer = 1;
|
||||
m4aSongNumStart(SE_PICHU_IN_POSITION_CHIRP);
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->creatureWaypointIndex == 7)
|
||||
{
|
||||
gMain.fieldSpriteGroups[41]->available = 0;
|
||||
gCurrentPinballGame->pichuEntranceTimer = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->pichuEntranceTimer--;
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#include "global.h"
|
||||
#include "agb_sram.h"
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/ereader.h"
|
||||
|
|
@ -17,61 +16,18 @@ struct BoardProcessPair
|
|||
};
|
||||
|
||||
extern struct BoardProcessPair CurrentBoardProcPairs_020028D8[9];
|
||||
extern u8 gBoardGfxBuffer[];
|
||||
extern u8 gBoardBGTileBufferAlt[];
|
||||
|
||||
extern const struct BoardProcessPair BoardProcPairs_086B077C[];
|
||||
extern const VoidFunc gFieldInitFuncs[];
|
||||
extern struct SpriteGroup *gMainFieldSpriteGroups[][60];
|
||||
extern struct SpriteGroup *gBonusFieldSpriteGroups[][30];
|
||||
extern const u8 gBoardActionTilesGfx[];
|
||||
extern const u8 gEggModeTilesGfx[];
|
||||
extern const u8 gCaptureModeTilesGfx[];
|
||||
extern const u8 gCaptureScreenTilesGfx[];
|
||||
extern const u8 gRubyBoardBonusGfx[];
|
||||
extern const u8 gRubyBoardBonusObjPalette[];
|
||||
extern const u8 gSapphireBoardBonusGfx[];
|
||||
extern const u8 gSapphireBoardBonusObjPalette[];
|
||||
extern const u8 gSapphireCatchTilesGfx[];
|
||||
extern const u8 gHatchRevealTilesGfx[];
|
||||
extern const u8 gHatchStartTilesGfx[];
|
||||
extern const u8 gHatchStage2TilesGfx[];
|
||||
extern const u8 gHatchStage3TilesGfx[];
|
||||
extern const u8 gHatchFinalTilesGfx[];
|
||||
extern const u8 gAlphabetTilesGfx[][0x40];
|
||||
extern const u8 gSpaceTileGfx[0x40];
|
||||
extern const u8 gDecimalDigitTilesGfx[][0x40];
|
||||
extern const u8 gPokemonNameDisplayGfx[];
|
||||
extern const u8 gEggPortraitTilesGfx[];
|
||||
extern const u8 gMainBoardBallSave_Gfx[];
|
||||
extern const u8 gMainBoardEndOfBall_Gfx[];
|
||||
extern const u8 gSapphireBoardZigzagoonFx_Gfx[];
|
||||
extern const s16 gCaughtTextChars[];
|
||||
extern const u16 gShopCursorToItemMap[];
|
||||
extern const u8 *gEvoItemAppear_GfxList[];
|
||||
extern const s16 gEvoShopAnimFrames[][7];
|
||||
extern const u8 gRubyBoardHatchCave_Gfx[][0x480];
|
||||
extern const u8 gRubyFlashingDecorationTiles[][0x300];
|
||||
extern const u8 gRubyBoardSharpedo_Gfx[][0x260];
|
||||
extern const u8 gRubyFlashingTiles_Secondary[][0x100];
|
||||
extern const u8 gRubyBoardShopDoor_Gfx[][0x180];
|
||||
extern const u8 gRubyStageCyndaquil_Gfx[][0x280];
|
||||
extern const u8 gRubyBoardShop_Gfx[][0x500];
|
||||
extern const u8 gHoleIndicatorTileGfx[][0x440];
|
||||
extern const s16 gHoleAnimKeyframeData[][2];
|
||||
extern const u8 gKecleonBonusClear_Gfx[0x2000];
|
||||
extern const u8 gKyogreBonusClear_Gfx[0x2000];
|
||||
extern const u8 gGroudonBoardBackgroundGfx[0x2000];
|
||||
extern const u8 gGroudonBonusClear_Gfx[0x2000];
|
||||
extern const u8 gRayquazaSkyBackgroundGfx[0x2800];
|
||||
extern const u8 gRayquazaWindBoardGfx[0x1C00];
|
||||
extern const u8 gRayquazaBonusClear_Gfx[0x2000];
|
||||
extern const u8 gRayquazaSpriteSheet[0x860];
|
||||
extern const u8 gSphealResultsScreenGfx[0x800];
|
||||
|
||||
extern const StateFunc gPinballGameStateFuncs[];
|
||||
extern const u8 gDxModePikachuObjTiles[];
|
||||
|
||||
extern void SaveGameToSram(void);
|
||||
extern void RestoreGameState(u16);
|
||||
|
||||
void ClampPortraitSpritesToOffscreen(void);
|
||||
void SetBallPositionForBonusReturn(void);
|
||||
void ClearBG0Tilemap(void);
|
||||
|
|
@ -80,21 +36,6 @@ void InitPinballGameState(void);
|
|||
void ConfigureBoardProcessesForField(void);
|
||||
void UpdateButtonActionsFromJoy(void);
|
||||
void ReplayButtonActionsFromRecording(void);
|
||||
void SaveGameStateSnapshot(s16);
|
||||
void SaveGameToSram(void);
|
||||
void RestoreGameState(u16);
|
||||
void RestoreFieldSpecificGraphics(void);
|
||||
void RestoreMainFieldDynamicGraphics(void);
|
||||
void RestoreRubyBoardTileGraphics(void);
|
||||
void RestoreSapphireBoardTileGraphics(void);
|
||||
void nullsub_18(void);
|
||||
void RestoreDusclopsBonusGraphics(void);
|
||||
void RestoreKecleonBonusGraphics(void);
|
||||
void RestoreKyogreBonusGraphics(void);
|
||||
void RestoreGroudonBonusGraphics(void);
|
||||
void RestoreRayquazaBonusGraphics(void);
|
||||
void RestoreSphealBonusGraphics(void);
|
||||
|
||||
|
||||
void PinballGameMain(void)
|
||||
{
|
||||
|
|
@ -129,7 +70,7 @@ void PinballGame_State0_49ED4(void)
|
|||
case 0:
|
||||
SetupDisplayRegistersForField();
|
||||
InitPinballGameState();
|
||||
loadIntroduction();
|
||||
loadFieldBoardGraphics();
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[0], (void *)OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
if (gMain.eReaderBonuses[EREADER_DX_MODE_CARD])
|
||||
DmaCopy16(3, &gBallPalettes[gCurrentPinballGame->ballUpgradeType], (void *)OBJ_PLTT + 0x20, 0x20);
|
||||
|
|
@ -161,7 +102,7 @@ void PinballGame_State0_49ED4(void)
|
|||
case 1:
|
||||
SetupDisplayRegistersForField();
|
||||
InitPinballGameState();
|
||||
loadIntroduction();
|
||||
loadFieldBoardGraphics();
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[0], (void *)OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
if (gMain.eReaderBonuses[EREADER_DX_MODE_CARD])
|
||||
DmaCopy16(3, &gBallPalettes[gCurrentPinballGame->ballUpgradeType], (void *)OBJ_PLTT + 0x20, 0x20);
|
||||
|
|
@ -187,7 +128,7 @@ void PinballGame_State0_49ED4(void)
|
|||
case 3:
|
||||
SetupDisplayRegistersForField();
|
||||
InitPinballGameState();
|
||||
loadIntroduction();
|
||||
loadFieldBoardGraphics();
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[0], (void *)OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
ConfigureBoardProcessesForField();
|
||||
for (i = 0; i < 9; i++)
|
||||
|
|
@ -960,698 +901,4 @@ void ReplayButtonActionsFromRecording(void)
|
|||
|
||||
if (gCurrentPinballGame->newButtonActions[1])
|
||||
gMain.newKeys = A_BUTTON;
|
||||
}
|
||||
|
||||
void SaveGameStateSnapshot(s16 arg0)
|
||||
{
|
||||
s16 i;
|
||||
u16 *var0;
|
||||
|
||||
if (gMPlayInfo_BGM.status >= 0)
|
||||
{
|
||||
gCurrentPinballGame->savedBgmSongHeader = gMPlayInfo_BGM.songHeader;
|
||||
m4aMPlayStop(&gMPlayInfo_BGM);
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->savedBgmSongHeader = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
gCurrentPinballGame->savedSpriteAvailability[gMain.isBonusField][i] = gMain.spriteGroups[i].available;
|
||||
|
||||
DmaCopy16(3, (void *)OBJ_PLTT, gCurrentPinballGame->savedObjPalette[gMain.isBonusField], OBJ_PLTT_SIZE);
|
||||
DmaCopy16(3, (void *)BG_PLTT, gCurrentPinballGame->savedBgPalette[gMain.isBonusField], BG_PLTT_SIZE);
|
||||
if (!arg0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bgOffsets0 = gMain.bgOffsets[0];
|
||||
gCurrentPinballGame->bgOffsets1 = gMain.bgOffsets[1];
|
||||
gCurrentPinballGame->bgOffsets2 = gMain.bgOffsets[2];
|
||||
gCurrentPinballGame->bgOffsets3 = gMain.bgOffsets[3];
|
||||
gCurrentPinballGame->savedField = gMain.selectedField;
|
||||
gCurrentPinballGame->savedTempField = gMain.tempField;
|
||||
gCurrentPinballGame->savedIsBonusField = gMain.isBonusField;
|
||||
gCurrentPinballGame->savedModeChangeFlags = gMain.modeChangeFlags;
|
||||
gCurrentPinballGame->savedDebugMenuCursorIndex = gMain.debugMenuCursorIndex;
|
||||
gCurrentPinballGame->savedPendingModeChangeType = gMain.pendingModeChangeType;
|
||||
gCurrentPinballGame->savedAnimationTimer = gMain.animationTimer;
|
||||
gCurrentPinballGame->savedModeChangeDelayTimer = gMain.modeChangeDelayTimer;
|
||||
gCurrentPinballGame->savedShopPanelActive = gMain.shopPanelActive;
|
||||
gCurrentPinballGame->savedShopPanelSlideOffset = gMain.shopPanelSlideOffset;
|
||||
gCurrentPinballGame->savedBlendControl = gCurrentPinballGame->pauseBlendControl;
|
||||
gCurrentPinballGame->savedBlendAlpha = gCurrentPinballGame->pauseBlendAlpha;
|
||||
gCurrentPinballGame->savedBlendBrightness = gCurrentPinballGame->pauseBlendBrightness;
|
||||
gCurrentPinballGame->savedScoreOverlayActive = gCurrentPinballGame->pauseScoreOverlayActive;
|
||||
gCurrentPinballGame->savedVCount = gCurrentPinballGame->pauseVCount;
|
||||
gCurrentPinballGame->ballSpeed = gMain_saveData.ballSpeed;
|
||||
|
||||
for (i = 0; i < NUM_EREADER_CARDS; i++)
|
||||
gCurrentPinballGame->eReaderBonuses[i] = gMain.eReaderBonuses[i];
|
||||
}
|
||||
|
||||
void SaveGameToSram(void)
|
||||
{
|
||||
gCurrentPinballGame->saveDataValid = 1;
|
||||
WriteAndVerifySramFast((const u8 *)gCurrentPinballGame, (void *)SRAM + 0x544, sizeof(*gCurrentPinballGame));
|
||||
}
|
||||
|
||||
void RestoreGameState(u16 arg0)
|
||||
{
|
||||
s16 i, j;
|
||||
s16 var0, var1;
|
||||
int var2;
|
||||
|
||||
if (arg0 == 1)
|
||||
{
|
||||
ReadSramFast((void *)SRAM + 0x544, (u8 *)gCurrentPinballGame, sizeof(*gCurrentPinballGame));
|
||||
}
|
||||
else if (arg0 == 2)
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.pinballGame, gCurrentPinballGame, sizeof(*gCurrentPinballGame));
|
||||
gCurrentPinballGame->ball = &gCurrentPinballGame->ballStates[0];
|
||||
gCurrentPinballGame->secondaryBall = &gCurrentPinballGame->ballStates[0];
|
||||
var2 = gMain.idleDemoVariant;
|
||||
if ((var2 & 0x3) == 1)
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinMomentum = 0;
|
||||
gCurrentPinballGame->kickbackAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->kickbackFrameId = 0;
|
||||
gCurrentPinballGame->pikaChargeTarget = 0;
|
||||
gCurrentPinballGame->pikaChargeProgress = 0;
|
||||
gCurrentPinballGame->prevChargeFillValue = 0;
|
||||
gCurrentPinballGame->chargeFillValue = 0;
|
||||
gCurrentPinballGame->chargeIndicatorXOffset = 0;
|
||||
gCurrentPinballGame->chargeIndicatorYOffset = -4;
|
||||
gCurrentPinballGame->chargeIndicatorScaleX = 256;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 256;
|
||||
gCurrentPinballGame->chargeFillAnimTimer = 0;
|
||||
gCurrentPinballGame->fullChargeSlideAnimTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg0 != 0)
|
||||
{
|
||||
gMain.selectedField = gCurrentPinballGame->savedField;
|
||||
gMain.tempField = gCurrentPinballGame->savedTempField;
|
||||
gMain.isBonusField = gCurrentPinballGame->savedIsBonusField;
|
||||
gMain.modeChangeFlags = gCurrentPinballGame->savedModeChangeFlags;
|
||||
gMain.debugMenuCursorIndex = gCurrentPinballGame->savedDebugMenuCursorIndex;
|
||||
gMain.pendingModeChangeType = gCurrentPinballGame->savedPendingModeChangeType;
|
||||
gMain.animationTimer = gCurrentPinballGame->savedAnimationTimer;
|
||||
gMain.modeChangeDelayTimer = gCurrentPinballGame->savedModeChangeDelayTimer;
|
||||
gMain.shopPanelActive = gCurrentPinballGame->savedShopPanelActive;
|
||||
gMain.shopPanelSlideOffset = gCurrentPinballGame->savedShopPanelSlideOffset;
|
||||
gMain.blendControl = gCurrentPinballGame->savedBlendControl;
|
||||
gMain.blendAlpha = gCurrentPinballGame->savedBlendAlpha;
|
||||
gMain.blendBrightness = gCurrentPinballGame->savedBlendBrightness;
|
||||
gMain.scoreOverlayActive = gCurrentPinballGame->savedScoreOverlayActive;
|
||||
gMain.vCount = gCurrentPinballGame->savedVCount;
|
||||
gMain.bgOffsets[0] = gCurrentPinballGame->bgOffsets0;
|
||||
gMain.bgOffsets[1] = gCurrentPinballGame->bgOffsets1;
|
||||
gMain.bgOffsets[2] = gCurrentPinballGame->bgOffsets2;
|
||||
gMain.bgOffsets[3] = gCurrentPinballGame->bgOffsets3;
|
||||
for (i = 0; i < NUM_EREADER_CARDS; i++)
|
||||
gMain.eReaderBonuses[i] = gCurrentPinballGame->eReaderBonuses[i];
|
||||
|
||||
gCurrentPinballGame->startButtonDisabled = 1;
|
||||
if (arg0 == 1 && gMain.selectedField < MAIN_FIELD_COUNT)
|
||||
{
|
||||
gCurrentPinballGame->cameraYViewport = gCurrentPinballGame->cameraBaseY +
|
||||
gCurrentPinballGame->tiltYOffset +
|
||||
gCurrentPinballGame->cameraScrollOffset +
|
||||
gCurrentPinballGame->cameraYAdjust;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->cameraYViewport = gCurrentPinballGame->hudSpriteBaseY;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->fadeSubState = 0;
|
||||
gMain.continueFromSave = 0;
|
||||
loadIntroduction();
|
||||
if (gMain.selectedField == FIELD_RUBY && gCurrentPinballGame->boardCollisionConfigChanged)
|
||||
SetBoardCollisionConfig(1);
|
||||
|
||||
if (gMain.selectedField < MAIN_FIELD_COUNT)
|
||||
{
|
||||
for (i = 0; i < 22; i++)
|
||||
{
|
||||
var0 = i + gCurrentPinballGame->ballLaunchSpeed;
|
||||
var1 = (i + 10 + gCurrentPinballGame->ballLaunchSpeed) % 22;
|
||||
if (var0 < 32)
|
||||
{
|
||||
DmaCopy16(3, &gBoardGfxBuffer[var0 * 0x400], (void *)0x6008000 + var1 * 0x400, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 -= 32;
|
||||
DmaCopy16(3, &gBoardBGTileBufferAlt[var0 * 0x400], (void *)0x6008000 + var1 * 0x400, 0x400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x800; i++)
|
||||
gBG0TilemapBuffer[i] = 0x1FF;
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x6002000, 0x1000);
|
||||
if (gMain.scoreOverlayActive)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState == 6)
|
||||
{
|
||||
for (j = 0; j <= gCurrentPinballGame->cutsceneTilemapColumn; j++)
|
||||
{
|
||||
for (i = 2; i < 12; i++)
|
||||
gBG0TilemapBuffer[(i + 15) * 0x20 + j] = 0xC100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j <= gCurrentPinballGame->cutsceneTilemapColumn; j++)
|
||||
{
|
||||
for (i = 1; i < 11; i++)
|
||||
gBG0TilemapBuffer[(i + 15) * 0x20 + j] = 0xC100;
|
||||
}
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x6002000, 0x800);
|
||||
}
|
||||
|
||||
DmaCopy16(3, gCurrentPinballGame->savedObjPalette[gMain.isBonusField], (void *)OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
DmaCopy16(3, gCurrentPinballGame->savedBgPalette[gMain.isBonusField], (void *)BG_PLTT, BG_PLTT_SIZE);
|
||||
DmaCopy16(3, &gBallPalettes[gCurrentPinballGame->ballUpgradeType], (void *)OBJ_PLTT + 0x20, 0x20);
|
||||
RestoreFieldSpecificGraphics();
|
||||
switch (gMain.selectedField)
|
||||
{
|
||||
case FIELD_RUBY:
|
||||
RubyBoardProcess_0A_50848();
|
||||
LoadShopItemGraphics(gCurrentPinballGame->evolutionShopActive);
|
||||
break;
|
||||
case FIELD_SAPPHIRE:
|
||||
SapphireBoardProcess_0A_50AD4();
|
||||
break;
|
||||
case FIELD_DUSCLOPS:
|
||||
DusclopsBoardProcess_0A_50D48();
|
||||
break;
|
||||
case FIELD_KECLEON:
|
||||
KecleonBoardProcess_0A_50DE0();
|
||||
break;
|
||||
case FIELD_KYOGRE:
|
||||
KyogreBoardProcess_0A_50F04();
|
||||
break;
|
||||
case FIELD_GROUDON:
|
||||
GroudonBoardProcess_0A_50FD4();
|
||||
break;
|
||||
case FIELD_RAYQUAZA:
|
||||
RayquazaBoardProcess_0A_51090();
|
||||
break;
|
||||
case FIELD_SPHEAL:
|
||||
SphealBoardProcess_0A_51150();
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
gMain.spriteGroups[i].available = gCurrentPinballGame->savedSpriteAvailability[gMain.isBonusField][i];
|
||||
|
||||
if (arg0 == 1)
|
||||
{
|
||||
gCurrentPinballGame->saveDataValid = 0;
|
||||
WriteAndVerifySramFast((const u8 *)gCurrentPinballGame, (void *)SRAM + 0x544, sizeof(gCurrentPinballGame->saveDataValid));
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreFieldSpecificGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
struct PokemonSpecies *species;
|
||||
const u16 *var1;
|
||||
s16 var2, var3;
|
||||
|
||||
switch (gMain.selectedField)
|
||||
{
|
||||
case FIELD_RUBY:
|
||||
RestoreMainFieldDynamicGraphics();
|
||||
RestoreRubyBoardTileGraphics();
|
||||
break;
|
||||
case FIELD_SAPPHIRE:
|
||||
RestoreMainFieldDynamicGraphics();
|
||||
RestoreSapphireBoardTileGraphics();
|
||||
break;
|
||||
case FIELD_DUSCLOPS:
|
||||
nullsub_18();
|
||||
RestoreDusclopsBonusGraphics();
|
||||
break;
|
||||
case FIELD_KECLEON:
|
||||
nullsub_18();
|
||||
RestoreKecleonBonusGraphics();
|
||||
break;
|
||||
case FIELD_KYOGRE:
|
||||
nullsub_18();
|
||||
RestoreKyogreBonusGraphics();
|
||||
break;
|
||||
case FIELD_GROUDON:
|
||||
nullsub_18();
|
||||
RestoreGroudonBonusGraphics();
|
||||
break;
|
||||
case FIELD_RAYQUAZA:
|
||||
nullsub_18();
|
||||
RestoreRayquazaBonusGraphics();
|
||||
break;
|
||||
case FIELD_SPHEAL:
|
||||
nullsub_18();
|
||||
RestoreSphealBonusGraphics();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->activePortraitType - 1)
|
||||
{
|
||||
case 0:
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2 && gCurrentPinballGame->outLaneSide == 2)
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverFullCoverageGfx, (void *)0x6015800, 0x2400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverPartialCoverageGfx, (void *)0x6015800, 0x2400);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
DmaCopy16(3, gEggModeTilesGfx, (void *)0x6015800, 0x1000);
|
||||
break;
|
||||
case 2:
|
||||
DmaCopy16(3, gCaptureModeTilesGfx, (void *)0x6015800, 0xCA0);
|
||||
break;
|
||||
case 3:
|
||||
DmaCopy16(3, gModeBannerTilemaps[gCurrentPinballGame->bannerGfxIndex], (void *)0x6015800, 0x25E0);
|
||||
break;
|
||||
case 4:
|
||||
DmaCopy16(3, gHatchStartTilesGfx, (void *)0x6015800, 0x2000);
|
||||
break;
|
||||
case 5:
|
||||
DmaCopy16(3, gHatchStage2TilesGfx, (void *)0x6015800, 0x800);
|
||||
break;
|
||||
case 6:
|
||||
DmaCopy16(3, gHatchStage3TilesGfx, (void *)0x6015800, 0x2000);
|
||||
break;
|
||||
case 7:
|
||||
DmaCopy16(3, gHatchFinalTilesGfx, (void *)0x6015800, 0x1800);
|
||||
break;
|
||||
case 8:
|
||||
DmaCopy16(3, gCaptureScreenTilesGfx, (void *)0x6015800, 0x1C00);
|
||||
break;
|
||||
case 9:
|
||||
DmaCopy16(3, gSapphireCatchTilesGfx, (void *)0x6015800, 0x1400);
|
||||
break;
|
||||
case 10:
|
||||
DmaCopy16(3, gHatchRevealTilesGfx, (void *)0x6015800, 0x2800);
|
||||
break;
|
||||
case 11:
|
||||
DmaCopy16(3, gEggPortraitTilesGfx, (void *)0x6015800, 0x280);
|
||||
break;
|
||||
case 13:
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] == ' ')
|
||||
{
|
||||
DmaCopy16(3, gSpaceTileGfx, (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
int var0 = gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] - 'A';
|
||||
DmaCopy16(3, gAlphabetTilesGfx[var0], (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
}
|
||||
DmaCopy16(3, gPokemonNameDisplayGfx, (void *)0x6015C00, 0x940);
|
||||
break;
|
||||
case 12:
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] == ' ')
|
||||
{
|
||||
DmaCopy16(3, gSpaceTileGfx, (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
int var0 = gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] - 'A';
|
||||
DmaCopy16(3, gAlphabetTilesGfx[var0], (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (gCaughtTextChars[i] == ' ')
|
||||
{
|
||||
DmaCopy16(3, gSpaceTileGfx, (void *)0x6015800 + (i + 10) * 0x40, 0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
int var0 = gCaughtTextChars[i] - 'A';
|
||||
DmaCopy16(3, gAlphabetTilesGfx[var0], (void *)0x6015800 + (i + 10) * 0x40, 0x40);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
DmaCopy16(3, gEvoItemAppear_GfxList[gCurrentPinballGame->evoItemGfxIndex], (void *)0x6015800, 0x1C00);
|
||||
break;
|
||||
case 15:
|
||||
DmaCopy16(3, gBoardActionTilesGfx, (void *)0x6015800, 0x2400);
|
||||
break;
|
||||
case 16:
|
||||
DmaCopy16(3, gHatchFinalTilesGfx, (void *)0x6015800, 0x1800);
|
||||
break;
|
||||
case 17:
|
||||
DmaCopy16(3, gPokemonNameDisplayGfx, (void *)0x6015C00, 0x940);
|
||||
if (gCurrentPinballGame->evolutionShopActive == 0)
|
||||
{
|
||||
var1 = gShopItemData[gShopCursorToItemMap[gCurrentPinballGame->shopItemCursor]];
|
||||
var2 = var1[3] / 10;
|
||||
DmaCopy16(3, gDecimalDigitTilesGfx[var2], (void *)0x6015DA0, 0x40);
|
||||
var3 = var1[3] % 10;
|
||||
DmaCopy16(3, gDecimalDigitTilesGfx[var3], (void *)0x6015E60, 0x40);
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
DmaCopy16(3, gMainBoardBallSave_Gfx, (void *)0x6015800, 0x2400);
|
||||
break;
|
||||
case 19:
|
||||
DmaCopy16(3, gMainBoardEndOfBall_Gfx, (void *)0x6015800, 0x2800);
|
||||
break;
|
||||
case 20:
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
DmaCopy16(3, gRubyBoardBonusGfx, (void *)0x6015800, 0x1800);
|
||||
DmaCopy16(3, gRubyBoardBonusObjPalette, (void *)OBJ_PLTT + 0x1C0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gSapphireBoardBonusGfx, (void *)0x6015800, 0x1800);
|
||||
DmaCopy16(3, gSapphireBoardBonusObjPalette, (void *)OBJ_PLTT + 0x1C0, 0x20);
|
||||
}
|
||||
break;
|
||||
case 21:
|
||||
DmaCopy16(3, gSapphireBoardZigzagoonFx_Gfx, (void *)0x6015800, 0xC00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreMainFieldDynamicGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
s16 var0;
|
||||
|
||||
LoadCatchSpriteGraphics();
|
||||
LoadEggSpriteGraphics();
|
||||
|
||||
for (i = 0; i <= 1; i++)
|
||||
{
|
||||
var0 = gCurrentPinballGame->flipper[i].position / 2;
|
||||
DmaCopy16(3, gFlipperTileGraphics[var0], ((i * 0x200) + 0x06010000), 0x200);
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->ball->spinAngle / 0x1000;
|
||||
DmaCopy16(3, gBallRotationTileGraphics[var0], 0x06010400, 0x80);
|
||||
|
||||
for (i = 0; i <= 1; i++)
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverTilesGfx + ((var0 =gCurrentPinballGame->pikaSaverTileIndex[i]) * 0x180), 0x06010480 + (i * 0x180), 0x180);
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->pikachuSpinFrame;
|
||||
DmaCopy16(3, gMainBoardPikaSpinner_Gfx[var0 = gCurrentPinballGame->pikachuSpinFrame], 0x06010780, 0x120);
|
||||
var0 = gCurrentPinballGame->chargeFillValue;
|
||||
DmaCopy16(3, gChargeFillIndicator_Gfx[var0], 0x06010AE0, 0x80);
|
||||
|
||||
for (i = 0; i <= 1; i++)
|
||||
{
|
||||
switch (gCurrentPinballGame->portraitRenderMode[i])
|
||||
{
|
||||
case 0:
|
||||
DmaCopy16(3, gPortraitGenericGraphics[gCurrentPinballGame->portraitGfxIndex[i]], 0x06010CA0 + (i * 0x300), 0x300);
|
||||
gCurrentPinballGame->ball += 0; //TODO: Dumb match is still a match...
|
||||
break;
|
||||
case 9:
|
||||
if (gCurrentPinballGame->evoChainPosition > 0)
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[gCurrentPinballGame->evoTargetSpecies] == 0)
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = 205;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[i] / 15] + (gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x20, 0x050003A0, 0x20);
|
||||
}
|
||||
else if (gMain_saveData.pokedexFlags[gCurrentPinballGame->evoTargetSpecies] <= 3)
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = gCurrentPinballGame->evoTargetSpecies;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[0] + 15 * 0x20, 0x050003A0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = gCurrentPinballGame->evoTargetSpecies;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[i] / 15] + (gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x20, 0x050003A0, 0x20);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = gCurrentPinballGame->currentSpecies;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[i] / 15] + ((gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x20), 0x050003A0, 0x20);
|
||||
}
|
||||
case 3:
|
||||
DmaCopy16(3, gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[i] / 15] + (gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x300, 0x06010CA0 + (i * 0x18), 0x300);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[i]], 0x06010CA0 + (i * 0x300), 0x300);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->boardState == 4)
|
||||
{
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 7:
|
||||
case 8:
|
||||
if ((u32) gCurrentPinballGame->captureFlashTimer > 4)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (gCurrentPinballGame->captureSequenceTimer <= 31)
|
||||
{
|
||||
if (gCurrentPinballGame->captureFlashTimer > 4)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->boardState == 8)
|
||||
{
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 2:
|
||||
if (gCurrentPinballGame->captureFlashTimer > 4U)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (gCurrentPinballGame->captureSequenceTimer <= 31)
|
||||
{
|
||||
if (gCurrentPinballGame->captureFlashTimer > 4U)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DmaCopy16(3, gMainStageBonusTrap_Gfx[gCurrentPinballGame->bonusTrapAnimFrame], 0x060113C0, 0x300);
|
||||
DmaCopy16(3, gEvoItemTilesGfxPtrs[gCurrentPinballGame->evoItemGfxIndex] + var0 * 0x200, 0x060116C0, 0x200);
|
||||
DmaCopy16(3, gEggFrameTilesGfx[(s16)gEggAnimationFrameData[gCurrentPinballGame->eggAnimFrameIndex][3]], 0x06011CE0, 0x200);
|
||||
DmaCopy16(3, gBallShadowTileGraphics[gCurrentPinballGame->ballShadowTileIndex], 0x06011EE0, 0x200);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void RestoreRubyBoardTileGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
s16 var0;
|
||||
|
||||
var0 = gEggAnimationFrameData[gCurrentPinballGame->eggAnimFrameIndex][2];
|
||||
DmaCopy16(3, gRubyBoardHatchCave_Gfx[var0], (void *)0x60122A0, 0x480);
|
||||
var0 = (gMain.systemFrameCount % 50) / 25;
|
||||
DmaCopy16(3, gRubyFlashingDecorationTiles[var0], (void *)0x6012720, 0x300);
|
||||
DmaCopy16(3, gRubyBoardSharpedo_Gfx[gCurrentPinballGame->catchHoleTileVariant], (void *)0x6012C20, 0x260);
|
||||
for (i = 0; i < 2; i++)
|
||||
DmaCopy16(3, gRubyFlashingTiles_Secondary[var0], (void *)0x6010000 + (0x174 + i * 8) * 0x20, 0x100);
|
||||
|
||||
var0 = gCurrentPinballGame->shopDoorCurrentFrame & 0xF;
|
||||
DmaCopy16(3, gRubyBoardShopDoor_Gfx[var0], (void *)0x6013180, 0x180);
|
||||
if (gCurrentPinballGame->eggCaveState < 3)
|
||||
gCurrentPinballGame->cyndaquilFrame = 0;
|
||||
else
|
||||
gCurrentPinballGame->cyndaquilFrame = 1;
|
||||
|
||||
DmaCopy16(3, gRubyStageCyndaquil_Gfx[gCurrentPinballGame->cyndaquilFrame], (void *)0x6013300, 0x280);
|
||||
var0 = gEvoShopAnimFrames[gCurrentPinballGame->evolutionShopActive][(gCurrentPinballGame->shopAnimTimer % 42) / 6];
|
||||
DmaCopy16(3, gRubyBoardShop_Gfx[var0], (void *)0x6013D00, 0x500);
|
||||
}
|
||||
|
||||
void RestoreSapphireBoardTileGraphics(void)
|
||||
{
|
||||
s16 index;
|
||||
|
||||
switch (gCurrentPinballGame->holeLetterSystemState)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
index = gCurrentPinballGame->holeLetterCount;
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
index = 15;
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
break;
|
||||
case 5:
|
||||
index = gHoleAnimKeyframeData[gCurrentPinballGame->holeLetterCount][0];
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreDusclopsBonusGraphics(void)
|
||||
{
|
||||
DmaCopy16(3, gDusclopsBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
void RestoreKecleonBonusGraphics(void)
|
||||
{
|
||||
DmaCopy16(3, gKecleonBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
void RestoreKyogreBonusGraphics(void)
|
||||
{
|
||||
DmaCopy16(3, gKyogreBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[0] / 15] + (gCurrentPinballGame->portraitGfxIndex[0] % 15) * 0x300,
|
||||
(void *)0x6010CA0,
|
||||
0x300
|
||||
);
|
||||
}
|
||||
|
||||
void RestoreGroudonBonusGraphics(void)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 2)
|
||||
{
|
||||
DmaCopy16(3, gGroudonBoardBackgroundGfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gGroudonBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[0] / 15] + (gCurrentPinballGame->portraitGfxIndex[0] % 15) * 0x300,
|
||||
(void *)0x6010CA0,
|
||||
0x300
|
||||
);
|
||||
}
|
||||
|
||||
void RestoreRayquazaBonusGraphics(void)
|
||||
{
|
||||
u8 var0;
|
||||
|
||||
if (gCurrentPinballGame->boardState == 0)
|
||||
{
|
||||
DmaCopy16(3, gRayquazaSkyBackgroundGfx, (void *)0x6015800, 0x2800);
|
||||
}
|
||||
else if (gCurrentPinballGame->boardState == 1)
|
||||
{
|
||||
DmaCopy16(3, gRayquazaWindBoardGfx, (void *)0x6015800, 0x1C00);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gRayquazaBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->bossEntityState - 2;
|
||||
if (var0 > 9)
|
||||
{
|
||||
DmaCopy16(3, gRayquazaSpriteSheet, (void *)0x6011620, 0x860);
|
||||
}
|
||||
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[0] / 15] + (gCurrentPinballGame->portraitGfxIndex[0] % 15) * 0x300,
|
||||
(void *)0x6010CA0,
|
||||
0x300
|
||||
);
|
||||
}
|
||||
|
||||
void RestoreSphealBonusGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
int var0;
|
||||
u16 var1;
|
||||
|
||||
for (i = 0; i < 0x800; i++)
|
||||
gBG0TilemapBuffer[0x400 + i] = 0x200;
|
||||
|
||||
DmaCopy16(3, &gBG0TilemapBuffer[0x400], (void *)0x6001000, 0x1000);
|
||||
gMain.blendControl = 0x1C42;
|
||||
gMain.blendAlpha = 0xC04;
|
||||
for (i = 0; i < 0x140; i++)
|
||||
{
|
||||
var0 = i;
|
||||
if (i < 0)
|
||||
var0 += 31;
|
||||
|
||||
var0 = (var0 >> 5) << 5;
|
||||
var1 = i - var0 - 2;
|
||||
if (var1 < 28)
|
||||
gBG0TilemapBuffer[0x800 + i] = 0x9000;
|
||||
}
|
||||
|
||||
gMain.bgOffsets[1].xOffset = 8;
|
||||
gMain.bgOffsets[1].yOffset = 126;
|
||||
DmaCopy16(3, &gBG0TilemapBuffer[0x800], (void *)0x6001140, 0x280);
|
||||
for (i = 0; i < 0x800; i++)
|
||||
gBG0TilemapBuffer[i] = 0x1FF;
|
||||
|
||||
DmaCopy16(3, gSphealResultsScreenGfx, (void *)0x6015800, 0x800);
|
||||
}
|
||||
|
||||
void nullsub_18(void)
|
||||
{
|
||||
}
|
||||
}
|
||||
125
src/rom_1068C.c
125
src/rom_1068C.c
|
|
@ -1,125 +0,0 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
void PrintString(u16 glyph, u16 palette, int x, int y, int width, int height)
|
||||
{
|
||||
u16 i, j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
for (i = 0; i < width; i++)
|
||||
gBG0TilemapBuffer[y * 0x20 + x + j * 0x20 + i] = (glyph + j * 0x20 + i) | (palette << 12);
|
||||
}
|
||||
|
||||
void CopyString(int srcX, int srcY, int destX, int destY, int width, int height)
|
||||
{
|
||||
u16 i, j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
for (i = 0; i < width; i++)
|
||||
gBG0TilemapBuffer[destY * 0x20 + destX + j * 0x20 + i] = gBG0TilemapBuffer[srcY * 0x20 + srcX + j * 0x20 + i];
|
||||
}
|
||||
|
||||
void SetStringPalette(int x, int y, int width, int height, u16 palette)
|
||||
{
|
||||
u16 i, j;
|
||||
u16 index;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
index = y * 0x20 + x + j * 0x20 + i;
|
||||
gBG0TilemapBuffer[index] = (gBG0TilemapBuffer[index] & 0xFFF) | (palette << 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This requires volatile parameters to match. There is no reason, *ever*, to do this.
|
||||
void CopyBgTilesRect(void *volatile src, void *volatile dest, s16 width, s16 height)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
DmaCopy16(3, (u8 *)src + 0x400 * j, (u8 *)dest + 0x400 * j, width * 0x20);
|
||||
}
|
||||
}
|
||||
|
||||
// This function is unused. It appears to operates on a pixel canvas where each "tile" is represented by
|
||||
// 2 bytes.
|
||||
void CopyPixelCanvasRect(void *volatile src, void *volatile dest, s16 width, s16 height)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < height; j++)
|
||||
{
|
||||
DmaCopy16(3, (u8 *)src + 0x40 * j, (u8 *)dest + 0x40 * j, width * 2);
|
||||
}
|
||||
}
|
||||
|
||||
// This function is unused.
|
||||
void Unused_FadeInWithCustomPalettes(void *src1, void *src2, void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, src1, gPaletteFadeBuffers[1], BG_PLTT_SIZE);
|
||||
DmaCopy16(3, src2, gPaletteFadeBuffers[2], BG_PLTT_SIZE);
|
||||
DmaFill16(3, RGB_WHITE, gPaletteFadeBuffers, PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, PLTT_SIZE);
|
||||
|
||||
UnblankLCD();
|
||||
gMain.dispcntBackup = REG_DISPCNT;
|
||||
|
||||
for (i = 0; i <= 0x20; i += 0x10)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 0x20)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function is unused.
|
||||
void Unused_FadeOutToWhite(void (*func)(void))
|
||||
{
|
||||
u16 i;
|
||||
|
||||
DmaCopy16(3, (void *)PLTT, gPaletteFadeBuffers[0], PLTT_SIZE);
|
||||
DmaFill16(3, RGB_WHITE, gPaletteFadeBuffers[1], PLTT_SIZE);
|
||||
DmaCopy16(3, gPaletteFadeBuffers[0], gPaletteFadeBuffers[2], PLTT_SIZE);
|
||||
|
||||
for (i = 0; i <= 0x20; i += 0x10)
|
||||
{
|
||||
if (func != NULL)
|
||||
func();
|
||||
InterpolatePaletteStep(i);
|
||||
MainLoopIter();
|
||||
if (i == 0x20)
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[1], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPaletteFadeBuffers[2], (void *)PLTT, PLTT_SIZE);
|
||||
}
|
||||
}
|
||||
MainLoopIter();
|
||||
}
|
||||
|
||||
void ClearHighScoreNameEntry(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HIGH_SCORE_NAME_LENGTH; i++)
|
||||
gHighScoreNameEntry[i] = 0;
|
||||
}
|
||||
2163
src/rom_201B8.c
2163
src/rom_201B8.c
File diff suppressed because it is too large
Load Diff
|
|
@ -1,92 +0,0 @@
|
|||
#include "global.h"
|
||||
#include "functions.h"
|
||||
#include "main.h"
|
||||
#include "variables.h"
|
||||
|
||||
extern u32 gLinkStatusResult;
|
||||
extern s16 gLinkTimeoutCounter;
|
||||
extern u32 gLinkConnectionState;
|
||||
extern u8 gLinkPlayerCount;
|
||||
extern u8 gLinkNegotiationFlags;
|
||||
|
||||
s16 LoadSpriteSetsWithCpuCopy(const struct SpriteSet *const *spriteSets, u16 numSpriteSets, struct SpriteGroup *spriteGroups)
|
||||
{
|
||||
struct SpriteGroup *spriteGroup;
|
||||
struct OamDataSimple *simple;
|
||||
u16 *oamData;
|
||||
u16 i;
|
||||
u16 j;
|
||||
u16 pos;
|
||||
u16 numSpritesInGroup;
|
||||
|
||||
oamData = (u16 *)gOamBuffer;
|
||||
pos = 0;
|
||||
CpuCopy16(gEmptyOamData, oamData, sizeof(gOamBuffer));
|
||||
|
||||
for (i = 0; i < numSpriteSets; i++) {
|
||||
spriteGroup = &spriteGroups[i];
|
||||
if (!spriteGroup->available) {
|
||||
continue;
|
||||
}
|
||||
numSpritesInGroup = spriteSets[i]->count;
|
||||
CpuCopy16(spriteSets[i]->oamData, &gOamBuffer[pos], numSpritesInGroup * sizeof(struct OamData));
|
||||
for (j = 0; j < numSpritesInGroup; j++) {
|
||||
oamData = (u16 *)&gOamBuffer[pos];
|
||||
simple = &spriteGroup->oam[j];
|
||||
|
||||
simple->oamId = pos++;
|
||||
simple->xOffset = oamData[1] & 0x1FF;
|
||||
simple->yOffset = oamData[0] & 0xFF;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
void nullsub_16(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ResetSerialIO(void)
|
||||
{
|
||||
REG_RCNT = 0;
|
||||
REG_SIOCNT = 0;
|
||||
|
||||
REG_SIOMLT_SEND = 0;
|
||||
REG_SIOMULTI0 = 0;
|
||||
REG_SIOMLT_SEND = 0;
|
||||
REG_SIOMULTI0 = 0;
|
||||
|
||||
REG_SIOMULTI0 = 0;
|
||||
REG_SIOMULTI1 = 0;
|
||||
REG_SIOMULTI2 = 0;
|
||||
REG_SIOMULTI3 = 0;
|
||||
}
|
||||
|
||||
void SetupDefaultInterrupts(void)
|
||||
{
|
||||
REG_IME = 0;
|
||||
REG_IE = INTR_FLAG_GAMEPAK | INTR_FLAG_VBLANK;
|
||||
REG_DISPSTAT = DISPSTAT_VBLANK_INTR;
|
||||
REG_IME = 1;
|
||||
}
|
||||
|
||||
void ResetLinkState(void)
|
||||
{
|
||||
gLinkStatusResult = 0;
|
||||
gLinkTimeoutCounter = 0;
|
||||
gLinkConnectionState = 0;
|
||||
gLinkPlayerCount = 0;
|
||||
gLinkNegotiationFlags = 0;
|
||||
}
|
||||
|
||||
void ResetSerialAndInterrupts(void)
|
||||
{
|
||||
ResetSerialIO();
|
||||
REG_IME = 0;
|
||||
ResetMainCallback();
|
||||
ResetVBlankIntrFunc();
|
||||
REG_IE = INTR_FLAG_GAMEPAK | INTR_FLAG_VCOUNT | INTR_FLAG_VBLANK;
|
||||
REG_DISPSTAT = DISPSTAT_VCOUNT_INTR | DISPSTAT_VBLANK_INTR;
|
||||
REG_IME = 1;
|
||||
}
|
||||
|
||||
1561
src/rom_27E08.c
1561
src/rom_27E08.c
File diff suppressed because it is too large
Load Diff
1781
src/rom_2E67C.c
1781
src/rom_2E67C.c
File diff suppressed because it is too large
Load Diff
305
src/rom_31BE8.c
305
src/rom_31BE8.c
|
|
@ -1,305 +0,0 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "gba/gba.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/fields.h"
|
||||
#include "constants/bg_music.h"
|
||||
|
||||
extern const u8 gSplashEffectTileGfx[][0x100];
|
||||
extern const s16 gHoleAnimKeyframeData[][2];
|
||||
extern const s16 gSplashEffectFrameDurations[][2];
|
||||
extern const s16 gSplashEffectTileIndices[][2];
|
||||
extern const u8 gHoleIndicatorTileGfx[][0x440];
|
||||
extern struct Vector16 gSplashEffectPositions[];
|
||||
extern const u8 gRubyStageCyndaquil_Gfx[][0x280];
|
||||
extern const u8 gSapphireShopSignPalettes[][0x20];
|
||||
extern const u8 gSapphireShopSignTileGfx[][0x480];
|
||||
|
||||
void DrawSapphireShopSignSprite(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
group = &gMain.spriteGroups[69];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 16 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 115 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gCurrentPinballGame->shopSignPaletteIndex + gCurrentPinballGame->activePaletteIndex * 3;
|
||||
DmaCopy16(3, gSapphireShopSignPalettes[index], (void *)0x05000300, 0x20);
|
||||
DmaCopy16(3, gSapphireShopSignTileGfx[gCurrentPinballGame->shopSignFrame], (void *) 0x06014B20, 0x480);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSapphireHoleLetterSystem(void)
|
||||
{
|
||||
s16 i, j;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
switch (gCurrentPinballGame->holeLetterSystemState)
|
||||
{
|
||||
case 0:
|
||||
if (gCurrentPinballGame->holeLetterNewHit)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->holeLetterCount < 3)
|
||||
{
|
||||
gCurrentPinballGame->holeLetterCount++;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 20000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 920;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 0;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->holeLetterSystemState = 1;
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
m4aMPlayStop(&gMPlayInfo_BGM);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 200000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xDF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->holeLetterCount < 3)
|
||||
{
|
||||
gCurrentPinballGame->holeLetterCount++;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 20000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xDE);
|
||||
}
|
||||
}
|
||||
|
||||
index = gCurrentPinballGame->holeLetterCount;
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
gCurrentPinballGame->holeLetterNewHit = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (gCurrentPinballGame->holeAnimFrameCounter < 270)
|
||||
{
|
||||
index = (gCurrentPinballGame->holeAnimFrameCounter % 60) / 30 + 4;
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = 0;
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
gCurrentPinballGame->holeLetterSystemState = 2;
|
||||
gCurrentPinballGame->holeLetterCount = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->holeAnimFrameCounter == 60)
|
||||
{
|
||||
m4aSongNumStart(MUS_EGG_MODE_START);
|
||||
gCurrentPinballGame->catchArrowPaletteActive = 0;
|
||||
gCurrentPinballGame->eggAnimationPhase = 5;
|
||||
gCurrentPinballGame->eggAnimFrameIndex = 12;
|
||||
gCurrentPinballGame->eggFrameTimer = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->holeAnimFrameCounter++;
|
||||
break;
|
||||
case 3:
|
||||
if (gHoleAnimKeyframeData[gCurrentPinballGame->holeLetterCount][1] > gCurrentPinballGame->holeAnimFrameCounter)
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->holeLetterCount++;
|
||||
if (gCurrentPinballGame->holeLetterCount == 10)
|
||||
gCurrentPinballGame->holeLetterSystemState = 4;
|
||||
|
||||
if (gCurrentPinballGame->holeLetterCount == 6)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE0);
|
||||
|
||||
index = gHoleAnimKeyframeData[gCurrentPinballGame->holeLetterCount][0];
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->holeLetterCount < 6)
|
||||
{
|
||||
gCurrentPinballGame->walkMonYPos = 280;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->walkMonYPos += 6;
|
||||
if (gCurrentPinballGame->holeLetterSystemState == 4)
|
||||
gCurrentPinballGame->walkMonYPos = gCurrentPinballGame->walkMonYPos + 20;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (gCurrentPinballGame->holeCaptureReady && gCurrentPinballGame->holeLetterNewHit)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 160;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 0;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->holeLetterSystemState = 5;
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->holeLetterCount = 10;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE0);
|
||||
gCurrentPinballGame->eggAnimationPhase = 1;
|
||||
gCurrentPinballGame->portraitOffsetX = 2080;
|
||||
gCurrentPinballGame->portraitOffsetY = 960;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->holeLetterNewHit = 0;
|
||||
break;
|
||||
case 5:
|
||||
if (gHoleAnimKeyframeData[gCurrentPinballGame->holeLetterCount][1] > gCurrentPinballGame->holeAnimFrameCounter)
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->holeLetterCount++;
|
||||
if (gCurrentPinballGame->holeLetterCount == 15)
|
||||
gCurrentPinballGame->holeLetterSystemState = 6;
|
||||
|
||||
index = gHoleAnimKeyframeData[gCurrentPinballGame->holeLetterCount][0];
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->holeLetterCount == 14 && gCurrentPinballGame->holeAnimFrameCounter == 10)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE1);
|
||||
|
||||
if (gCurrentPinballGame->portraitOffsetY > 700)
|
||||
gCurrentPinballGame->portraitOffsetY -= 5;
|
||||
else
|
||||
gCurrentPinballGame->portraitOffsetY = 700;
|
||||
break;
|
||||
case 6:
|
||||
gCurrentPinballGame->holeLetterCount = 0;
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->holeLetterSystemState = 0;
|
||||
gCurrentPinballGame->holeCaptureReady = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
group = &gMain.spriteGroups[47 + i];
|
||||
if (group->available)
|
||||
{
|
||||
if (gSplashEffectFrameDurations[gCurrentPinballGame->splashEffectFrameIndex[i]][0] > gCurrentPinballGame->splashEffectFrameTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->splashEffectFrameTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->splashEffectFrameTimer[i] = 0;
|
||||
gCurrentPinballGame->splashEffectFrameIndex[i]++;
|
||||
if (gCurrentPinballGame->splashEffectFrameIndex[i] == 6)
|
||||
{
|
||||
group->available = 0;
|
||||
gCurrentPinballGame->splashEffectFrameIndex[i] = 5;
|
||||
}
|
||||
}
|
||||
|
||||
index = gSplashEffectTileIndices[gCurrentPinballGame->splashEffectFrameIndex[i]][0];
|
||||
DmaCopy16(3, &gSplashEffectTileGfx[index], (void *)0x060140a0 + i * 0x100, 0x100);
|
||||
group->baseX = gSplashEffectPositions[gCurrentPinballGame->splashEffectPositionIndex[i]].x - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gSplashEffectPositions[gCurrentPinballGame->splashEffectPositionIndex[i]].y - gCurrentPinballGame->cameraYOffset;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
oamSimple = &group->oam[j];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBoardEdgeBanner(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
group = &gMain.spriteGroups[81];
|
||||
else
|
||||
group = &gMain.spriteGroups[85];
|
||||
|
||||
if (group->available)
|
||||
{
|
||||
if (gCurrentPinballGame->cameraBaseX < 8)
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->cameraXOffset;
|
||||
group->baseX = -8 - group->baseX;
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseX = gCurrentPinballGame->cameraXOffset;
|
||||
group->baseX = 256 - group->baseX;
|
||||
}
|
||||
|
||||
group->baseY = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
struct OamDataSimple *oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY + i * 0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed when saving or loading from a main field
|
||||
* arg0
|
||||
* 0 when saving and loading normally
|
||||
* 2 when loading into the evo or mart menu
|
||||
*/
|
||||
void RestoreBoardObjPalettes(s16 arg0)
|
||||
{
|
||||
if (gCurrentPinballGame->paletteSwapActive == 1)
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0], (void*)OBJ_PLTT, 0x20);
|
||||
}
|
||||
|
||||
if (gMain.selectedField == FIELD_SAPPHIRE)
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0] + 0x40, (void*)OBJ_PLTT + 0x40, 0xC0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0] + 0x40, (void*)OBJ_PLTT + 0x40, 0xE0);
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBoardConfig.fieldLayout.objPaletteSets[arg0] + 0x140, (void *)OBJ_PLTT + 0x140, 0x20);
|
||||
|
||||
// related to Y position of camera on the field
|
||||
if (gCurrentPinballGame->cameraYViewport < 170)
|
||||
{
|
||||
DmaCopy16(3, gFieldPaletteVariants[gMain.selectedField][arg0 * 2], (void *)OBJ_PLTT + 0x160, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gFieldPaletteVariants[gMain.selectedField][arg0 * 2 + 1], (void *)OBJ_PLTT + 0x160, 0x20);
|
||||
}
|
||||
}
|
||||
124
src/rom_31CF8.c
124
src/rom_31CF8.c
|
|
@ -1,124 +0,0 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "constants/species.h"
|
||||
|
||||
/**
|
||||
* 0 if captured via ball
|
||||
* 1 if evolved
|
||||
*/
|
||||
void RegisterCaptureOrEvolution(s16 evolved)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
if (!evolved)
|
||||
{
|
||||
if (gMain.mainState != STATE_GAME_IDLE)
|
||||
SaveFile_SetPokedexFlags(gCurrentPinballGame->currentSpecies, SPECIES_CAUGHT);
|
||||
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionMethod != 0)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionTarget < SPECIES_NONE)
|
||||
{
|
||||
if (gCurrentPinballGame->evolvablePartySize < MAX_EVOLVABLE_PARTY_SIZE)
|
||||
{
|
||||
gCurrentPinballGame->evolvablePartySpecies[gCurrentPinballGame->evolvablePartySize] =
|
||||
gCurrentPinballGame->currentSpecies;
|
||||
|
||||
gCurrentPinballGame->evolvablePartySize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_EVOLVABLE_PARTY_SIZE; i++)
|
||||
gCurrentPinballGame->evolvablePartySpecies[i] = gCurrentPinballGame->evolvablePartySpecies[i + 1];
|
||||
|
||||
gCurrentPinballGame->evolvablePartySpecies[MAX_EVOLVABLE_PARTY_SIZE - 1] = gCurrentPinballGame->currentSpecies;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->evolvablePartySize--;
|
||||
|
||||
for (i = gCurrentPinballGame->evolvingPartyIndex; i < gCurrentPinballGame->evolvablePartySize; i++)
|
||||
gCurrentPinballGame->evolvablePartySpecies[i] = gCurrentPinballGame->evolvablePartySpecies[i + 1];
|
||||
|
||||
if (gCurrentPinballGame->currentSpecies == SPECIES_WURMPLE)
|
||||
{
|
||||
if ((gMain.systemFrameCount & 1) == 0)
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_SILCOON] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_SILCOON;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_CASCOON;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_CASCOON] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_CASCOON;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_SILCOON;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_GLOOM)
|
||||
{
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_VILEPLUME;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_BELLOSSOM;
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_CLAMPERL)
|
||||
{
|
||||
if ((gMain.systemFrameCount & 1) == 0)
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_HUNTAIL] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_HUNTAIL;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_GOREBYSS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[SPECIES_GOREBYSS] < SPECIES_CAUGHT)
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_GOREBYSS;
|
||||
else
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_HUNTAIL;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->currentSpecies == SPECIES_NINCADA)
|
||||
{
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_SHEDINJA;
|
||||
if (gMain.mainState != STATE_GAME_IDLE)
|
||||
SaveFile_SetPokedexFlags(SPECIES_SHEDINJA, SPECIES_CAUGHT);
|
||||
|
||||
gCurrentPinballGame->currentSpecies = SPECIES_NINJASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->currentSpecies =
|
||||
gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionTarget;
|
||||
}
|
||||
|
||||
if (gMain.mainState != STATE_GAME_IDLE)
|
||||
SaveFile_SetPokedexFlags(gCurrentPinballGame->currentSpecies, SPECIES_CAUGHT);
|
||||
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionMethod != 0)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].evolutionTarget < SPECIES_NONE)
|
||||
{
|
||||
if (gCurrentPinballGame->evolvablePartySize < MAX_EVOLVABLE_PARTY_SIZE)
|
||||
{
|
||||
gCurrentPinballGame->evolvablePartySpecies[gCurrentPinballGame->evolvablePartySize] =
|
||||
gCurrentPinballGame->currentSpecies;
|
||||
gCurrentPinballGame->evolvablePartySize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_EVOLVABLE_PARTY_SIZE; i++)
|
||||
gCurrentPinballGame->evolvablePartySpecies[i] = gCurrentPinballGame->evolvablePartySpecies[i + 1];
|
||||
|
||||
gCurrentPinballGame->evolvablePartySpecies[MAX_EVOLVABLE_PARTY_SIZE - 1] = gCurrentPinballGame->currentSpecies;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
|
||||
u16 IsInVblank(void)
|
||||
{
|
||||
if ((REG_IME & 1) // Interrupts enabled
|
||||
&& (REG_DISPSTAT & DISPSTAT_VBLANK_INTR) // In VBLANK
|
||||
&& (REG_IE & INTR_FLAG_VBLANK) // VBlank interrupt enabled
|
||||
&& !(REG_DISPCNT & DISPCNT_FORCED_BLANK)) // Ignore VBlank interrupts during forced blank
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SetMainCallback(void (*func)(void))
|
||||
{
|
||||
gMainCallbackShadow = func;
|
||||
if (!IsInVblank())
|
||||
gMainCallback = func;
|
||||
}
|
||||
|
||||
void ResetMainCallback(void)
|
||||
{
|
||||
gMainCallback = DefaultMainCallback;
|
||||
gMainCallbackShadow = DefaultMainCallback;
|
||||
}
|
||||
|
||||
void SetVBlankIntrFunc(void (*func)(void))
|
||||
{
|
||||
gVBlankIntrFuncShadow = func;
|
||||
if (!IsInVblank())
|
||||
*gVBlankIntrFuncPtr = func;
|
||||
}
|
||||
|
||||
void ResetVBlankIntrFunc(void)
|
||||
{
|
||||
*gVBlankIntrFuncPtr = VBlankIntr;
|
||||
gVBlankIntrFuncShadow = VBlankIntr;
|
||||
}
|
||||
|
||||
void SetVCountIntrFunc(void (*func)(void))
|
||||
{
|
||||
gVCountIntrFuncShadow = func;
|
||||
if (!IsInVblank())
|
||||
*gVCountIntrFuncPtr = func;
|
||||
}
|
||||
|
||||
void ResetVCountIntrFunc(void)
|
||||
{
|
||||
*gVCountIntrFuncPtr = VCountIntr;
|
||||
gVCountIntrFuncShadow = VCountIntr;
|
||||
}
|
||||
|
||||
|
|
@ -16,7 +16,11 @@ extern const u8 *gRubyTrapIndicatorTilePointers[][2];
|
|||
extern const u8 *gRubyProgressDigitTilePointers[][2];
|
||||
extern const u8 *gShopItemTilePointers[][3];
|
||||
extern const s16 gRubySlingshotAnimIndices[];
|
||||
extern const u8 *gRubySlingshotTilePointers[][3][5];
|
||||
extern const u8 *gRubySlingshotTilePointers[2][3][5];
|
||||
extern const u8 *gRubyCoinRewardTilePtrs[][5][3];
|
||||
extern const s16 gCoinRewardLevelTimerThresholds[];
|
||||
extern const u8 *gRubyEvoArrowTilePtrs[][5][3];
|
||||
extern const u8 *gRubyCatchArrowTilePtrs[][5][3];
|
||||
|
||||
extern struct SongHeader se_ball_upgrade;
|
||||
|
||||
|
|
@ -28,8 +32,8 @@ void UpdateRubyBoardAnimations(void)
|
|||
DrawRubyProgressDigits();
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 232)
|
||||
{
|
||||
AnimateRubyCatchArrow();
|
||||
AnimateRubyEvoArrow();
|
||||
AnimateRubyCatchArrowPalette();
|
||||
AnimateRubyEvoArrowPalette();
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 81 && gCurrentPinballGame->hudSpriteBaseY < 248)
|
||||
|
|
@ -44,12 +48,12 @@ void UpdateRubyBoardAnimations(void)
|
|||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 104)
|
||||
{
|
||||
DrawEvoArrowProgress();
|
||||
DrawCatchArrowProgress();
|
||||
DrawRubyEvoArrowProgress();
|
||||
DrawRubyCatchArrowProgress();
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 256)
|
||||
DrawCoinRewardMeter();
|
||||
DrawRubyCoinRewardMeter();
|
||||
|
||||
UpdateCoinRewardTimer();
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 110)
|
||||
|
|
@ -59,7 +63,7 @@ void UpdateRubyBoardAnimations(void)
|
|||
{
|
||||
AnimateRubyCatchLightBlink();
|
||||
AnimateRubyHoleIndicators();
|
||||
AnimateRubySlingshotTimer();
|
||||
AnimateRubySlingshotHit();
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 202)
|
||||
|
|
@ -69,7 +73,7 @@ void UpdateRubyBoardAnimations(void)
|
|||
gCurrentPinballGame->saverTimeRemaining--;
|
||||
}
|
||||
|
||||
void AnimateRubySlingshotTimer(void)
|
||||
void AnimateRubySlingshotHit(void)
|
||||
{
|
||||
s16 index;
|
||||
const u8 **src;
|
||||
|
|
@ -225,7 +229,7 @@ void DrawRubyModeTimerDisplay(void)
|
|||
}
|
||||
}
|
||||
|
||||
void AnimateRubyCatchArrow(void)
|
||||
void AnimateRubyCatchArrowPalette(void)
|
||||
{
|
||||
s16 index;
|
||||
const u8 **src;
|
||||
|
|
@ -256,7 +260,7 @@ void AnimateRubyCatchArrow(void)
|
|||
}
|
||||
}
|
||||
|
||||
void AnimateRubyEvoArrow(void)
|
||||
void AnimateRubyEvoArrowPalette(void)
|
||||
{
|
||||
s16 index;
|
||||
const u8 **src;
|
||||
|
|
@ -407,3 +411,230 @@ void DrawRubyBallPowerUpLights(void)
|
|||
DmaCopy16(3, *src, *dest, 0x40);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCoinRewardTimer(void)
|
||||
{
|
||||
if (gCurrentPinballGame->coinRewardLevel > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->coinRewardLevelTimer < gCoinRewardLevelTimerThresholds[gCurrentPinballGame->coinRewardLevel - 1])
|
||||
{
|
||||
gCurrentPinballGame->coinRewardLevelTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->coinRewardLevelTimer = 0;
|
||||
gCurrentPinballGame->coinRewardLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRubyCoinRewardMeter(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
const u8 **dest;
|
||||
|
||||
if (gCurrentPinballGame->coinRewardLevel == 0)
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase;
|
||||
sp0[2] = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->coinRewardLevel == 1)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase + 1;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->coinRewardLevel == 2)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = 3;
|
||||
}
|
||||
|
||||
src = gRubyCoinRewardTilePtrs[0][sp0[0]];
|
||||
dest = gRubyCoinRewardTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 42 && gCurrentPinballGame->hudSpriteBaseY < 208)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 50 && gCurrentPinballGame->hudSpriteBaseY < 216)
|
||||
{
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
}
|
||||
|
||||
src = gRubyCoinRewardTilePtrs[1][sp0[1]];
|
||||
dest = gRubyCoinRewardTilePtrs[1][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 58 && gCurrentPinballGame->hudSpriteBaseY < 224)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 66 && gCurrentPinballGame->hudSpriteBaseY < 232)
|
||||
{
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
}
|
||||
|
||||
src = gRubyCoinRewardTilePtrs[2][sp0[2]];
|
||||
dest = gRubyCoinRewardTilePtrs[2][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 74 && gCurrentPinballGame->hudSpriteBaseY < 240)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 82 && gCurrentPinballGame->hudSpriteBaseY < 248)
|
||||
{
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 90)
|
||||
{
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRubyEvoArrowProgress(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
const u8 **dest;
|
||||
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->evoArrowProgress == 0)
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
sp0[1] = 0;
|
||||
sp0[2] = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->evoArrowProgress == 1)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase + 1;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->evoArrowProgress == 2)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->prevTravelArrowTiles[0];
|
||||
sp0[1] = gCurrentPinballGame->prevTravelArrowTiles[1];
|
||||
sp0[2] = gCurrentPinballGame->prevTravelArrowTiles[2];
|
||||
}
|
||||
|
||||
src = gRubyEvoArrowTilePtrs[0][sp0[0]];
|
||||
dest = gRubyEvoArrowTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 264)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 120)
|
||||
{
|
||||
src = gRubyEvoArrowTilePtrs[1][sp0[1]];
|
||||
dest = gRubyEvoArrowTilePtrs[1][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 136)
|
||||
{
|
||||
src = gRubyEvoArrowTilePtrs[2][sp0[2]];
|
||||
dest = gRubyEvoArrowTilePtrs[2][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRubyCatchArrowProgress(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
const u8 **dest;
|
||||
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->catchArrowProgress == 0)
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
sp0[1] = 0;
|
||||
sp0[2] = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->catchArrowProgress == 1)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase + 1;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->catchArrowProgress == 2)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = (s16) gCurrentPinballGame->hudBlinkPhase + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->travelArrowTiles[0];
|
||||
sp0[1] = gCurrentPinballGame->travelArrowTiles[1];
|
||||
sp0[2] = gCurrentPinballGame->travelArrowTiles[2];
|
||||
}
|
||||
|
||||
src = gRubyCatchArrowTilePtrs[0][sp0[0]];
|
||||
dest = gRubyCatchArrowTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 264)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 120)
|
||||
{
|
||||
src = gRubyCatchArrowTilePtrs[1][sp0[1]];
|
||||
dest = gRubyCatchArrowTilePtrs[1][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
DmaCopy16(3, src[1], dest[1], 0x40);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 136)
|
||||
{
|
||||
src = gRubyCatchArrowTilePtrs[2][sp0[2]];
|
||||
dest = gRubyCatchArrowTilePtrs[2][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
}
|
||||
403
src/ruby_catch_holes.c
Normal file
403
src/ruby_catch_holes.c
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
#include "global.h"
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/ruby_states.h"
|
||||
#include "functions_ruby.h"
|
||||
|
||||
void InitSharpedoCatchMode(void);
|
||||
void AnimateSharpedoCatchSequence(void);
|
||||
void InitRubyEvolutionShopMode(void);
|
||||
void AnimateRubyEvolutionShopSequence(void);
|
||||
void AnimateRubyEggHatchSequence(void);
|
||||
void AnimateTotodileEggDelivery(void);
|
||||
void InitAerodactylEggDelivery(void);
|
||||
void AnimateAerodactylEggDelivery(void);
|
||||
|
||||
void DispatchRubyCatchModeInit(void)
|
||||
{
|
||||
if (gMain.modeChangeFlags != MODE_CHANGE_NONE)
|
||||
return;
|
||||
|
||||
switch (gCurrentPinballGame->ballCatchState)
|
||||
{
|
||||
case TRAP_CATCH_HOLE:
|
||||
InitSharpedoCatchMode();
|
||||
break;
|
||||
case TRAP_EGG_HOLE:
|
||||
InitRubyEggHatchMode();
|
||||
break;
|
||||
case TRAP_EVO_SHOP_HOLE:
|
||||
InitRubyEvolutionShopMode();
|
||||
break;
|
||||
case TRAP_CENTER_HOLE:
|
||||
InitCenterTrapMode();
|
||||
break;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->collisionCooldownTimer = 60;
|
||||
}
|
||||
|
||||
void UpdateRubyCatchModeAnimation(void)
|
||||
{
|
||||
if (gCurrentPinballGame->collisionCooldownTimer > 0)
|
||||
gCurrentPinballGame->collisionCooldownTimer--;
|
||||
|
||||
switch (gCurrentPinballGame->ballCatchState)
|
||||
{
|
||||
case TRAP_CATCH_HOLE:
|
||||
AnimateSharpedoCatchSequence(); // Catch hole
|
||||
break;
|
||||
case TRAP_EGG_HOLE:
|
||||
AnimateRubyEggHatchSequence(); //Hatch hole
|
||||
break;
|
||||
case TRAP_EVO_SHOP_HOLE:
|
||||
AnimateRubyEvolutionShopSequence(); //Mart / Evo hole
|
||||
break;
|
||||
case TRAP_CENTER_HOLE:
|
||||
AnimateCenterTrapSequence(); //Center Hole
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InitSharpedoCatchMode(void)
|
||||
{
|
||||
if (gCurrentPinballGame->catchArrowProgress > 1)
|
||||
{
|
||||
RequestBoardStateTransition(4);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->cameraScrollOffset = 0;
|
||||
gCurrentPinballGame->cameraScrollEnabled = 0;
|
||||
gCurrentPinballGame->cameraScrollTarget = 0;
|
||||
gCurrentPinballGame->modeAnimTimer = 113;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xCE);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 50000;
|
||||
|
||||
PlayRumble(8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ruby board Sharpedo; during the initation of the catch mode
|
||||
* Echoes UpdateSapphireWailmerCatchSequence, which is the equivalent 'catch hole' on the sapphire board.
|
||||
*
|
||||
* Note: this *does not* affect the start of the catch mode itself.
|
||||
* When this function is nulled out at UpdateRubyCatchModeAnimation, the banner *doesn't* show, and
|
||||
* the ball bounces off the sharpedo. However, the grid still shows a picked mon,
|
||||
* and the mode otherwise works mostly normally, with the exception of affecting
|
||||
* the 'tilt' behavior, and the collision with the cyndaquil pushback.
|
||||
*/
|
||||
void AnimateSharpedoCatchSequence(void)
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer) //Countdown timer; ball grabbed/held while banner shows
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
if (gCurrentPinballGame->modeAnimTimer > 100)
|
||||
{
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 108)
|
||||
{
|
||||
gCurrentPinballGame->boardEntityActive = 1;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 110)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 195;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 222;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 196;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 221;
|
||||
}
|
||||
//Presumed controling either the message board 'state'/'tile'
|
||||
// or the sharpedo animation 'state'/tile.
|
||||
gCurrentPinballGame->catchHoleAnimFrame =6;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 104)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 197;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 219;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 8;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 20)
|
||||
{
|
||||
if (gCurrentPinballGame->modeAnimTimer > 77)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 9;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer < 80)
|
||||
{
|
||||
if (gCurrentPinballGame->catchHolePauseTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->catchHolePauseTimer--;
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 72)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 10;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 67)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 11;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 44)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 12;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 38)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 13;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 28)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 14;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 23)
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 15;
|
||||
}
|
||||
else {
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 16;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 18)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 193;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 226;
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 17;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 16)
|
||||
{
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->cameraScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraScrollEnabled = 1;
|
||||
gCurrentPinballGame->boardEntityActive = 0;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ball->velocity.x = 0xFF56;
|
||||
gCurrentPinballGame->ball->velocity.y = 220;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 190;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 232;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 18;
|
||||
if (gCurrentPinballGame->modeAnimTimer == 18)
|
||||
{
|
||||
m4aSongNumStart(194);
|
||||
PlayRumble(7);
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 12)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 19;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 8)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 20;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer > 4)
|
||||
{
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 21;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 22;
|
||||
}
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
|
||||
gCurrentPinballGame->ball->prevPositionQ1 = gCurrentPinballGame->ball->positionQ1;
|
||||
gCurrentPinballGame->ball->positionQ8.x= gCurrentPinballGame->ball->positionQ0.x << 8;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y << 8;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->collisionCooldownTimer = 30;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ballCatchState = NOT_TRAPPED;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
gCurrentPinballGame->catchHoleAnimFrame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void InitRubyEggHatchMode(void)
|
||||
{
|
||||
gCurrentPinballGame->scoreAddedInFrame = 100000;
|
||||
if (gCurrentPinballGame->eggCaveState == 3)
|
||||
{
|
||||
gCurrentPinballGame->eggCaveState = 4;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
PlayRumble(7);
|
||||
gCurrentPinballGame->modeAnimTimer = 500;
|
||||
}
|
||||
else if (gCurrentPinballGame->rubyEggDeliveryState !=0)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 300;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 120;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
}
|
||||
|
||||
void AnimateRubyEggHatchSequence(void)
|
||||
{
|
||||
u16 modeAnimTimer = gCurrentPinballGame->modeAnimTimer;
|
||||
|
||||
if (modeAnimTimer != 0)
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0x58;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0x94;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
|
||||
if (gCurrentPinballGame->rubyEggDeliveryState != 1)
|
||||
return;
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0xC8)
|
||||
return;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer == 0xC8)
|
||||
{
|
||||
if (gCurrentPinballGame->activePortraitType != 0)
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->scoreHi != 0 && gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_LOTAD)
|
||||
InitTotodileEggDelivery();
|
||||
else
|
||||
InitAerodactylEggDelivery();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->scoreHi != 0 && gCurrentPinballGame->rubyPondState == RUBY_POND_STATE_LOTAD)
|
||||
AnimateTotodileEggDelivery();
|
||||
else
|
||||
AnimateAerodactylEggDelivery();
|
||||
}
|
||||
if (gCurrentPinballGame->modeAnimTimer <= 9)
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->ballCatchState = NOT_TRAPPED;
|
||||
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0x58;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0xA2;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
|
||||
if (gCurrentPinballGame->rubyEggDeliveryState == 2)
|
||||
{
|
||||
gCurrentPinballGame->eggCaveState = 3;
|
||||
gCurrentPinballGame->eggCaveLiftTimer = 0x30;
|
||||
gCurrentPinballGame->eggCaveExitDelayTimer = 0x1E;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->collisionCooldownTimer = 0x3C;
|
||||
gCurrentPinballGame->ball->velocity.x = 0x14;
|
||||
gCurrentPinballGame->ball->velocity.y = 0xC8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitRubyEvolutionShopMode(void)
|
||||
{
|
||||
gCurrentPinballGame->shopAnimSlideTimer = 0;
|
||||
gCurrentPinballGame->shopUISlideOffset = 0;
|
||||
gCurrentPinballGame->modeAnimTimer = 0xB4;
|
||||
gCurrentPinballGame->shopEntryTimer = 0xB4;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 500000;
|
||||
gMain.blendControl = 0xCE;
|
||||
gMain.blendBrightness = 0;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
}
|
||||
|
||||
void AnimateRubyEvolutionShopSequence(void)
|
||||
{
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0x18)
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0xDC;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0x62;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ0.x * 256;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y * 256;
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0x9B)
|
||||
gCurrentPinballGame->shopDoorTargetFrame = (gCurrentPinballGame->modeAnimTimer - 0x9C) / 8;
|
||||
if (gCurrentPinballGame->modeAnimTimer <= 0x31)
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
|
||||
UpdateShopEntryAnimation(gCurrentPinballGame->evolutionShopActive);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer > 0)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer--;
|
||||
gCurrentPinballGame->shopDoorTargetFrame = (0x18 - gCurrentPinballGame->modeAnimTimer) / 8;
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->collisionCooldownTimer = 0x3C;
|
||||
|
||||
gCurrentPinballGame->ball->velocity.x = 0x60;
|
||||
gCurrentPinballGame->ball->velocity.y = 0xC0;
|
||||
gCurrentPinballGame->ball->positionQ0.x = 0xDF;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 0x63;
|
||||
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ballCatchState = NOT_TRAPPED;
|
||||
gCurrentPinballGame->shopDoorTargetFrame = 0x13;
|
||||
|
||||
m4aSongNumStart(SE_UNKNOWN_0xC3);
|
||||
|
||||
if (gCurrentPinballGame->evoArrowProgress > 2 && gCurrentPinballGame->evolvablePartySize > 0)
|
||||
{
|
||||
RequestBoardStateTransition(6);
|
||||
}
|
||||
}
|
||||
491
src/ruby_trigger_targets.c
Normal file
491
src/ruby_trigger_targets.c
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/ruby_states.h"
|
||||
|
||||
extern const u8 gSideBumperGfx[][0x100];
|
||||
extern const s16 gSideBumperGfxFrameIndices[][2];
|
||||
extern const u16 gSideBumperAnimDurations[][2];
|
||||
|
||||
extern const s16 gGulpinAnimData[][5];
|
||||
extern const u16 gGulpinOamData[146][18];
|
||||
extern const u8 gRubyStageGulpin_Gfx[][0x180];
|
||||
|
||||
extern const s16 gChikoritaFlashFrameIndices[];
|
||||
extern const u8 gChikoritaExplosionTiles[][0x100];
|
||||
extern const u8 gChikoritaProjectileTiles[][0x80];
|
||||
extern const u8 gRubyFlashingDecorationTiles[][0x300];
|
||||
|
||||
//ruby
|
||||
void UpdateChikoritaAttackAnimation(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
s16 var0;
|
||||
|
||||
index = 0;
|
||||
group = &gMain.spriteGroups[14];
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer < 60)
|
||||
{
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer >= 27 && gCurrentPinballGame->chikoritaProjectileTimer < 47)
|
||||
{
|
||||
index = (gCurrentPinballGame->chikoritaProjectileTimer - 27) / 5;
|
||||
DmaCopy16(3, gChikoritaExplosionTiles[index], (void *)0x06014280, 0x100);
|
||||
group->baseX = 176 - gCurrentPinballGame->cameraXOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
group->available = 0;
|
||||
group->baseX = 176 - gCurrentPinballGame->cameraXOffset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer >= 100 && gCurrentPinballGame->chikoritaProjectileTimer < 120)
|
||||
{
|
||||
index = (gCurrentPinballGame->chikoritaProjectileTimer - 100) / 5;
|
||||
DmaCopy16(3, gChikoritaExplosionTiles[index], (void *)0x06014280, 0x100);
|
||||
group->baseX = 32 - gCurrentPinballGame->cameraXOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
group->available = 0;
|
||||
group->baseX = 32 - gCurrentPinballGame->cameraXOffset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (group->available)
|
||||
{
|
||||
group->baseY = 296 - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY > 180)
|
||||
group->baseY = 180;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
group = &gMain.spriteGroups[13];
|
||||
if (group->available)
|
||||
{
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer < 120)
|
||||
{
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer % 8 == 0)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xC6);
|
||||
|
||||
index = (gCurrentPinballGame->chikoritaProjectileTimer % 16) / 4;
|
||||
DmaCopy16(3, gChikoritaProjectileTiles[index], (void *)0x06014200, 0x80);
|
||||
var0 = (gCurrentPinballGame->chikoritaProjectileTimer << 0x10) / 90;
|
||||
gCurrentPinballGame->chikoritaProjectileVelX -= 2;
|
||||
gCurrentPinballGame->chikoritaProjectileX += gCurrentPinballGame->chikoritaProjectileVelX;
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer < 30)
|
||||
gCurrentPinballGame->chikoritaProjectileY = gCurrentPinballGame->chikoritaProjectileTimer + (Sin(var0) * 24) / 20000;
|
||||
else
|
||||
gCurrentPinballGame->chikoritaProjectileY = 30 + (Sin(var0) * 24) / 20000;
|
||||
|
||||
gCurrentPinballGame->chikoritaProjectileTimer++;
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer == 27)
|
||||
{
|
||||
gMain.spriteGroups[14].available = 1;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xC7);
|
||||
if (gCurrentPinballGame->sideBumperBounceCount[1] > 0)
|
||||
{
|
||||
gCurrentPinballGame->sideBumperBounceCount[1]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sideBumperBounceCount[1] = 2;
|
||||
gCurrentPinballGame->sideBumperAnimTimer[1] = 190;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->chikoritaProjectileTimer == 100)
|
||||
{
|
||||
gMain.spriteGroups[14].available = 1;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xC7);
|
||||
if (gCurrentPinballGame->sideBumperBounceCount[0] > 0)
|
||||
{
|
||||
gCurrentPinballGame->sideBumperBounceCount[0]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sideBumperBounceCount[0] = 2;
|
||||
gCurrentPinballGame->sideBumperAnimTimer[0] = 190;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->chikoritaProjectileTimer = 0;
|
||||
gCurrentPinballGame->chikoritaProjectileX = 0;
|
||||
gCurrentPinballGame->chikoritaProjectileY = 190;
|
||||
gCurrentPinballGame->chikoritaProjectileVelX = 100;
|
||||
gCurrentPinballGame->chikoritaProjectileUnused = 0;
|
||||
group->available = 0;
|
||||
}
|
||||
|
||||
group->baseX = (gCurrentPinballGame->chikoritaProjectileX / 20) + 71u - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->chikoritaProjectileY + 248u - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY > 190)
|
||||
group->baseY = 190;
|
||||
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateChikoritaSprite(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
group = &gMain.spriteGroups[53];
|
||||
if (gCurrentPinballGame->chikoritaFlashActive)
|
||||
{
|
||||
index = gChikoritaFlashFrameIndices[gCurrentPinballGame->chikoritaFlashTimer / 5];
|
||||
if (gCurrentPinballGame->chikoritaFlashTimer == 40)
|
||||
{
|
||||
gCurrentPinballGame->chikoritaProjectileTimer = 0;
|
||||
gCurrentPinballGame->chikoritaProjectileX = 0;
|
||||
gCurrentPinballGame->chikoritaProjectileY = 0;
|
||||
gCurrentPinballGame->chikoritaProjectileVelX = 100;
|
||||
gCurrentPinballGame->chikoritaProjectileUnused = 0;
|
||||
gMain.spriteGroups[13].available = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->chikoritaFlashTimer < 54)
|
||||
gCurrentPinballGame->chikoritaFlashTimer++;
|
||||
else
|
||||
gCurrentPinballGame->chikoritaFlashActive = 0;
|
||||
|
||||
DmaCopy16(3, gRubyFlashingDecorationTiles[index], (void *)0x06012720, 0x300);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = (gMain.systemFrameCount % 50) / 25;
|
||||
if (gCurrentPinballGame->randomSpriteVariantSeed == 1)
|
||||
{
|
||||
DmaCopy16(3, gRubyFlashingDecorationTiles[index], (void *)0x06012720, 0x300);
|
||||
}
|
||||
}
|
||||
|
||||
group->baseX = 55 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 221 - gCurrentPinballGame->cameraYOffset;
|
||||
i = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateGulpinBossState(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const s16 *var0;
|
||||
s16 index;
|
||||
|
||||
var0 = gGulpinAnimData[gCurrentPinballGame->gulpinAnimFrameIndex];
|
||||
group = &gMain.spriteGroups[57];
|
||||
group->baseX = 9 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 288 - gCurrentPinballGame->cameraYOffset;
|
||||
if (gCurrentPinballGame->gulpinCurrentLevel > gCurrentPinballGame->seedotCount)
|
||||
{
|
||||
if (gCurrentPinballGame->seedotExitSequenceActive)
|
||||
{
|
||||
if (gCurrentPinballGame->seedotExitSequenceTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 59;
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->seedotExitSequenceTimer++;
|
||||
}
|
||||
|
||||
if (var0[1] > gCurrentPinballGame->gulpinAnimFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 1;
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex++;
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 84)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 0;
|
||||
gCurrentPinballGame->seedotExitSequenceActive = 0;
|
||||
gCurrentPinballGame->seedotExitSequenceTimer = 0;
|
||||
gCurrentPinballGame->gulpinCurrentLevel = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 60 || gCurrentPinballGame->gulpinAnimFrameIndex == 69 || gCurrentPinballGame->gulpinAnimFrameIndex == 78)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xD2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->gulpinCurrentLevel < gCurrentPinballGame->seedotCount)
|
||||
{
|
||||
if (var0[1] <= gCurrentPinballGame->gulpinAnimFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 1;
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex++;
|
||||
if (gCurrentPinballGame->seedotCount == 1)
|
||||
{
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 9)
|
||||
{
|
||||
gCurrentPinballGame->gulpinCurrentLevel = 1;
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 84;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 6)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xD2);
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount == 2)
|
||||
{
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 23)
|
||||
{
|
||||
gCurrentPinballGame->gulpinCurrentLevel = 2;
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 95;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 20)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xD2);
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount == 3)
|
||||
{
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 35)
|
||||
{
|
||||
gCurrentPinballGame->gulpinCurrentLevel = 3;
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 35;
|
||||
RequestBoardStateTransition(7);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 32)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xD2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer++;
|
||||
}
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount)
|
||||
{
|
||||
if (var0[1] > gCurrentPinballGame->gulpinAnimFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 1;
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex++;
|
||||
if (gCurrentPinballGame->seedotCount == 1)
|
||||
{
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 95)
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 84;
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount == 2)
|
||||
{
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 109)
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 95;
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount == 3)
|
||||
{
|
||||
if (gCurrentPinballGame->gulpinAnimFrameIndex == 60)
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 35;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index = var0[0];
|
||||
DmaCopy16(3, gRubyStageGulpin_Gfx[var0[2]], (void *)0x06013B80, 0x180);
|
||||
DmaCopy16(3, gRubyStageGulpin_Gfx[var0[3]], (void *)0x06013A00, 0x180);
|
||||
DmaCopy16(3, gRubyStageGulpin_Gfx[var0[4]], (void *)0x06013880, 0x180);
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gGulpinOamData[index][i * 3 + 0];
|
||||
*dst++ = gGulpinOamData[index][i * 3 + 1];
|
||||
*dst++ = gGulpinOamData[index][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRubySideBumperAnimation(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (gCurrentPinballGame->sideBumperBounceCount[i] > 0)
|
||||
{
|
||||
if (gSideBumperAnimDurations[gCurrentPinballGame->sideBumperAnimPhase[i]][0] > gCurrentPinballGame->sideBumperAnimTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->sideBumperAnimTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->sideBumperAnimTimer[i] = 0;
|
||||
gCurrentPinballGame->sideBumperAnimPhase[i]++;
|
||||
if (gCurrentPinballGame->sideBumperAnimPhase[i] > 11)
|
||||
{
|
||||
gCurrentPinballGame->sideBumperAnimPhase[i] = 0;
|
||||
gCurrentPinballGame->sideBumperBounceCount[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->sideBumperAnimPhase[i] == 1)
|
||||
gCurrentPinballGame->sideBumperShakeOffset[i] = gCurrentPinballGame->sideBumperAnimTimer[i] / 2;
|
||||
|
||||
if (gCurrentPinballGame->sideBumperAnimPhase[i] == 11)
|
||||
gCurrentPinballGame->sideBumperShakeOffset[i] = 14 - gCurrentPinballGame->sideBumperAnimTimer[i] / 2;
|
||||
|
||||
if (gCurrentPinballGame->sideBumperShakeOffset[i] < 3)
|
||||
gCurrentPinballGame->sideBumperShakeOffset[i] = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->sideBumperHitFlag)
|
||||
{
|
||||
if (gCurrentPinballGame->sideBumperHitFlag == 1)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState != 7)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 3) {
|
||||
if (gCurrentPinballGame->seedotCount < 3)
|
||||
{
|
||||
gCurrentPinballGame->seedotCount++;
|
||||
if (gCurrentPinballGame->seedotCount == 1)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 0;
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount == 2)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 12;
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount == 3)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 24;
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->seedotModeStartDelay = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->seedotCount < 2)
|
||||
{
|
||||
gCurrentPinballGame->seedotCount++;
|
||||
if (gCurrentPinballGame->seedotCount == 1)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 0;
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->seedotCount == 2)
|
||||
{
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 12;
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->rampGateState == 0)
|
||||
gCurrentPinballGame->rampGateState = 1;
|
||||
else
|
||||
gCurrentPinballGame->rampGateState = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->sideBumperBounceCount[0] = 0;
|
||||
gCurrentPinballGame->sideBumperBounceCount[1] = 0;
|
||||
gCurrentPinballGame->sideBumperHitFlag = 0;
|
||||
PlayRumble(7);
|
||||
m4aSongNumStart(SE_UNKNOWN_0xB7);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 3000;
|
||||
gCurrentPinballGame->sideBumperAnimPhase[0] = 0;
|
||||
gCurrentPinballGame->sideBumperAnimPhase[1] = 0;
|
||||
gCurrentPinballGame->sideBumperAnimTimer[0] = 0;
|
||||
gCurrentPinballGame->sideBumperAnimTimer[1] = 0;
|
||||
gCurrentPinballGame->sideBumperShakeOffset[0] = 3;
|
||||
gCurrentPinballGame->sideBumperShakeOffset[1] = 3;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRubySideBumperSprites(void)
|
||||
{
|
||||
s16 i, j;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
index = gSideBumperGfxFrameIndices[gCurrentPinballGame->sideBumperAnimPhase[i]][0];
|
||||
DmaCopy16(3, gSideBumperGfx[index], (void *)0x06012A20 + i * 0x100, 0x100);
|
||||
group = &gMain.spriteGroups[59 + i];
|
||||
if (group->available)
|
||||
{
|
||||
int var0 = i * 120 - (gCurrentPinballGame->cameraXOffset - 48);
|
||||
group->baseX = var0 + ((1 - (i * 2)) * (gCurrentPinballGame->sideBumperShakeOffset[i] - 14));
|
||||
group->baseY = 301 - gCurrentPinballGame->cameraYOffset;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
oamSimple = &group->oam[j];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->seedotModeStartDelay)
|
||||
{
|
||||
gCurrentPinballGame->seedotModeStartDelay--;
|
||||
if (gCurrentPinballGame->seedotModeStartDelay == 0)
|
||||
{
|
||||
if (gCurrentPinballGame->activePortraitType)
|
||||
gCurrentPinballGame->seedotModeStartDelay = 1;
|
||||
else
|
||||
gCurrentPinballGame->activePortraitType = 4;
|
||||
|
||||
if (gCurrentPinballGame->seedotModeStartDelay == 0)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 70;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 160;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 4;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->bannerDisplayDuration = 120;
|
||||
gCurrentPinballGame->bannerSlidePosition = 0;
|
||||
gCurrentPinballGame->bannerSlideTimer = 50;
|
||||
gCurrentPinballGame->bannerSlideVelocity = 0;
|
||||
DmaCopy16(3, gModeBannerTilemaps[4], (void *)0x06015800, 0x2400);
|
||||
DmaCopy16(3, gModeBannerPalettes[4], (void *)0x050003C0, 0x20);
|
||||
gMain.blendControl = 0xCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4,15 +4,15 @@
|
|||
#include "constants/bg_music.h"
|
||||
|
||||
extern const u8 *gBumperHitCounterTilePtrs[][2];
|
||||
extern const u8 *gBonusModeIndicatorTilePtrs[][3][2];
|
||||
extern const u8 *gHatchMachineDrawSegment[][3][2];
|
||||
extern const u8 *gSapphireBallPowerUpLightTilePtrs[][3];
|
||||
extern const u8 *gSapphireRouletteSlotTilePtrs[][4];
|
||||
extern const u8 *gSapphireCatchFlashTilePtrs[][4];
|
||||
extern const u8 *gSapphireCatchArrowBonusTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireEvoArrowBonusTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireCatchArrowTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireEvoArrowTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireEvoArrowPaletteTilePtrs[][4];
|
||||
extern const u8 *gSapphireCatchArrowPaletteTilePtrs[][4];
|
||||
extern const u8 *gSapphireCoinRewardAltTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireCoinRewardTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireModeTimerDisplayTilePtrs[][4];
|
||||
extern const u8 *gSapphireHoleIndicatorTilePtrs[][4];
|
||||
extern const u8 *gSapphireCatchLightTilePtrs[][7][2];
|
||||
|
|
@ -21,245 +21,14 @@ extern const u8 *gSapphireTrapIndicatorTilePtrs[][2];
|
|||
extern const u16 gSlingshotHitFrameIndices[];
|
||||
extern const u8 *gSapphireSlingshotTilePtrs[][3][5];
|
||||
extern const u8 *gSapphireProgressDigitTilePtrs[][4];
|
||||
extern const u8 *gSapphireCatchArrowTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireEvoArrowTilePtrs[][5][3];
|
||||
extern const u8 *gSapphireCoinRewardTilePtrs[][5][3];
|
||||
extern const s16 gCoinRewardLevelTimerThresholds[];
|
||||
|
||||
|
||||
void UpdateCoinRewardTimer(void)
|
||||
{
|
||||
if (gCurrentPinballGame->coinRewardLevel > 0)
|
||||
{
|
||||
if (gCurrentPinballGame->coinRewardLevelTimer < gCoinRewardLevelTimerThresholds[gCurrentPinballGame->coinRewardLevel - 1])
|
||||
{
|
||||
gCurrentPinballGame->coinRewardLevelTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->coinRewardLevelTimer = 0;
|
||||
gCurrentPinballGame->coinRewardLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCoinRewardMeter(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
const u8 **dest;
|
||||
|
||||
if (gCurrentPinballGame->coinRewardLevel == 0)
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase;
|
||||
sp0[2] = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->coinRewardLevel == 1)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase + 1;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->coinRewardLevel == 2)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = 3;
|
||||
}
|
||||
|
||||
src = gSapphireCoinRewardTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireCoinRewardTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 42 && gCurrentPinballGame->hudSpriteBaseY < 208)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 50 && gCurrentPinballGame->hudSpriteBaseY < 216)
|
||||
{
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
}
|
||||
|
||||
src = gSapphireCoinRewardTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireCoinRewardTilePtrs[1][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 58 && gCurrentPinballGame->hudSpriteBaseY < 224)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 66 && gCurrentPinballGame->hudSpriteBaseY < 232)
|
||||
{
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
}
|
||||
|
||||
src = gSapphireCoinRewardTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireCoinRewardTilePtrs[2][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 74 && gCurrentPinballGame->hudSpriteBaseY < 240)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 82 && gCurrentPinballGame->hudSpriteBaseY < 248)
|
||||
{
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 90)
|
||||
{
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawEvoArrowProgress(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
const u8 **dest;
|
||||
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->evoArrowProgress == 0)
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
sp0[1] = 0;
|
||||
sp0[2] = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->evoArrowProgress == 1)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase + 1;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->evoArrowProgress == 2)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->prevTravelArrowTiles[0];
|
||||
sp0[1] = gCurrentPinballGame->prevTravelArrowTiles[1];
|
||||
sp0[2] = gCurrentPinballGame->prevTravelArrowTiles[2];
|
||||
}
|
||||
|
||||
src = gSapphireEvoArrowTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireEvoArrowTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 264)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 120)
|
||||
{
|
||||
src = gSapphireEvoArrowTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireEvoArrowTilePtrs[1][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 136)
|
||||
{
|
||||
src = gSapphireEvoArrowTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireEvoArrowTilePtrs[2][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCatchArrowProgress(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
const u8 **dest;
|
||||
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->catchArrowProgress == 0)
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
sp0[1] = 0;
|
||||
sp0[2] = 0;
|
||||
}
|
||||
else if (gCurrentPinballGame->catchArrowProgress == 1)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = gCurrentPinballGame->hudBlinkPhase + 1;
|
||||
sp0[2] = gCurrentPinballGame->hudBlinkPhase * 2;
|
||||
}
|
||||
else if (gCurrentPinballGame->catchArrowProgress == 2)
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = (s16) gCurrentPinballGame->hudBlinkPhase + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = 3;
|
||||
sp0[1] = 3;
|
||||
sp0[2] = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sp0[0] = gCurrentPinballGame->travelArrowTiles[0];
|
||||
sp0[1] = gCurrentPinballGame->travelArrowTiles[1];
|
||||
sp0[2] = gCurrentPinballGame->travelArrowTiles[2];
|
||||
}
|
||||
|
||||
src = gSapphireCatchArrowTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireCatchArrowTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 264)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
}
|
||||
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 120)
|
||||
{
|
||||
src = gSapphireCatchArrowTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireCatchArrowTilePtrs[1][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
DmaCopy16(3, src[1], dest[1], 0x40);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 136)
|
||||
{
|
||||
src = gSapphireCatchArrowTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireCatchArrowTilePtrs[2][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSapphireBoardAnimations(void)
|
||||
{
|
||||
|
||||
gCurrentPinballGame->hudBlinkPhase = (gCurrentPinballGame->hudAnimFrameCounter % 40) / 20;
|
||||
gCurrentPinballGame->hudAnimFrameCounter++;
|
||||
AnimateBonusModeIndicators();
|
||||
AnimateHatchMachineSpinner();
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 83)
|
||||
AnimateSapphireCatchArrowPalette();
|
||||
|
||||
|
|
@ -271,10 +40,10 @@ void UpdateSapphireBoardAnimations(void)
|
|||
|
||||
AnimateRubyBallPowerUpSequence();
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 112)
|
||||
DrawBallPowerUpLights();
|
||||
DrawSapphireBallPowerUpLights();
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 64 && gCurrentPinballGame->hudSpriteBaseY < 254)
|
||||
AnimateCatchArrowPaletteFlash();
|
||||
AnimateSapphireCatchArrowPaletteFlash();
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 27 && gCurrentPinballGame->hudSpriteBaseY < 211)
|
||||
{
|
||||
|
|
@ -284,12 +53,12 @@ void UpdateSapphireBoardAnimations(void)
|
|||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 104)
|
||||
{
|
||||
DrawEvoArrowBonusField();
|
||||
DrawCatchArrowBonusField();
|
||||
DrawSapphireEvoArrowProgress();
|
||||
DrawSapphireCatchArrowProgress();
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 72)
|
||||
DrawCoinRewardMeterAlt();
|
||||
DrawSapphireCoinRewardMeter();
|
||||
|
||||
UpdateCoinRewardTimer();
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 110)
|
||||
|
|
@ -306,7 +75,7 @@ void UpdateSapphireBoardAnimations(void)
|
|||
DrawSapphireModeTimerDisplay();
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY >= 8 && gCurrentPinballGame->hudSpriteBaseY < 182)
|
||||
AnimateBumperHitCounter();
|
||||
AnimatePelliperBumper();
|
||||
|
||||
if (gCurrentPinballGame->saverTimeRemaining && gCurrentPinballGame->ballCatchState == 0)
|
||||
gCurrentPinballGame->saverTimeRemaining--;
|
||||
|
|
@ -483,7 +252,7 @@ void DrawSapphireModeTimerDisplay(void)
|
|||
}
|
||||
}
|
||||
|
||||
void DrawCoinRewardMeterAlt(void)
|
||||
void DrawSapphireCoinRewardMeter(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
|
|
@ -514,8 +283,8 @@ void DrawCoinRewardMeterAlt(void)
|
|||
sp0[2] = 2;
|
||||
}
|
||||
|
||||
src = gSapphireCoinRewardAltTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireCoinRewardAltTilePtrs[0][3];
|
||||
src = gSapphireCoinRewardTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireCoinRewardTilePtrs[0][3];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 240)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
|
|
@ -528,8 +297,8 @@ void DrawCoinRewardMeterAlt(void)
|
|||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 88)
|
||||
{
|
||||
src = gSapphireCoinRewardAltTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireCoinRewardAltTilePtrs[1][3];
|
||||
src = gSapphireCoinRewardTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireCoinRewardTilePtrs[1][3];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 254)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
|
|
@ -542,8 +311,8 @@ void DrawCoinRewardMeterAlt(void)
|
|||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 96)
|
||||
{
|
||||
src = gSapphireCoinRewardAltTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireCoinRewardAltTilePtrs[2][3];
|
||||
src = gSapphireCoinRewardTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireCoinRewardTilePtrs[2][3];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 264)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
|
|
@ -614,7 +383,7 @@ void AnimateSapphireEvoArrowPalette(void)
|
|||
}
|
||||
}
|
||||
|
||||
void DrawEvoArrowBonusField(void)
|
||||
void DrawSapphireEvoArrowProgress(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
|
|
@ -655,8 +424,8 @@ void DrawEvoArrowBonusField(void)
|
|||
}
|
||||
|
||||
|
||||
src = gSapphireEvoArrowBonusTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireEvoArrowBonusTilePtrs[0][4];
|
||||
src = gSapphireEvoArrowTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireEvoArrowTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 264)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
|
|
@ -666,23 +435,23 @@ void DrawEvoArrowBonusField(void)
|
|||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 120)
|
||||
{
|
||||
src = gSapphireEvoArrowBonusTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireEvoArrowBonusTilePtrs[1][4];
|
||||
src = gSapphireEvoArrowTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireEvoArrowTilePtrs[1][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 136) {
|
||||
src = gSapphireEvoArrowBonusTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireEvoArrowBonusTilePtrs[2][4];
|
||||
src = gSapphireEvoArrowTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireEvoArrowTilePtrs[2][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x40);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCatchArrowBonusField(void)
|
||||
void DrawSapphireCatchArrowProgress(void)
|
||||
{
|
||||
s16 sp0[3];
|
||||
const u8 **src;
|
||||
|
|
@ -722,8 +491,8 @@ void DrawCatchArrowBonusField(void)
|
|||
sp0[2] = gCurrentPinballGame->travelArrowTiles[2];
|
||||
}
|
||||
|
||||
src = gSapphireCatchArrowBonusTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireCatchArrowBonusTilePtrs[0][4];
|
||||
src = gSapphireCatchArrowTilePtrs[0][sp0[0]];
|
||||
dest = gSapphireCatchArrowTilePtrs[0][4];
|
||||
if (gCurrentPinballGame->hudSpriteBaseY < 264)
|
||||
{
|
||||
DmaCopy16(3, src[0], dest[0], 0x60);
|
||||
|
|
@ -734,8 +503,8 @@ void DrawCatchArrowBonusField(void)
|
|||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 120)
|
||||
{
|
||||
src = gSapphireCatchArrowBonusTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireCatchArrowBonusTilePtrs[1][4];
|
||||
src = gSapphireCatchArrowTilePtrs[1][sp0[1]];
|
||||
dest = gSapphireCatchArrowTilePtrs[1][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
DmaCopy16(3, src[1], dest[1], 0x40);
|
||||
DmaCopy16(3, src[2], dest[2], 0x60);
|
||||
|
|
@ -743,15 +512,15 @@ void DrawCatchArrowBonusField(void)
|
|||
|
||||
if (gCurrentPinballGame->hudSpriteBaseY > 136)
|
||||
{
|
||||
src = gSapphireCatchArrowBonusTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireCatchArrowBonusTilePtrs[2][4];
|
||||
src = gSapphireCatchArrowTilePtrs[2][sp0[2]];
|
||||
dest = gSapphireCatchArrowTilePtrs[2][4];
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
DmaCopy16(3, src[1], dest[1], 0x60);
|
||||
DmaCopy16(3, src[2], dest[2], 0x40);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateCatchArrowPaletteFlash(void)
|
||||
void AnimateSapphireCatchArrowPaletteFlash(void)
|
||||
{
|
||||
s16 index;
|
||||
const u8 **src;
|
||||
|
|
@ -830,7 +599,7 @@ void AnimateSapphireRouletteSlot(void)
|
|||
}
|
||||
}
|
||||
|
||||
void DrawBallPowerUpLights(void)
|
||||
void DrawSapphireBallPowerUpLights(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
|
|
@ -842,14 +611,14 @@ void DrawBallPowerUpLights(void)
|
|||
}
|
||||
}
|
||||
|
||||
void AnimateBonusModeIndicators(void)
|
||||
void AnimateHatchMachineSpinner(void)
|
||||
{
|
||||
s16 i;
|
||||
s16 srcIndex;
|
||||
const u8 **src;
|
||||
const u8 **dest;
|
||||
|
||||
if (gCurrentPinballGame->holeLetterSystemState != 3)
|
||||
if (gCurrentPinballGame->sapphireHatchMachineState != 3)
|
||||
{
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
|
|
@ -866,15 +635,15 @@ void AnimateBonusModeIndicators(void)
|
|||
srcIndex = 0;
|
||||
}
|
||||
|
||||
src = gBonusModeIndicatorTilePtrs[i][srcIndex];
|
||||
dest = gBonusModeIndicatorTilePtrs[i][2];
|
||||
src = gHatchMachineDrawSegment[i][srcIndex];
|
||||
dest = gHatchMachineDrawSegment[i][2];
|
||||
DmaCopy16(3, src[0], dest[0], 0x40);
|
||||
DmaCopy16(3, src[1], dest[1], 0x40);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateBumperHitCounter(void)
|
||||
void AnimatePelliperBumper(void)
|
||||
{
|
||||
s16 index;
|
||||
const u8 **src;
|
||||
516
src/sapphire_pond_and_zigzagoon.c
Normal file
516
src/sapphire_pond_and_zigzagoon.c
Normal file
|
|
@ -0,0 +1,516 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/main_board.h"
|
||||
|
||||
extern const s16 gPelipperIdleFrameIndices[];
|
||||
extern const s16 gPelipperSwallowAnimData[][3];
|
||||
extern const s8 gPelipperFlyAnimTable[][2];
|
||||
extern const u8 gPelipper_Gfx[][0x480];
|
||||
extern const u16 gPelipperPondSpritesheetOam[20][4][3];
|
||||
extern const s16 gWailmerAnimFrameMap[][2];
|
||||
extern const u8 gSapphireBoardWailmer_Gfx[][0x300];
|
||||
extern const u16 gWailmerSpritesheetOam[26][2][3];
|
||||
extern const u8 gSapphireBoardZigzagoonFx_Gfx[];
|
||||
extern const s16 gZigzagoonAnimKeyframes[][3];
|
||||
extern const u8 gSapphireBoardZigzagoon_Gfx[][0x380];
|
||||
extern const u16 gSapphireBoardZigzagoonSpritesheetOam[42][3][3];
|
||||
extern const u16 gZigzagoonFxSpritesheetOam[14][7][3];
|
||||
extern const u8 gZigzagoonShockWallIndicator_Gfx[][0x200];
|
||||
|
||||
extern struct SongHeader se_unk_e3;
|
||||
|
||||
void DecrementPelipperTimer(void)
|
||||
{
|
||||
if (gCurrentPinballGame->pelipperState == 1)
|
||||
{
|
||||
if (gCurrentPinballGame->pelipperFrameTimer)
|
||||
gCurrentPinballGame->pelipperFrameTimer--;
|
||||
else
|
||||
gCurrentPinballGame->pelipperState = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePelipperPondEntity(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group = &gMain.spriteGroups[60];
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const u16 *src;
|
||||
s16 var_sl;
|
||||
s16 sp0;
|
||||
s16 index;
|
||||
|
||||
var_sl = 0;
|
||||
sp0 = 0;
|
||||
switch (gCurrentPinballGame->pelipperState)
|
||||
{
|
||||
case 0:
|
||||
gCurrentPinballGame->pelipperYBobOffset = 0;
|
||||
var_sl = (gCurrentPinballGame->globalAnimFrameCounter % 50) / 25;
|
||||
gCurrentPinballGame->pelipperPosX = 0;
|
||||
gCurrentPinballGame->pelipperPosY = 0;
|
||||
break;
|
||||
case 1:
|
||||
var_sl = gPelipperIdleFrameIndices[(gCurrentPinballGame->globalAnimFrameCounter % 40) / 10];
|
||||
gCurrentPinballGame->pelipperPosX = 0;
|
||||
gCurrentPinballGame->pelipperPosY = 0;
|
||||
gCurrentPinballGame->pelipperSwallowAnimIndex = 0;
|
||||
gCurrentPinballGame->pelipperSwallowSubTimer = 0;
|
||||
if (gCurrentPinballGame->boardState > 2)
|
||||
{
|
||||
gCurrentPinballGame->pelipperState = 0;
|
||||
var_sl = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
var_sl = 4;
|
||||
break;
|
||||
case 3:
|
||||
if (gCurrentPinballGame->pelipperFrameTimer < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->pelipperFrameTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 1;
|
||||
gCurrentPinballGame->ballFrozenState = 1;
|
||||
gCurrentPinballGame->ball->velocity.x = 0;
|
||||
gCurrentPinballGame->ball->velocity.y = 0;
|
||||
gCurrentPinballGame->ball->spinSpeed = 0;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE2);
|
||||
PlayRumble(7);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 100000;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ball->positionQ0.x = 156;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 121 + gCurrentPinballGame->pelipperFrameTimer * 2;
|
||||
var_sl = 4;
|
||||
}
|
||||
else if (gCurrentPinballGame->pelipperFrameTimer < 23)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = 157;
|
||||
gCurrentPinballGame->ball->positionQ0.y = 134;
|
||||
gCurrentPinballGame->ball->ballHidden = 1;
|
||||
var_sl = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pelipperState = 4;
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
var_sl = 2;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ0.x << 8;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y << 8;
|
||||
gCurrentPinballGame->pelipperFrameTimer++;
|
||||
gCurrentPinballGame->pelipperSfxTimer = 0;
|
||||
break;
|
||||
case 4:
|
||||
if (gPelipperSwallowAnimData[gCurrentPinballGame->pelipperSwallowAnimIndex][2] > gCurrentPinballGame->pelipperSwallowSubTimer)
|
||||
{
|
||||
gCurrentPinballGame->pelipperSwallowSubTimer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pelipperSwallowSubTimer = 0;
|
||||
gCurrentPinballGame->pelipperSwallowAnimIndex++;
|
||||
if (gCurrentPinballGame->pelipperSwallowAnimIndex == 21)
|
||||
{
|
||||
gCurrentPinballGame->pelipperSwallowAnimIndex = 20;
|
||||
gCurrentPinballGame->pelipperState = 5;
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pelipperSwallowAnimIndex == 1)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE3);
|
||||
}
|
||||
|
||||
sp0 = gPelipperSwallowAnimData[gCurrentPinballGame->pelipperSwallowAnimIndex][0];
|
||||
var_sl = gPelipperSwallowAnimData[gCurrentPinballGame->pelipperSwallowAnimIndex][1];
|
||||
if (gCurrentPinballGame->pelipperSfxTimer++ % 35 == 34)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE3);
|
||||
break;
|
||||
case 5:
|
||||
if (gCurrentPinballGame->pelipperFrameTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->pelipperPosX = -360;
|
||||
gCurrentPinballGame->pelipperPosY = -200;
|
||||
}
|
||||
|
||||
index = (gCurrentPinballGame->pelipperFrameTimer % 26) / 2;
|
||||
var_sl = gPelipperFlyAnimTable[index][0];
|
||||
gCurrentPinballGame->pelipperYBobOffset = gPelipperFlyAnimTable[index][1] * 10;
|
||||
gCurrentPinballGame->pelipperFlyVelX = -12;
|
||||
gCurrentPinballGame->pelipperFlyVelY = -10;
|
||||
gCurrentPinballGame->pelipperPosX += gCurrentPinballGame->pelipperFlyVelX;
|
||||
gCurrentPinballGame->pelipperPosY += gCurrentPinballGame->pelipperFlyVelY;
|
||||
gCurrentPinballGame->ball->positionQ0.x = gCurrentPinballGame->pelipperPosX / 10 + 157;
|
||||
gCurrentPinballGame->ball->positionQ0.y = gCurrentPinballGame->pelipperPosY / 10 + 134;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ0.x << 8;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y << 8;
|
||||
gCurrentPinballGame->pelipperFrameTimer++;
|
||||
if (gCurrentPinballGame->ball->positionQ0.y < -12)
|
||||
{
|
||||
if (gCurrentPinballGame->bumperHitsSinceReset > 99)
|
||||
{
|
||||
gCurrentPinballGame->bumperHitsSinceReset = 0;
|
||||
gCurrentPinballGame->pelipperState = 6;
|
||||
gCurrentPinballGame->pelipperFrameTimer = 65;
|
||||
m4aMPlayAllStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
gCurrentPinballGame->pelipperState = 7;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pelipperSfxTimer++ % 35 == 34)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE3);
|
||||
break;
|
||||
case 6:
|
||||
gCurrentPinballGame->startButtonDisabled = 1;
|
||||
var_sl = gPelipperFlyAnimTable[0][0];
|
||||
if (gCurrentPinballGame->pelipperFrameTimer == 65)
|
||||
{
|
||||
m4aSongNumStart(SE_WARP);
|
||||
gMain.blendControl = 0x9E;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pelipperFrameTimer)
|
||||
{
|
||||
gCurrentPinballGame->pelipperFrameTimer--;
|
||||
gMain.blendBrightness = 16 - gCurrentPinballGame->pelipperFrameTimer / 4;
|
||||
if (gCurrentPinballGame->pelipperFrameTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->nextBonusField = FIELD_SPHEAL;
|
||||
gCurrentPinballGame->bonusReturnState = 2;
|
||||
gCurrentPinballGame->arrowProgressPreserved = gCurrentPinballGame->evoArrowProgress;
|
||||
gCurrentPinballGame->catchModeArrows = gCurrentPinballGame->catchArrowProgress;
|
||||
TransitionToBonusField();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
gCurrentPinballGame->pelipperPosX = -1880;
|
||||
gCurrentPinballGame->pelipperPosY = -800;
|
||||
gCurrentPinballGame->pelipperFlyVelX = 82;
|
||||
gCurrentPinballGame->pelipperFlyVelY = 0;
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
gCurrentPinballGame->pelipperState = 8;
|
||||
var_sl = 13;
|
||||
sp0 = 9;
|
||||
break;
|
||||
case 8:
|
||||
var_sl = (gCurrentPinballGame->pelipperFrameTimer % 24) / 6 + 13;
|
||||
gCurrentPinballGame->pelipperYBobOffset = (Sin(gCurrentPinballGame->pelipperFrameTimer * 0x400) * 240) / 20000;
|
||||
if (gCurrentPinballGame->pelipperFrameTimer == 0)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE4);
|
||||
|
||||
if (gCurrentPinballGame->pelipperFrameTimer < 40)
|
||||
{
|
||||
gCurrentPinballGame->pelipperPosX += gCurrentPinballGame->pelipperFlyVelX;
|
||||
gCurrentPinballGame->pelipperPosY += gCurrentPinballGame->pelipperFlyVelY;
|
||||
}
|
||||
else if (gCurrentPinballGame->pelipperFrameTimer >= 70)
|
||||
{
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
gCurrentPinballGame->pelipperState = 9;
|
||||
gCurrentPinballGame->pelipperPosX = 1200;
|
||||
gCurrentPinballGame->pelipperPosY = -1000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE3);
|
||||
gCurrentPinballGame->pelipperSfxTimer = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pelipperFrameTimer == 13)
|
||||
{
|
||||
gCurrentPinballGame->ball->ballHidden = 0;
|
||||
gCurrentPinballGame->pelipperBallDropVelX = 5;
|
||||
gCurrentPinballGame->pelipperBallDropVelY = -25;
|
||||
gCurrentPinballGame->pelipperBallDropPosX = (gCurrentPinballGame->pelipperPosX / 10 + 157) * 10;
|
||||
gCurrentPinballGame->pelipperBallDropPosY = (gCurrentPinballGame->pelipperPosY / 10 + 134) * 10;
|
||||
gCurrentPinballGame->ball->oamPriority = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ballFrozenState)
|
||||
{
|
||||
if (gCurrentPinballGame->pelipperFrameTimer < 13)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.x = gCurrentPinballGame->pelipperPosX / 10 + 157;
|
||||
gCurrentPinballGame->ball->positionQ0.y = gCurrentPinballGame->pelipperPosY / 10 + 134;
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ0.x << 8;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pelipperBallDropVelY += 2;
|
||||
gCurrentPinballGame->pelipperBallDropPosX += gCurrentPinballGame->pelipperBallDropVelX;
|
||||
gCurrentPinballGame->pelipperBallDropPosY += gCurrentPinballGame->pelipperBallDropVelY;
|
||||
gCurrentPinballGame->ball->positionQ0.x = gCurrentPinballGame->pelipperBallDropPosX / 10;
|
||||
gCurrentPinballGame->ball->positionQ0.y = gCurrentPinballGame->pelipperBallDropPosY / 10;
|
||||
if (gCurrentPinballGame->ball->positionQ0.y >= 91)
|
||||
{
|
||||
gCurrentPinballGame->ball->positionQ0.y = 91;
|
||||
gCurrentPinballGame->ballUpgradeTimerFrozen = 0;
|
||||
gCurrentPinballGame->ballFrozenState = 0;
|
||||
gCurrentPinballGame->ball->velocity.x = 128;
|
||||
gCurrentPinballGame->ball->velocity.y = 256;
|
||||
gCurrentPinballGame->ball->oamPriority = 3;
|
||||
gCurrentPinballGame->boardLayerDepth = 0;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE5);
|
||||
PlayRumble(7);
|
||||
}
|
||||
|
||||
gCurrentPinballGame->ball->positionQ1.x = gCurrentPinballGame->ball->positionQ0.x * 2;
|
||||
gCurrentPinballGame->ball->positionQ1.y = gCurrentPinballGame->ball->positionQ0.y * 2;
|
||||
gCurrentPinballGame->ball->positionQ8.x = gCurrentPinballGame->ball->positionQ0.x << 8;
|
||||
gCurrentPinballGame->ball->positionQ8.y = gCurrentPinballGame->ball->positionQ0.y << 8;
|
||||
}
|
||||
}
|
||||
|
||||
sp0 = 9;
|
||||
gCurrentPinballGame->pelipperFrameTimer++;
|
||||
break;
|
||||
case 9:
|
||||
index = (gCurrentPinballGame->pelipperFrameTimer % 26) / 2;
|
||||
var_sl = gPelipperFlyAnimTable[index][0] + 4;
|
||||
gCurrentPinballGame->pelipperYBobOffset = gPelipperFlyAnimTable[index][1];
|
||||
gCurrentPinballGame->pelipperFlyVelX = -12;
|
||||
gCurrentPinballGame->pelipperFlyVelY = 10;
|
||||
if (gCurrentPinballGame->pelipperFrameTimer < 100)
|
||||
{
|
||||
gCurrentPinballGame->pelipperPosX += gCurrentPinballGame->pelipperFlyVelX;
|
||||
gCurrentPinballGame->pelipperPosY += gCurrentPinballGame->pelipperFlyVelY;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
gCurrentPinballGame->pelipperState = 10;
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_unk_e3);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->pelipperSfxTimer++ % 35 == 34)
|
||||
MPlayStart(&gMPlayInfo_SE1, &se_unk_e3);
|
||||
|
||||
gCurrentPinballGame->pelipperFrameTimer++;
|
||||
break;
|
||||
case 10:
|
||||
gCurrentPinballGame->pelipperYBobOffset = 0;
|
||||
gCurrentPinballGame->pelipperState = 0;
|
||||
gCurrentPinballGame->pelipperFrameTimer = 0;
|
||||
var_sl = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (group->available)
|
||||
{
|
||||
DmaCopy16(3, gPelipper_Gfx[var_sl], (void *)0x060122A0, 0x480);
|
||||
group->baseX = gCurrentPinballGame->pelipperPosX / 10 + 146 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->pelipperPosY / 10 + 110 - gCurrentPinballGame->cameraYOffset + gCurrentPinballGame->pelipperYBobOffset / 10;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
src = gPelipperPondSpritesheetOam[sp0][i];
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateWailmerEntity(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const u16 *src;
|
||||
s16 index;
|
||||
s16 var0;
|
||||
|
||||
index = (gCurrentPinballGame->globalAnimFrameCounter % 32) / 16;
|
||||
group = &gMain.spriteGroups[75];
|
||||
if (gCurrentPinballGame->catchHoleAnimFrame)
|
||||
index = gCurrentPinballGame->catchHoleAnimFrame;
|
||||
|
||||
var0 = gWailmerAnimFrameMap[index][0];
|
||||
index = gWailmerAnimFrameMap[index][1];
|
||||
group->baseX = 164 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 166 - gCurrentPinballGame->cameraYOffset;
|
||||
DmaCopy16(3, gSapphireBoardWailmer_Gfx[index], (void *)0x06012720, 0x300);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
src = gWailmerSpritesheetOam[var0][i];
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateZigzagoonEntity(void)
|
||||
{
|
||||
s16 var0;
|
||||
|
||||
switch (gCurrentPinballGame->zigzagoonState)
|
||||
{
|
||||
case 0:
|
||||
gCurrentPinballGame->zigzagoonGfxFrame = (gCurrentPinballGame->globalAnimFrameCounter % 50) / 25 + 2;
|
||||
gCurrentPinballGame->zigzagoonOamFrame = gCurrentPinballGame->zigzagoonGfxFrame + 1;
|
||||
gCurrentPinballGame->zigzagoonShockWallActive = 0;
|
||||
break;
|
||||
case 1:
|
||||
var0 = gCurrentPinballGame->globalAnimFrameCounter % 33;
|
||||
if (var0 < 13)
|
||||
{
|
||||
gCurrentPinballGame->zigzagoonGfxFrame = 0;
|
||||
gCurrentPinballGame->zigzagoonOamFrame = 0;
|
||||
}
|
||||
else if (var0 < 20)
|
||||
{
|
||||
gCurrentPinballGame->zigzagoonGfxFrame = 9;
|
||||
gCurrentPinballGame->zigzagoonOamFrame = 1;
|
||||
}
|
||||
else if (var0 < 26)
|
||||
{
|
||||
gCurrentPinballGame->zigzagoonGfxFrame = 1;
|
||||
gCurrentPinballGame->zigzagoonOamFrame = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->zigzagoonGfxFrame = 9;
|
||||
gCurrentPinballGame->zigzagoonOamFrame = 1;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->ballCatchState != TRAP_CENTER_HOLE)
|
||||
gCurrentPinballGame->zigzagoonShockWallActive = 0;
|
||||
break;
|
||||
case 2:
|
||||
gCurrentPinballGame->zigzagoonShockWallActive = 0;
|
||||
gCurrentPinballGame->zigzagoonAnimKeyframeIndex = 0;
|
||||
gCurrentPinballGame->sapphireBumperAnimFrame = 0;
|
||||
gCurrentPinballGame->zigzagoonState = 3;
|
||||
gCurrentPinballGame->zigzagoonFxFrame = 0;
|
||||
gMain.spriteGroups[27].available = 1;
|
||||
gCurrentPinballGame->activePortraitType = 22;
|
||||
DmaCopy16(3, gSapphireBoardZigzagoonFx_Gfx, (void *)0x06015800, 0xC00);
|
||||
m4aSongNumStart(SE_UNKNOWN_0xEC);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 5000;
|
||||
break;
|
||||
case 3:
|
||||
if (gZigzagoonAnimKeyframes[gCurrentPinballGame->zigzagoonAnimKeyframeIndex][1] > gCurrentPinballGame->sapphireBumperAnimFrame)
|
||||
{
|
||||
gCurrentPinballGame->sapphireBumperAnimFrame++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->zigzagoonAnimKeyframeIndex++;
|
||||
gCurrentPinballGame->sapphireBumperAnimFrame = 0;
|
||||
if (gCurrentPinballGame->zigzagoonAnimKeyframeIndex > 16)
|
||||
{
|
||||
gCurrentPinballGame->zigzagoonAnimKeyframeIndex = 16;
|
||||
gCurrentPinballGame->zigzagoonState = 4;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->zigzagoonOamFrame = gZigzagoonAnimKeyframes[gCurrentPinballGame->zigzagoonAnimKeyframeIndex][0];
|
||||
gCurrentPinballGame->zigzagoonGfxFrame = gZigzagoonAnimKeyframes[gCurrentPinballGame->zigzagoonAnimKeyframeIndex][2];
|
||||
if (gCurrentPinballGame->zigzagoonAnimKeyframeIndex < 6)
|
||||
gCurrentPinballGame->zigzagoonFxFrame = gCurrentPinballGame->zigzagoonAnimKeyframeIndex + 1;
|
||||
else
|
||||
gCurrentPinballGame->zigzagoonFxFrame = 0;
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
gMain.spriteGroups[27].available = 0;
|
||||
gCurrentPinballGame->zigzagoonState = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawZigzagoonAndRouletteStopPrompt(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
const u16 *src;
|
||||
s16 index;
|
||||
|
||||
group = &gMain.spriteGroups[26];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 198 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->sapphireBumperTimer + 284 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gCurrentPinballGame->zigzagoonGfxFrame;
|
||||
DmaCopy16(3, gSapphireBoardZigzagoon_Gfx[index], (void *)0x06012A20, 0x380);
|
||||
index = gCurrentPinballGame->zigzagoonOamFrame;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
src = gSapphireBoardZigzagoonSpritesheetOam[index][i];
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
group = &gMain.spriteGroups[27];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 198 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 284 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gCurrentPinballGame->zigzagoonFxFrame;
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16*)&gOamBuffer[oamSimple->oamId];
|
||||
src = gZigzagoonFxSpritesheetOam[index][i];
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
group = &gMain.spriteGroups[70];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 206 - gCurrentPinballGame->cameraXOffset;
|
||||
if (gCurrentPinballGame->zigzagoonShockWallActive)
|
||||
{
|
||||
group->baseY = 260 - gCurrentPinballGame->cameraYOffset;
|
||||
index = (gCurrentPinballGame->globalAnimFrameCounter % 50) / 25;
|
||||
DmaCopy16(3, &gZigzagoonShockWallIndicator_Gfx[index], (void *)0x06014FA0, 0x200);
|
||||
}
|
||||
else
|
||||
{
|
||||
group->baseY = 200;
|
||||
}
|
||||
|
||||
oamSimple = &group->oam[0];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,18 @@ extern const u16 gShopSignTransitionFrames[][14];
|
|||
extern const u16 gShopSignIntroFrames[][4];
|
||||
extern const u16 gShopSignLoopFrames[][5];
|
||||
|
||||
extern const s16 gHoleAnimKeyframeData[][2];
|
||||
extern const u8 gHoleIndicatorTileGfx[][0x440];
|
||||
|
||||
void InitSapphireEggCaveState(void)
|
||||
extern const u8 gSplashEffectTileGfx[][0x100];
|
||||
extern struct Vector16 gSplashEffectPositions[];
|
||||
extern const s16 gSplashEffectFrameDurations[][2];
|
||||
extern const s16 gSplashEffectTileIndices[][2];
|
||||
extern const u8 gSapphireShopSignPalettes[][0x20];
|
||||
extern const u8 gSapphireShopSignTileGfx[][0x480];
|
||||
|
||||
|
||||
void InitSapphireEggHatchState(void)
|
||||
{
|
||||
gCurrentPinballGame->eggAnimationPhase = 1;
|
||||
gCurrentPinballGame->prevEggAnimFrame = 0;
|
||||
|
|
@ -24,7 +34,7 @@ void InitSapphireEggCaveState(void)
|
|||
gCurrentPinballGame->portraitOffsetY = 700;
|
||||
}
|
||||
|
||||
void UpdateSapphireEggCaveAnimation(void)
|
||||
void UpdateSapphireEggHatchAnimation(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
|
|
@ -160,7 +170,7 @@ void UpdateSapphireEggCaveAnimation(void)
|
|||
if (group->available)
|
||||
{
|
||||
group->baseX = 192 - gCurrentPinballGame->cameraXOffset;
|
||||
if (gCurrentPinballGame->holeLetterSystemState > 2 && gMain.modeChangeFlags)
|
||||
if (gCurrentPinballGame->sapphireHatchMachineState > 2 && gMain.modeChangeFlags)
|
||||
group->baseY = 56 - gCurrentPinballGame->cameraYOffset;
|
||||
else
|
||||
group->baseY = 200;
|
||||
|
|
@ -525,3 +535,224 @@ void UpdateSapphireShopSignAnimation(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSapphireShopSignSprite(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
group = &gMain.spriteGroups[69];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 16 - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = 115 - gCurrentPinballGame->cameraYOffset;
|
||||
index = gCurrentPinballGame->shopSignPaletteIndex + gCurrentPinballGame->activePaletteIndex * 3;
|
||||
DmaCopy16(3, gSapphireShopSignPalettes[index], (void *)0x05000300, 0x20);
|
||||
DmaCopy16(3, gSapphireShopSignTileGfx[gCurrentPinballGame->shopSignFrame], (void *) 0x06014B20, 0x480);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSapphireEggMachine(void)
|
||||
{
|
||||
s16 i, j;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
s16 index;
|
||||
|
||||
switch (gCurrentPinballGame->sapphireHatchMachineState)
|
||||
{
|
||||
case 0:
|
||||
if (gCurrentPinballGame->hatchMachineNewHit)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 3)
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx < 3)
|
||||
{
|
||||
gCurrentPinballGame->sapphireHatchMachineFrameIx++;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 20000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 920;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 0;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->sapphireHatchMachineState = 1;
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
m4aMPlayStop(&gMPlayInfo_BGM);
|
||||
gCurrentPinballGame->scoreAddedInFrame = 200000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xDF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx < 3)
|
||||
{
|
||||
gCurrentPinballGame->sapphireHatchMachineFrameIx++;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 20000;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xDE);
|
||||
}
|
||||
}
|
||||
|
||||
index = gCurrentPinballGame->sapphireHatchMachineFrameIx;
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
gCurrentPinballGame->hatchMachineNewHit = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (gCurrentPinballGame->holeAnimFrameCounter < 270)
|
||||
{
|
||||
index = (gCurrentPinballGame->holeAnimFrameCounter % 60) / 30 + 4;
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = 0;
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
gCurrentPinballGame->sapphireHatchMachineState = 2;
|
||||
gCurrentPinballGame->sapphireHatchMachineFrameIx = 0;
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->holeAnimFrameCounter == 60)
|
||||
{
|
||||
m4aSongNumStart(MUS_EGG_MODE_START);
|
||||
gCurrentPinballGame->catchArrowPaletteActive = 0;
|
||||
gCurrentPinballGame->eggAnimationPhase = 5;
|
||||
gCurrentPinballGame->eggAnimFrameIndex = 12;
|
||||
gCurrentPinballGame->eggFrameTimer = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->holeAnimFrameCounter++;
|
||||
break;
|
||||
case 3:
|
||||
if (gHoleAnimKeyframeData[gCurrentPinballGame->sapphireHatchMachineFrameIx][1] > gCurrentPinballGame->holeAnimFrameCounter)
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->sapphireHatchMachineFrameIx++;
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx == 10)
|
||||
gCurrentPinballGame->sapphireHatchMachineState = 4;
|
||||
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx == 6)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE0);
|
||||
|
||||
index = gHoleAnimKeyframeData[gCurrentPinballGame->sapphireHatchMachineFrameIx][0];
|
||||
DmaCopy16(3, &gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx < 6)
|
||||
{
|
||||
gCurrentPinballGame->walkMonYPos = 280;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->walkMonYPos += 6;
|
||||
if (gCurrentPinballGame->sapphireHatchMachineState == 4)
|
||||
gCurrentPinballGame->walkMonYPos = gCurrentPinballGame->walkMonYPos + 20;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (gCurrentPinballGame->sapphirerubyEggDeliveryState && gCurrentPinballGame->hatchMachineNewHit)
|
||||
{
|
||||
gMain.modeChangeFlags |= MODE_CHANGE_BANNER;
|
||||
gCurrentPinballGame->bannerDelayTimer = 0;
|
||||
gCurrentPinballGame->bannerDisplayTimer = 160;
|
||||
gCurrentPinballGame->cameraYScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraYAdjust = 0;
|
||||
gCurrentPinballGame->cameraYScrollSpeed = 0;
|
||||
gCurrentPinballGame->bannerGfxIndex = 0;
|
||||
gCurrentPinballGame->bannerActive = 1;
|
||||
gCurrentPinballGame->bannerPreserveBallState = 0;
|
||||
gCurrentPinballGame->sapphireHatchMachineState = 5;
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->sapphireHatchMachineFrameIx = 10;
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE0);
|
||||
gCurrentPinballGame->eggAnimationPhase = 1;
|
||||
gCurrentPinballGame->portraitOffsetX = 2080;
|
||||
gCurrentPinballGame->portraitOffsetY = 960;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->hatchMachineNewHit = 0;
|
||||
break;
|
||||
case 5:
|
||||
if (gHoleAnimKeyframeData[gCurrentPinballGame->sapphireHatchMachineFrameIx][1] > gCurrentPinballGame->holeAnimFrameCounter)
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->sapphireHatchMachineFrameIx++;
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx == 15)
|
||||
gCurrentPinballGame->sapphireHatchMachineState = 6;
|
||||
|
||||
index = gHoleAnimKeyframeData[gCurrentPinballGame->sapphireHatchMachineFrameIx][0];
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->sapphireHatchMachineFrameIx == 14 && gCurrentPinballGame->holeAnimFrameCounter == 10)
|
||||
m4aSongNumStart(SE_UNKNOWN_0xE1);
|
||||
|
||||
if (gCurrentPinballGame->portraitOffsetY > 700)
|
||||
gCurrentPinballGame->portraitOffsetY -= 5;
|
||||
else
|
||||
gCurrentPinballGame->portraitOffsetY = 700;
|
||||
break;
|
||||
case 6:
|
||||
gCurrentPinballGame->sapphireHatchMachineFrameIx = 0;
|
||||
gCurrentPinballGame->holeAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->sapphireHatchMachineState = 0;
|
||||
gCurrentPinballGame->sapphirerubyEggDeliveryState = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
group = &gMain.spriteGroups[47 + i];
|
||||
if (group->available)
|
||||
{
|
||||
if (gSplashEffectFrameDurations[gCurrentPinballGame->splashEffectFrameIndex[i]][0] > gCurrentPinballGame->splashEffectFrameTimer[i])
|
||||
{
|
||||
gCurrentPinballGame->splashEffectFrameTimer[i]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->splashEffectFrameTimer[i] = 0;
|
||||
gCurrentPinballGame->splashEffectFrameIndex[i]++;
|
||||
if (gCurrentPinballGame->splashEffectFrameIndex[i] == 6)
|
||||
{
|
||||
group->available = 0;
|
||||
gCurrentPinballGame->splashEffectFrameIndex[i] = 5;
|
||||
}
|
||||
}
|
||||
|
||||
index = gSplashEffectTileIndices[gCurrentPinballGame->splashEffectFrameIndex[i]][0];
|
||||
DmaCopy16(3, &gSplashEffectTileGfx[index], (void *)0x060140a0 + i * 0x100, 0x100);
|
||||
group->baseX = gSplashEffectPositions[gCurrentPinballGame->splashEffectPositionIndex[i]].x - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gSplashEffectPositions[gCurrentPinballGame->splashEffectPositionIndex[i]].y - gCurrentPinballGame->cameraYOffset;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
oamSimple = &group->oam[j];
|
||||
gOamBuffer[oamSimple->oamId].x = oamSimple->xOffset + group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y = oamSimple->yOffset + group->baseY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
768
src/save_and_restore_game.c
Normal file
768
src/save_and_restore_game.c
Normal file
|
|
@ -0,0 +1,768 @@
|
|||
#include "global.h"
|
||||
#include "agb_sram.h"
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
|
||||
extern u8 gBoardGfxBuffer[];
|
||||
extern u8 gBoardBGTileBufferAlt[];
|
||||
extern const u8 gMainBoardBallSave_Gfx[];
|
||||
extern const u8 gMainBoardEndOfBall_Gfx[];
|
||||
extern const u8 gBoardActionTilesGfx[];
|
||||
|
||||
extern const u8 gEggModeTilesGfx[];
|
||||
extern const u8 gAreaRouletteSelectedFx_Gfx[];
|
||||
|
||||
extern const u8 gCaptureModeTilesGfx[];
|
||||
extern const u8 gCaptureScreenTilesGfx[];
|
||||
|
||||
extern const u8 gHatchRevealTilesGfx[];
|
||||
extern const u8 gHatchStartTilesGfx[];
|
||||
extern const u8 gHatchStage2TilesGfx[];
|
||||
extern const u8 gHatchStage3TilesGfx[];
|
||||
extern const u8 gHatchFinalTilesGfx[];
|
||||
|
||||
extern const u8 *gEvoItemAppear_GfxList[];
|
||||
extern const s16 gEvoShopAnimFrames[][7];
|
||||
extern const u16 gShopCursorToItemMap[];
|
||||
|
||||
extern const u8 gRubyBoardBonusGfx[];
|
||||
extern const u8 gRubyBoardBonusObjPalette[];
|
||||
extern const u8 gRubyBoardHatchCave_Gfx[][0x480];
|
||||
extern const u8 gRubyFlashingDecorationTiles[][0x300];
|
||||
extern const u8 gRubyBoardSharpedo_Gfx[][0x260];
|
||||
extern const u8 gRubyFlashingTiles_Secondary[][0x100];
|
||||
extern const u8 gRubyBoardShopDoor_Gfx[][0x180];
|
||||
extern const u8 gRubyStageCyndaquil_Gfx[][0x280];
|
||||
extern const u8 gRubyBoardShop_Gfx[][0x500];
|
||||
|
||||
extern const u8 gSapphireBoardBonusGfx[];
|
||||
extern const u8 gSapphireBoardBonusObjPalette[];
|
||||
extern const u8 gSapphireCatchTilesGfx[];
|
||||
extern const u8 gSapphireBoardZigzagoonFx_Gfx[];
|
||||
|
||||
extern const u8 gAlphabetTilesGfx[][0x40];
|
||||
extern const u8 gSpaceTileGfx[0x40];
|
||||
extern const u8 gDecimalDigitTilesGfx[][0x40];
|
||||
extern const u8 gPokemonNameDisplayGfx[];
|
||||
extern const s16 gCaughtTextChars[];
|
||||
|
||||
extern const u8 gHoleIndicatorTileGfx[][0x440];
|
||||
extern const s16 gHoleAnimKeyframeData[][2];
|
||||
|
||||
extern const u8 gKecleonBonusClear_Gfx[0x2000];
|
||||
extern const u8 gKyogreBonusClear_Gfx[0x2000];
|
||||
extern const u8 gGroudonBoardBackgroundGfx[0x2000];
|
||||
extern const u8 gGroudonBonusClear_Gfx[0x2000];
|
||||
extern const u8 gRayquazaSkyBackgroundGfx[0x2800];
|
||||
extern const u8 gRayquazaWindBoardGfx[0x1C00];
|
||||
extern const u8 gRayquazaBonusClear_Gfx[0x2000];
|
||||
extern const u8 gRayquazaSpriteSheet[0x860];
|
||||
extern const u8 gSphealResultsScreenGfx[0x800];
|
||||
|
||||
|
||||
void SaveGameStateSnapshot(s16);
|
||||
|
||||
void RestoreFieldSpecificGraphics(void);
|
||||
void RestoreMainFieldDynamicGraphics(void);
|
||||
void RestoreRubyBoardTileGraphics(void);
|
||||
void RestoreSapphireBoardTileGraphics(void);
|
||||
void nullsub_18(void);
|
||||
void RestoreDusclopsBonusGraphics(void);
|
||||
void RestoreKecleonBonusGraphics(void);
|
||||
void RestoreKyogreBonusGraphics(void);
|
||||
void RestoreGroudonBonusGraphics(void);
|
||||
void RestoreRayquazaBonusGraphics(void);
|
||||
void RestoreSphealBonusGraphics(void);
|
||||
|
||||
void SaveGameStateSnapshot(s16 arg0)
|
||||
{
|
||||
s16 i;
|
||||
u16 *var0;
|
||||
|
||||
if (gMPlayInfo_BGM.status >= 0)
|
||||
{
|
||||
gCurrentPinballGame->savedBgmSongHeader = gMPlayInfo_BGM.songHeader;
|
||||
m4aMPlayStop(&gMPlayInfo_BGM);
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->savedBgmSongHeader = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
gCurrentPinballGame->savedSpriteAvailability[gMain.isBonusField][i] = gMain.spriteGroups[i].available;
|
||||
|
||||
DmaCopy16(3, (void *)OBJ_PLTT, gCurrentPinballGame->savedObjPalette[gMain.isBonusField], OBJ_PLTT_SIZE);
|
||||
DmaCopy16(3, (void *)BG_PLTT, gCurrentPinballGame->savedBgPalette[gMain.isBonusField], BG_PLTT_SIZE);
|
||||
if (!arg0)
|
||||
return;
|
||||
|
||||
gCurrentPinballGame->bgOffsets0 = gMain.bgOffsets[0];
|
||||
gCurrentPinballGame->bgOffsets1 = gMain.bgOffsets[1];
|
||||
gCurrentPinballGame->bgOffsets2 = gMain.bgOffsets[2];
|
||||
gCurrentPinballGame->bgOffsets3 = gMain.bgOffsets[3];
|
||||
gCurrentPinballGame->savedField = gMain.selectedField;
|
||||
gCurrentPinballGame->savedTempField = gMain.tempField;
|
||||
gCurrentPinballGame->savedIsBonusField = gMain.isBonusField;
|
||||
gCurrentPinballGame->savedModeChangeFlags = gMain.modeChangeFlags;
|
||||
gCurrentPinballGame->savedDebugMenuCursorIndex = gMain.debugMenuCursorIndex;
|
||||
gCurrentPinballGame->savedPendingModeChangeType = gMain.pendingModeChangeType;
|
||||
gCurrentPinballGame->savedAnimationTimer = gMain.animationTimer;
|
||||
gCurrentPinballGame->savedModeChangeDelayTimer = gMain.modeChangeDelayTimer;
|
||||
gCurrentPinballGame->savedShopPanelActive = gMain.shopPanelActive;
|
||||
gCurrentPinballGame->savedShopPanelSlideOffset = gMain.shopPanelSlideOffset;
|
||||
gCurrentPinballGame->savedBlendControl = gCurrentPinballGame->pauseBlendControl;
|
||||
gCurrentPinballGame->savedBlendAlpha = gCurrentPinballGame->pauseBlendAlpha;
|
||||
gCurrentPinballGame->savedBlendBrightness = gCurrentPinballGame->pauseBlendBrightness;
|
||||
gCurrentPinballGame->savedScoreOverlayActive = gCurrentPinballGame->pauseScoreOverlayActive;
|
||||
gCurrentPinballGame->savedVCount = gCurrentPinballGame->pauseVCount;
|
||||
gCurrentPinballGame->ballSpeed = gMain_saveData.ballSpeed;
|
||||
|
||||
for (i = 0; i < NUM_EREADER_CARDS; i++)
|
||||
gCurrentPinballGame->eReaderBonuses[i] = gMain.eReaderBonuses[i];
|
||||
}
|
||||
|
||||
void SaveGameToSram(void)
|
||||
{
|
||||
gCurrentPinballGame->saveDataValid = 1;
|
||||
WriteAndVerifySramFast((const u8 *)gCurrentPinballGame, (void *)SRAM + 0x544, sizeof(*gCurrentPinballGame));
|
||||
}
|
||||
|
||||
void RestoreGameState(u16 arg0)
|
||||
{
|
||||
s16 i, j;
|
||||
s16 var0, var1;
|
||||
int var2;
|
||||
|
||||
if (arg0 == 1)
|
||||
{
|
||||
ReadSramFast((void *)SRAM + 0x544, (u8 *)gCurrentPinballGame, sizeof(*gCurrentPinballGame));
|
||||
}
|
||||
else if (arg0 == 2)
|
||||
{
|
||||
DmaCopy16(3, gBoardConfig.pinballGame, gCurrentPinballGame, sizeof(*gCurrentPinballGame));
|
||||
gCurrentPinballGame->ball = &gCurrentPinballGame->ballStates[0];
|
||||
gCurrentPinballGame->secondaryBall = &gCurrentPinballGame->ballStates[0];
|
||||
var2 = gMain.idleDemoVariant;
|
||||
if ((var2 & 0x3) == 1)
|
||||
{
|
||||
gCurrentPinballGame->pikaSpinMomentum = 0;
|
||||
gCurrentPinballGame->kickbackAnimFrameTimer = 0;
|
||||
gCurrentPinballGame->kickbackFrameId = 0;
|
||||
gCurrentPinballGame->pikaChargeTarget = 0;
|
||||
gCurrentPinballGame->pikaChargeProgress = 0;
|
||||
gCurrentPinballGame->prevChargeFillValue = 0;
|
||||
gCurrentPinballGame->chargeFillValue = 0;
|
||||
gCurrentPinballGame->chargeIndicatorXOffset = 0;
|
||||
gCurrentPinballGame->chargeIndicatorYOffset = -4;
|
||||
gCurrentPinballGame->chargeIndicatorScaleX = 256;
|
||||
gCurrentPinballGame->chargeIndicatorScaleY = 256;
|
||||
gCurrentPinballGame->chargeFillAnimTimer = 0;
|
||||
gCurrentPinballGame->fullChargeSlideAnimTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg0 != 0)
|
||||
{
|
||||
gMain.selectedField = gCurrentPinballGame->savedField;
|
||||
gMain.tempField = gCurrentPinballGame->savedTempField;
|
||||
gMain.isBonusField = gCurrentPinballGame->savedIsBonusField;
|
||||
gMain.modeChangeFlags = gCurrentPinballGame->savedModeChangeFlags;
|
||||
gMain.debugMenuCursorIndex = gCurrentPinballGame->savedDebugMenuCursorIndex;
|
||||
gMain.pendingModeChangeType = gCurrentPinballGame->savedPendingModeChangeType;
|
||||
gMain.animationTimer = gCurrentPinballGame->savedAnimationTimer;
|
||||
gMain.modeChangeDelayTimer = gCurrentPinballGame->savedModeChangeDelayTimer;
|
||||
gMain.shopPanelActive = gCurrentPinballGame->savedShopPanelActive;
|
||||
gMain.shopPanelSlideOffset = gCurrentPinballGame->savedShopPanelSlideOffset;
|
||||
gMain.blendControl = gCurrentPinballGame->savedBlendControl;
|
||||
gMain.blendAlpha = gCurrentPinballGame->savedBlendAlpha;
|
||||
gMain.blendBrightness = gCurrentPinballGame->savedBlendBrightness;
|
||||
gMain.scoreOverlayActive = gCurrentPinballGame->savedScoreOverlayActive;
|
||||
gMain.vCount = gCurrentPinballGame->savedVCount;
|
||||
gMain.bgOffsets[0] = gCurrentPinballGame->bgOffsets0;
|
||||
gMain.bgOffsets[1] = gCurrentPinballGame->bgOffsets1;
|
||||
gMain.bgOffsets[2] = gCurrentPinballGame->bgOffsets2;
|
||||
gMain.bgOffsets[3] = gCurrentPinballGame->bgOffsets3;
|
||||
for (i = 0; i < NUM_EREADER_CARDS; i++)
|
||||
gMain.eReaderBonuses[i] = gCurrentPinballGame->eReaderBonuses[i];
|
||||
|
||||
gCurrentPinballGame->startButtonDisabled = 1;
|
||||
if (arg0 == 1 && gMain.selectedField < MAIN_FIELD_COUNT)
|
||||
{
|
||||
gCurrentPinballGame->cameraYViewport = gCurrentPinballGame->cameraBaseY +
|
||||
gCurrentPinballGame->tiltYOffset +
|
||||
gCurrentPinballGame->cameraScrollOffset +
|
||||
gCurrentPinballGame->cameraYAdjust;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->cameraYViewport = gCurrentPinballGame->hudSpriteBaseY;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->fadeSubState = 0;
|
||||
gMain.continueFromSave = 0;
|
||||
loadFieldBoardGraphics();
|
||||
if (gMain.selectedField == FIELD_RUBY && gCurrentPinballGame->boardCollisionConfigChanged)
|
||||
SetBoardCollisionConfig(1);
|
||||
|
||||
if (gMain.selectedField < MAIN_FIELD_COUNT)
|
||||
{
|
||||
for (i = 0; i < 22; i++)
|
||||
{
|
||||
var0 = i + gCurrentPinballGame->ballLaunchSpeed;
|
||||
var1 = (i + 10 + gCurrentPinballGame->ballLaunchSpeed) % 22;
|
||||
if (var0 < 32)
|
||||
{
|
||||
DmaCopy16(3, &gBoardGfxBuffer[var0 * 0x400], (void *)0x6008000 + var1 * 0x400, 0x400);
|
||||
}
|
||||
else
|
||||
{
|
||||
var0 -= 32;
|
||||
DmaCopy16(3, &gBoardBGTileBufferAlt[var0 * 0x400], (void *)0x6008000 + var1 * 0x400, 0x400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x800; i++)
|
||||
gBG0TilemapBuffer[i] = 0x1FF;
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x6002000, 0x1000);
|
||||
if (gMain.scoreOverlayActive)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState == 6)
|
||||
{
|
||||
for (j = 0; j <= gCurrentPinballGame->cutsceneTilemapColumn; j++)
|
||||
{
|
||||
for (i = 2; i < 12; i++)
|
||||
gBG0TilemapBuffer[(i + 15) * 0x20 + j] = 0xC100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j <= gCurrentPinballGame->cutsceneTilemapColumn; j++)
|
||||
{
|
||||
for (i = 1; i < 11; i++)
|
||||
gBG0TilemapBuffer[(i + 15) * 0x20 + j] = 0xC100;
|
||||
}
|
||||
}
|
||||
|
||||
DmaCopy16(3, gBG0TilemapBuffer, (void *)0x6002000, 0x800);
|
||||
}
|
||||
|
||||
DmaCopy16(3, gCurrentPinballGame->savedObjPalette[gMain.isBonusField], (void *)OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
DmaCopy16(3, gCurrentPinballGame->savedBgPalette[gMain.isBonusField], (void *)BG_PLTT, BG_PLTT_SIZE);
|
||||
DmaCopy16(3, &gBallPalettes[gCurrentPinballGame->ballUpgradeType], (void *)OBJ_PLTT + 0x20, 0x20);
|
||||
RestoreFieldSpecificGraphics();
|
||||
switch (gMain.selectedField)
|
||||
{
|
||||
case FIELD_RUBY:
|
||||
RubyBoardProcess_0A_50848();
|
||||
LoadShopItemGraphics(gCurrentPinballGame->evolutionShopActive);
|
||||
break;
|
||||
case FIELD_SAPPHIRE:
|
||||
SapphireBoardProcess_0A_50AD4();
|
||||
break;
|
||||
case FIELD_DUSCLOPS:
|
||||
DusclopsBoardProcess_0A_50D48();
|
||||
break;
|
||||
case FIELD_KECLEON:
|
||||
KecleonBoardProcess_0A_50DE0();
|
||||
break;
|
||||
case FIELD_KYOGRE:
|
||||
KyogreBoardProcess_0A_50F04();
|
||||
break;
|
||||
case FIELD_GROUDON:
|
||||
GroudonBoardProcess_0A_50FD4();
|
||||
break;
|
||||
case FIELD_RAYQUAZA:
|
||||
RayquazaBoardProcess_0A_51090();
|
||||
break;
|
||||
case FIELD_SPHEAL:
|
||||
SphealBoardProcess_0A_51150();
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
gMain.spriteGroups[i].available = gCurrentPinballGame->savedSpriteAvailability[gMain.isBonusField][i];
|
||||
|
||||
if (arg0 == 1)
|
||||
{
|
||||
gCurrentPinballGame->saveDataValid = 0;
|
||||
WriteAndVerifySramFast((const u8 *)gCurrentPinballGame, (void *)SRAM + 0x544, sizeof(gCurrentPinballGame->saveDataValid));
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreFieldSpecificGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
struct PokemonSpecies *species;
|
||||
const u16 *var1;
|
||||
s16 var2, var3;
|
||||
|
||||
switch (gMain.selectedField)
|
||||
{
|
||||
case FIELD_RUBY:
|
||||
RestoreMainFieldDynamicGraphics();
|
||||
RestoreRubyBoardTileGraphics();
|
||||
break;
|
||||
case FIELD_SAPPHIRE:
|
||||
RestoreMainFieldDynamicGraphics();
|
||||
RestoreSapphireBoardTileGraphics();
|
||||
break;
|
||||
case FIELD_DUSCLOPS:
|
||||
nullsub_18();
|
||||
RestoreDusclopsBonusGraphics();
|
||||
break;
|
||||
case FIELD_KECLEON:
|
||||
nullsub_18();
|
||||
RestoreKecleonBonusGraphics();
|
||||
break;
|
||||
case FIELD_KYOGRE:
|
||||
nullsub_18();
|
||||
RestoreKyogreBonusGraphics();
|
||||
break;
|
||||
case FIELD_GROUDON:
|
||||
nullsub_18();
|
||||
RestoreGroudonBonusGraphics();
|
||||
break;
|
||||
case FIELD_RAYQUAZA:
|
||||
nullsub_18();
|
||||
RestoreRayquazaBonusGraphics();
|
||||
break;
|
||||
case FIELD_SPHEAL:
|
||||
nullsub_18();
|
||||
RestoreSphealBonusGraphics();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->activePortraitType - 1)
|
||||
{
|
||||
case 0:
|
||||
if (gCurrentPinballGame->outLanePikaPosition == 2 && gCurrentPinballGame->outLaneSide == 2)
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverFullCoverageGfx, (void *)0x6015800, 0x2400);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverPartialCoverageGfx, (void *)0x6015800, 0x2400);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
DmaCopy16(3, gEggModeTilesGfx, (void *)0x6015800, 0x1000);
|
||||
break;
|
||||
case 2:
|
||||
DmaCopy16(3, gCaptureModeTilesGfx, (void *)0x6015800, 0xCA0);
|
||||
break;
|
||||
case 3:
|
||||
DmaCopy16(3, gModeBannerTilemaps[gCurrentPinballGame->bannerGfxIndex], (void *)0x6015800, 0x25E0);
|
||||
break;
|
||||
case 4:
|
||||
DmaCopy16(3, gHatchStartTilesGfx, (void *)0x6015800, 0x2000);
|
||||
break;
|
||||
case 5:
|
||||
DmaCopy16(3, gHatchStage2TilesGfx, (void *)0x6015800, 0x800);
|
||||
break;
|
||||
case 6:
|
||||
DmaCopy16(3, gHatchStage3TilesGfx, (void *)0x6015800, 0x2000);
|
||||
break;
|
||||
case 7:
|
||||
DmaCopy16(3, gHatchFinalTilesGfx, (void *)0x6015800, 0x1800);
|
||||
break;
|
||||
case 8:
|
||||
DmaCopy16(3, gCaptureScreenTilesGfx, (void *)0x6015800, 0x1C00);
|
||||
break;
|
||||
case 9:
|
||||
DmaCopy16(3, gSapphireCatchTilesGfx, (void *)0x6015800, 0x1400);
|
||||
break;
|
||||
case 10:
|
||||
DmaCopy16(3, gHatchRevealTilesGfx, (void *)0x6015800, 0x2800);
|
||||
break;
|
||||
case 11:
|
||||
DmaCopy16(3, gAreaRouletteSelectedFx_Gfx, (void *)0x6015800, 0x280);
|
||||
break;
|
||||
case 13:
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] == ' ')
|
||||
{
|
||||
DmaCopy16(3, gSpaceTileGfx, (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
int var0 = gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] - 'A';
|
||||
DmaCopy16(3, gAlphabetTilesGfx[var0], (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
}
|
||||
DmaCopy16(3, gPokemonNameDisplayGfx, (void *)0x6015C00, 0x940);
|
||||
break;
|
||||
case 12:
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] == ' ')
|
||||
{
|
||||
DmaCopy16(3, gSpaceTileGfx, (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
int var0 = gSpeciesInfo[gCurrentPinballGame->currentSpecies].name[i] - 'A';
|
||||
DmaCopy16(3, gAlphabetTilesGfx[var0], (void *)0x6015800 + i * 0x40, 0x40);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (gCaughtTextChars[i] == ' ')
|
||||
{
|
||||
DmaCopy16(3, gSpaceTileGfx, (void *)0x6015800 + (i + 10) * 0x40, 0x40);
|
||||
}
|
||||
else
|
||||
{
|
||||
int var0 = gCaughtTextChars[i] - 'A';
|
||||
DmaCopy16(3, gAlphabetTilesGfx[var0], (void *)0x6015800 + (i + 10) * 0x40, 0x40);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
DmaCopy16(3, gEvoItemAppear_GfxList[gCurrentPinballGame->evoItemGfxIndex], (void *)0x6015800, 0x1C00);
|
||||
break;
|
||||
case 15:
|
||||
DmaCopy16(3, gBoardActionTilesGfx, (void *)0x6015800, 0x2400);
|
||||
break;
|
||||
case 16:
|
||||
DmaCopy16(3, gHatchFinalTilesGfx, (void *)0x6015800, 0x1800);
|
||||
break;
|
||||
case 17:
|
||||
DmaCopy16(3, gPokemonNameDisplayGfx, (void *)0x6015C00, 0x940);
|
||||
if (gCurrentPinballGame->evolutionShopActive == 0)
|
||||
{
|
||||
var1 = gShopItemData[gShopCursorToItemMap[gCurrentPinballGame->shopItemCursor]];
|
||||
var2 = var1[3] / 10;
|
||||
DmaCopy16(3, gDecimalDigitTilesGfx[var2], (void *)0x6015DA0, 0x40);
|
||||
var3 = var1[3] % 10;
|
||||
DmaCopy16(3, gDecimalDigitTilesGfx[var3], (void *)0x6015E60, 0x40);
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
DmaCopy16(3, gMainBoardBallSave_Gfx, (void *)0x6015800, 0x2400);
|
||||
break;
|
||||
case 19:
|
||||
DmaCopy16(3, gMainBoardEndOfBall_Gfx, (void *)0x6015800, 0x2800);
|
||||
break;
|
||||
case 20:
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
DmaCopy16(3, gRubyBoardBonusGfx, (void *)0x6015800, 0x1800);
|
||||
DmaCopy16(3, gRubyBoardBonusObjPalette, (void *)OBJ_PLTT + 0x1C0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gSapphireBoardBonusGfx, (void *)0x6015800, 0x1800);
|
||||
DmaCopy16(3, gSapphireBoardBonusObjPalette, (void *)OBJ_PLTT + 0x1C0, 0x20);
|
||||
}
|
||||
break;
|
||||
case 21:
|
||||
DmaCopy16(3, gSapphireBoardZigzagoonFx_Gfx, (void *)0x6015800, 0xC00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreMainFieldDynamicGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
s16 var0;
|
||||
|
||||
LoadCatchSpriteGraphics();
|
||||
LoadEggSpriteGraphics();
|
||||
|
||||
for (i = 0; i <= 1; i++)
|
||||
{
|
||||
var0 = gCurrentPinballGame->flipper[i].position / 2;
|
||||
DmaCopy16(3, gFlipperTileGraphics[var0], ((i * 0x200) + 0x06010000), 0x200);
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->ball->spinAngle / 0x1000;
|
||||
DmaCopy16(3, gBallRotationTileGraphics[var0], 0x06010400, 0x80);
|
||||
|
||||
for (i = 0; i <= 1; i++)
|
||||
{
|
||||
DmaCopy16(3, gPikaSaverTilesGfx + ((var0 =gCurrentPinballGame->pikaSaverTileIndex[i]) * 0x180), 0x06010480 + (i * 0x180), 0x180);
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->pikachuSpinFrame;
|
||||
DmaCopy16(3, gMainBoardPikaSpinner_Gfx[var0 = gCurrentPinballGame->pikachuSpinFrame], 0x06010780, 0x120);
|
||||
var0 = gCurrentPinballGame->chargeFillValue;
|
||||
DmaCopy16(3, gChargeFillIndicator_Gfx[var0], 0x06010AE0, 0x80);
|
||||
|
||||
for (i = 0; i <= 1; i++)
|
||||
{
|
||||
switch (gCurrentPinballGame->portraitRenderMode[i])
|
||||
{
|
||||
case 0:
|
||||
DmaCopy16(3, gPortraitGenericGraphics[gCurrentPinballGame->portraitGfxIndex[i]], 0x06010CA0 + (i * 0x300), 0x300);
|
||||
gCurrentPinballGame->ball += 0; //TODO: Dumb match is still a match...
|
||||
break;
|
||||
case 9:
|
||||
if (gCurrentPinballGame->evoChainPosition > 0)
|
||||
{
|
||||
if (gMain_saveData.pokedexFlags[gCurrentPinballGame->evoTargetSpecies] == 0)
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = 205;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[i] / 15] + (gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x20, 0x050003A0, 0x20);
|
||||
}
|
||||
else if (gMain_saveData.pokedexFlags[gCurrentPinballGame->evoTargetSpecies] <= 3)
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = gCurrentPinballGame->evoTargetSpecies;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[0] + 15 * 0x20, 0x050003A0, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = gCurrentPinballGame->evoTargetSpecies;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[i] / 15] + (gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x20, 0x050003A0, 0x20);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->portraitGfxIndex[i] = gCurrentPinballGame->currentSpecies;
|
||||
DmaCopy16(3, gMonPortraitGroupPals[gCurrentPinballGame->portraitGfxIndex[i] / 15] + ((gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x20), 0x050003A0, 0x20);
|
||||
}
|
||||
case 3:
|
||||
DmaCopy16(3, gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[i] / 15] + (gCurrentPinballGame->portraitGfxIndex[i] % 15) * 0x300, 0x06010CA0 + (i * 0x18), 0x300);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
DmaCopy16(3, gPortraitAnimFrameGraphics[gCurrentPinballGame->portraitGfxIndex[i]], 0x06010CA0 + (i * 0x300), 0x300);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->boardState == 4)
|
||||
{
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 7:
|
||||
case 8:
|
||||
if ((u32) gCurrentPinballGame->captureFlashTimer > 4)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (gCurrentPinballGame->captureSequenceTimer <= 31)
|
||||
{
|
||||
if (gCurrentPinballGame->captureFlashTimer > 4)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->boardState == 8)
|
||||
{
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 2:
|
||||
if (gCurrentPinballGame->captureFlashTimer > 4U)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (gCurrentPinballGame->captureSequenceTimer <= 31)
|
||||
{
|
||||
if (gCurrentPinballGame->captureFlashTimer > 4U)
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteFlashGfx, 0x06010CA0, 0x480);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gCatchSpriteGfxBuffer, 0x06010CA0, 0x480);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DmaCopy16(3, gMainStageBonusTrap_Gfx[gCurrentPinballGame->bonusTrapAnimFrame], 0x060113C0, 0x300);
|
||||
DmaCopy16(3, gEvoItemTilesGfxPtrs[gCurrentPinballGame->evoItemGfxIndex] + var0 * 0x200, 0x060116C0, 0x200);
|
||||
DmaCopy16(3, gEggFrameTilesGfx[(s16)gEggAnimationFrameData[gCurrentPinballGame->eggAnimFrameIndex][3]], 0x06011CE0, 0x200);
|
||||
DmaCopy16(3, gBallShadowTileGraphics[gCurrentPinballGame->ballShadowTileIndex], 0x06011EE0, 0x200);
|
||||
return;
|
||||
}
|
||||
|
||||
void RestoreRubyBoardTileGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
s16 var0;
|
||||
|
||||
var0 = gEggAnimationFrameData[gCurrentPinballGame->eggAnimFrameIndex][2];
|
||||
DmaCopy16(3, gRubyBoardHatchCave_Gfx[var0], (void *)0x60122A0, 0x480);
|
||||
var0 = (gMain.systemFrameCount % 50) / 25;
|
||||
DmaCopy16(3, gRubyFlashingDecorationTiles[var0], (void *)0x6012720, 0x300);
|
||||
DmaCopy16(3, gRubyBoardSharpedo_Gfx[gCurrentPinballGame->catchHoleTileVariant], (void *)0x6012C20, 0x260);
|
||||
for (i = 0; i < 2; i++)
|
||||
DmaCopy16(3, gRubyFlashingTiles_Secondary[var0], (void *)0x6010000 + (0x174 + i * 8) * 0x20, 0x100);
|
||||
|
||||
var0 = gCurrentPinballGame->shopDoorCurrentFrame & 0xF;
|
||||
DmaCopy16(3, gRubyBoardShopDoor_Gfx[var0], (void *)0x6013180, 0x180);
|
||||
if (gCurrentPinballGame->eggCaveState < 3)
|
||||
gCurrentPinballGame->cyndaquilFrame = 0;
|
||||
else
|
||||
gCurrentPinballGame->cyndaquilFrame = 1;
|
||||
|
||||
DmaCopy16(3, gRubyStageCyndaquil_Gfx[gCurrentPinballGame->cyndaquilFrame], (void *)0x6013300, 0x280);
|
||||
var0 = gEvoShopAnimFrames[gCurrentPinballGame->evolutionShopActive][(gCurrentPinballGame->shopAnimTimer % 42) / 6];
|
||||
DmaCopy16(3, gRubyBoardShop_Gfx[var0], (void *)0x6013D00, 0x500);
|
||||
}
|
||||
|
||||
void RestoreSapphireBoardTileGraphics(void)
|
||||
{
|
||||
s16 index;
|
||||
|
||||
switch (gCurrentPinballGame->sapphireHatchMachineState)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
index = gCurrentPinballGame->sapphireHatchMachineFrameIx;
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
index = 15;
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
break;
|
||||
case 5:
|
||||
index = gHoleAnimKeyframeData[gCurrentPinballGame->sapphireHatchMachineFrameIx][0];
|
||||
DmaCopy16(3, gHoleIndicatorTileGfx[index], (void *)0x600D900, 0x440);
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RestoreDusclopsBonusGraphics(void)
|
||||
{
|
||||
DmaCopy16(3, gDusclopsBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
void RestoreKecleonBonusGraphics(void)
|
||||
{
|
||||
DmaCopy16(3, gKecleonBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
void RestoreKyogreBonusGraphics(void)
|
||||
{
|
||||
DmaCopy16(3, gKyogreBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[0] / 15] + (gCurrentPinballGame->portraitGfxIndex[0] % 15) * 0x300,
|
||||
(void *)0x6010CA0,
|
||||
0x300
|
||||
);
|
||||
}
|
||||
|
||||
void RestoreGroudonBonusGraphics(void)
|
||||
{
|
||||
if (gCurrentPinballGame->boardState < 2)
|
||||
{
|
||||
DmaCopy16(3, gGroudonBoardBackgroundGfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gGroudonBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[0] / 15] + (gCurrentPinballGame->portraitGfxIndex[0] % 15) * 0x300,
|
||||
(void *)0x6010CA0,
|
||||
0x300
|
||||
);
|
||||
}
|
||||
|
||||
void RestoreRayquazaBonusGraphics(void)
|
||||
{
|
||||
u8 var0;
|
||||
|
||||
if (gCurrentPinballGame->boardState == 0)
|
||||
{
|
||||
DmaCopy16(3, gRayquazaSkyBackgroundGfx, (void *)0x6015800, 0x2800);
|
||||
}
|
||||
else if (gCurrentPinballGame->boardState == 1)
|
||||
{
|
||||
DmaCopy16(3, gRayquazaWindBoardGfx, (void *)0x6015800, 0x1C00);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmaCopy16(3, gRayquazaBonusClear_Gfx, (void *)0x6015800, 0x2000);
|
||||
}
|
||||
|
||||
var0 = gCurrentPinballGame->bossEntityState - 2;
|
||||
if (var0 > 9)
|
||||
{
|
||||
DmaCopy16(3, gRayquazaSpriteSheet, (void *)0x6011620, 0x860);
|
||||
}
|
||||
|
||||
DmaCopy16(
|
||||
3,
|
||||
gMonPortraitGroupGfx[gCurrentPinballGame->portraitGfxIndex[0] / 15] + (gCurrentPinballGame->portraitGfxIndex[0] % 15) * 0x300,
|
||||
(void *)0x6010CA0,
|
||||
0x300
|
||||
);
|
||||
}
|
||||
|
||||
void RestoreSphealBonusGraphics(void)
|
||||
{
|
||||
s16 i;
|
||||
int var0;
|
||||
u16 var1;
|
||||
|
||||
for (i = 0; i < 0x800; i++)
|
||||
gBG0TilemapBuffer[0x400 + i] = 0x200;
|
||||
|
||||
DmaCopy16(3, &gBG0TilemapBuffer[0x400], (void *)0x6001000, 0x1000);
|
||||
gMain.blendControl = 0x1C42;
|
||||
gMain.blendAlpha = 0xC04;
|
||||
for (i = 0; i < 0x140; i++)
|
||||
{
|
||||
var0 = i;
|
||||
if (i < 0)
|
||||
var0 += 31;
|
||||
|
||||
var0 = (var0 >> 5) << 5;
|
||||
var1 = i - var0 - 2;
|
||||
if (var1 < 28)
|
||||
gBG0TilemapBuffer[0x800 + i] = 0x9000;
|
||||
}
|
||||
|
||||
gMain.bgOffsets[1].xOffset = 8;
|
||||
gMain.bgOffsets[1].yOffset = 126;
|
||||
DmaCopy16(3, &gBG0TilemapBuffer[0x800], (void *)0x6001140, 0x280);
|
||||
for (i = 0; i < 0x800; i++)
|
||||
gBG0TilemapBuffer[i] = 0x1FF;
|
||||
|
||||
DmaCopy16(3, gSphealResultsScreenGfx, (void *)0x6015800, 0x800);
|
||||
}
|
||||
|
||||
void nullsub_18(void)
|
||||
{
|
||||
}
|
||||
|
|
@ -31,6 +31,14 @@ enum
|
|||
SUBSTATE_11,
|
||||
};
|
||||
|
||||
void ClearHighScoreNameEntry(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HIGH_SCORE_NAME_LENGTH; i++)
|
||||
gHighScoreNameEntry[i] = 0;
|
||||
}
|
||||
|
||||
void TitlescreenMain(void)
|
||||
{
|
||||
gTitlescreenStateFuncs[gMain.subState]();
|
||||
|
|
|
|||
533
src/travel_mode.c
Normal file
533
src/travel_mode.c
Normal file
|
|
@ -0,0 +1,533 @@
|
|||
#include "global.h"
|
||||
#include "m4a.h"
|
||||
#include "main.h"
|
||||
#include "constants/bg_music.h"
|
||||
#include "constants/ruby_states.h"
|
||||
|
||||
extern const s16 gAreaRouletteTable[][7];
|
||||
extern const s16 gAreaToSpeciesTable[];
|
||||
extern const u16 gAreaRouletteOamFramesets[18][27];
|
||||
|
||||
extern const u8 gTravelPortraitPalette[];
|
||||
extern const u8 gAreaRouletteSelectedFx_Gfx[];
|
||||
|
||||
extern const u8 gDefaultBallPalette[];
|
||||
|
||||
extern const s16 gPondDialAnimFrames[];
|
||||
extern const s16 gBumperAnimFrames[];
|
||||
|
||||
void InitAreaRoulette(void)
|
||||
{
|
||||
s16 i;
|
||||
|
||||
gCurrentPinballGame->boardSubState = 1;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->creatureOamPriority = 3;
|
||||
gCurrentPinballGame->areaVisitCount = 0;
|
||||
gCurrentPinballGame->areaRouletteSlotIndex = (Random() + gMain.systemFrameCount) % 6;
|
||||
gCurrentPinballGame->area = gAreaRouletteTable[gMain.selectedField][gCurrentPinballGame->areaRouletteSlotIndex];
|
||||
gCurrentPinballGame->rouletteAreaIndex[1] = gAreaToSpeciesTable[gCurrentPinballGame->area];
|
||||
gCurrentPinballGame->area = gAreaRouletteTable[gMain.selectedField][(gCurrentPinballGame->areaRouletteSlotIndex + 1) % 6];
|
||||
gCurrentPinballGame->rouletteAreaIndex[0] = gAreaToSpeciesTable[gCurrentPinballGame->area];
|
||||
LoadPortraitGraphics(0, 0);
|
||||
LoadPortraitGraphics(0, 1);
|
||||
for (i = 0; i < 6; i++)
|
||||
gCurrentPinballGame->hatchTilePalette[i] = 13;
|
||||
|
||||
DmaCopy16(3, gTravelPortraitPalette, (void *)0x050003C0, 0x20);
|
||||
DmaCopy16(3, gAreaRouletteSelectedFx_Gfx, (void *)0x06015800, 0x280);
|
||||
gCurrentPinballGame->activePortraitType = 12;
|
||||
}
|
||||
|
||||
void UpdateAreaRoulette(void)
|
||||
{
|
||||
s16 i;
|
||||
struct SpriteGroup *group;
|
||||
struct OamDataSimple *oamSimple;
|
||||
u16 *dst;
|
||||
s16 var0;
|
||||
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 1:
|
||||
gMain.blendControl = 0x1C10;
|
||||
gMain.blendAlpha = BLDALPHA_BLEND(0, 16);
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->rouletteSubOffset = 0;
|
||||
gCurrentPinballGame->cameraScrollTarget = 0;
|
||||
gCurrentPinballGame->cameraScrollEnabled = 1;
|
||||
gMain.fieldSpriteGroups[20]->available = 1;
|
||||
gMain.fieldSpriteGroups[21]->available = 1;
|
||||
gMain.fieldSpriteGroups[23]->available = 1;
|
||||
gMain.fieldSpriteGroups[22]->available = 1;
|
||||
gMain.fieldSpriteGroups[19]->available = 1;
|
||||
gCurrentPinballGame->rouletteFrameIndex = 30;
|
||||
gCurrentPinballGame->rouletteRotationPeriod = 30;
|
||||
gCurrentPinballGame->rouletteSpinSpeed = 0;
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
gCurrentPinballGame->pondBumperStates[0] = 10;
|
||||
gCurrentPinballGame->pondBumperStates[1] = 10;
|
||||
gCurrentPinballGame->pondBumperStates[2] = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->pondBumperStates[0] = 0;
|
||||
gCurrentPinballGame->pondBumperStates[1] = 0;
|
||||
gCurrentPinballGame->pondBumperStates[2] = 0;
|
||||
}
|
||||
gCurrentPinballGame->rubyPondChangeTimer = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (gCurrentPinballGame->cameraScrollOffset == 0)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
}
|
||||
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer < 143)
|
||||
gCurrentPinballGame->pondBumperStates[0] = gPondDialAnimFrames[gCurrentPinballGame->rubyPondChangeTimer / 8];
|
||||
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer >= 18 && gCurrentPinballGame->rubyPondChangeTimer < 161)
|
||||
gCurrentPinballGame->pondBumperStates[2] = gPondDialAnimFrames[(gCurrentPinballGame->rubyPondChangeTimer - 18) / 8];
|
||||
|
||||
if (gCurrentPinballGame->rubyPondChangeTimer >= 36 && gCurrentPinballGame->rubyPondChangeTimer < 179)
|
||||
gCurrentPinballGame->pondBumperStates[1] = gPondDialAnimFrames[(gCurrentPinballGame->rubyPondChangeTimer - 36) / 8];
|
||||
|
||||
gCurrentPinballGame->rubyPondChangeTimer++;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->rouletteSubOffset = (gCurrentPinballGame->rouletteFrameIndex * 32) / gCurrentPinballGame->rouletteRotationPeriod;
|
||||
gCurrentPinballGame->portraitDisplayState = 1;
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
UpdateRouletteAnimState();
|
||||
break;
|
||||
case 3:
|
||||
if (gCurrentPinballGame->stageTimer < 15)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
if (gCurrentPinballGame->stageTimer == 15)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->rouletteRotationPeriod = 6;
|
||||
gCurrentPinballGame->rouletteSpinSpeed = 0;
|
||||
}
|
||||
}
|
||||
SetRouletteActiveState(0);
|
||||
/* fallthrough */
|
||||
case 4:
|
||||
case 5:
|
||||
if (gCurrentPinballGame->boardSubState == 3)
|
||||
{
|
||||
gCurrentPinballGame->rouletteFrameIndex--;
|
||||
gCurrentPinballGame->rouletteFrameIndex %= gCurrentPinballGame->rouletteRotationPeriod;
|
||||
}
|
||||
else if (gCurrentPinballGame->boardSubState == 4)
|
||||
{
|
||||
gCurrentPinballGame->rouletteFrameIndex++;
|
||||
if (gCurrentPinballGame->newButtonActions[1] && gCurrentPinballGame->boardSubState == 4)
|
||||
{
|
||||
if (gCurrentPinballGame->rouletteSpinSpeed == 0)
|
||||
{
|
||||
if (gMain.eReaderBonuses[EREADER_RUIN_AREA_CARD])
|
||||
gCurrentPinballGame->rouletteSpinSpeed = 48;
|
||||
else
|
||||
gCurrentPinballGame->rouletteSpinSpeed = 1;
|
||||
|
||||
gCurrentPinballGame->rouletteInitialSpeed = gCurrentPinballGame->rouletteSpinSpeed;
|
||||
gCurrentPinballGame->spoinkEntityState = 1;
|
||||
gCurrentPinballGame->launcherCharging = 1;
|
||||
gCurrentPinballGame->saverTimeRemaining = 3600;
|
||||
gCurrentPinballGame->rubyPondState = RUBY_POND_STATE_CHINCHOU_COUNTERCLOCKWISE;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->rouletteSpinSpeed)
|
||||
{
|
||||
gCurrentPinballGame->rouletteSpinSpeed--;
|
||||
if (gMain.eReaderBonuses[EREADER_RUIN_AREA_CARD])
|
||||
{
|
||||
gCurrentPinballGame->numCompletedBonusStages = 4;
|
||||
if (gCurrentPinballGame->rouletteSpinSpeed < 24)
|
||||
{
|
||||
gCurrentPinballGame->rouletteSpinSpeed = 24;
|
||||
if (gCurrentPinballGame->areaRouletteSlotIndex == 6)
|
||||
gCurrentPinballGame->rouletteSpinSpeed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->rouletteSpinSpeed == 0)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gCurrentPinballGame->rouletteFrameIndex == gCurrentPinballGame->rouletteRotationPeriod)
|
||||
{
|
||||
gCurrentPinballGame->rouletteRotationPeriod = 40 - (gCurrentPinballGame->rouletteSpinSpeed * 30) / gCurrentPinballGame->rouletteInitialSpeed;
|
||||
gCurrentPinballGame->rouletteFrameIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->rouletteFrameIndex %= gCurrentPinballGame->rouletteRotationPeriod;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->rouletteFrameIndex++;
|
||||
gCurrentPinballGame->rouletteFrameIndex %= gCurrentPinballGame->rouletteRotationPeriod;
|
||||
if (gCurrentPinballGame->rouletteFrameIndex == 0)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gMain.fieldSpriteGroups[23]->available = 0;
|
||||
gMain.fieldSpriteGroups[20]->available = 0;
|
||||
gMain.fieldSpriteGroups[21]->available = 0;
|
||||
gMain.fieldSpriteGroups[34]->available = 1;
|
||||
m4aSongNumStart(SE_AREA_ROULETTE_SELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->rouletteSubOffset = (gCurrentPinballGame->rouletteFrameIndex * 32) / gCurrentPinballGame->rouletteRotationPeriod;
|
||||
if (gCurrentPinballGame->rouletteFrameIndex == 0)
|
||||
{
|
||||
gCurrentPinballGame->rouletteAreaIndex[0] = gCurrentPinballGame->rouletteAreaIndex[1];
|
||||
LoadPortraitGraphics(0, 0);
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->rouletteFrameIndex == 1)
|
||||
{
|
||||
if (gMain.eReaderBonuses[EREADER_RUIN_AREA_CARD])
|
||||
{
|
||||
gCurrentPinballGame->areaRouletteSlotIndex = (gCurrentPinballGame->areaRouletteSlotIndex + 1) % 7;
|
||||
gCurrentPinballGame->areaRouletteNextSlot = 0;
|
||||
gCurrentPinballGame->areaRouletteFarSlot = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->areaRouletteSlotIndex = (gCurrentPinballGame->areaRouletteSlotIndex + 1) % 6;
|
||||
gCurrentPinballGame->areaRouletteNextSlot = (gCurrentPinballGame->areaRouletteSlotIndex + 1) % 6;
|
||||
gCurrentPinballGame->areaRouletteFarSlot = (gCurrentPinballGame->areaRouletteSlotIndex + 2) % 6;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->area = gAreaRouletteTable[gMain.selectedField][gCurrentPinballGame->areaRouletteSlotIndex];
|
||||
gCurrentPinballGame->rouletteAreaIndex[1] = gAreaToSpeciesTable[gCurrentPinballGame->area];
|
||||
LoadPortraitGraphics(0, 1);
|
||||
m4aSongNumStart(SE_ROULETTE_TICK);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (gCurrentPinballGame->stageTimer < 50)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
if (gCurrentPinballGame->stageTimer == 50)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
RequestBoardStateTransition(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer < 29)
|
||||
{
|
||||
if (gCurrentPinballGame->stageTimer < 8)
|
||||
var0 = gCurrentPinballGame->stageTimer / 4;
|
||||
else
|
||||
var0 = ((gCurrentPinballGame->stageTimer - 8) / 3) + 2;
|
||||
|
||||
group = gMain.fieldSpriteGroups[34];
|
||||
if (group->available)
|
||||
{
|
||||
group->baseX = 96u - gCurrentPinballGame->cameraXOffset;
|
||||
group->baseY = gCurrentPinballGame->rouletteSubOffset + 300u - gCurrentPinballGame->cameraYOffset;
|
||||
if (group->baseY >= 200)
|
||||
group->baseY = 200;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
oamSimple = &group->oam[i];
|
||||
dst = (u16 *)&gOamBuffer[oamSimple->oamId];
|
||||
*dst++ = gAreaRouletteOamFramesets[var0][i * 3 + 0];
|
||||
*dst++ = gAreaRouletteOamFramesets[var0][i * 3 + 1];
|
||||
*dst++ = gAreaRouletteOamFramesets[var0][i * 3 + 2];
|
||||
|
||||
gOamBuffer[oamSimple->oamId].x += group->baseX;
|
||||
gOamBuffer[oamSimple->oamId].y += group->baseY;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 0x1C) {
|
||||
gMain.fieldSpriteGroups[34]->available = 0;
|
||||
gCurrentPinballGame->activePortraitType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gCurrentPinballGame->portraitDisplayState = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRouletteAnimState(void)
|
||||
{
|
||||
s16 index;
|
||||
|
||||
index = (gMain.systemFrameCount % 100) / 10;
|
||||
gCurrentPinballGame->hudAnimFrameCounter = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = gBumperAnimFrames[index];
|
||||
gCurrentPinballGame->evoArrowProgress = gBumperAnimFrames[index];
|
||||
gCurrentPinballGame->coinRewardLevel = gBumperAnimFrames[index];
|
||||
if (index == 7 || index == 9)
|
||||
{
|
||||
gCurrentPinballGame->catchArrowPaletteActive = 1;
|
||||
gCurrentPinballGame->rouletteSlotActive = 1;
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->catchArrowPaletteActive = 0;
|
||||
gCurrentPinballGame->rouletteSlotActive = 0;
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SetRouletteActiveState(s16 arg0)
|
||||
{
|
||||
if (arg0)
|
||||
{
|
||||
gCurrentPinballGame->rouletteSlotActive = 1;
|
||||
gCurrentPinballGame->catchArrowPaletteActive = 1;
|
||||
gCurrentPinballGame->catchProgressFlashing = 1;
|
||||
gCurrentPinballGame->evoArrowProgress = 3;
|
||||
gCurrentPinballGame->coinRewardLevel = 3;
|
||||
gCurrentPinballGame->catchArrowProgress = 3;
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->evoArrowPaletteActive = 0;
|
||||
gCurrentPinballGame->rouletteSlotActive = 0;
|
||||
gCurrentPinballGame->catchArrowPaletteActive = 0;
|
||||
gCurrentPinballGame->evoArrowProgress = 0;
|
||||
gCurrentPinballGame->coinRewardLevel = 0;
|
||||
gCurrentPinballGame->catchArrowProgress = 2;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->progressLevel = 1;
|
||||
}
|
||||
|
||||
void CleanupTravelModeState(void)
|
||||
{
|
||||
gCurrentPinballGame->travelRouletteSlotHitType = 0;
|
||||
gCurrentPinballGame->seedotCount = 0;
|
||||
if (gMain.selectedField == FIELD_RUBY)
|
||||
{
|
||||
gCurrentPinballGame->gulpinCurrentLevel = 0;
|
||||
gCurrentPinballGame->gulpinAnimFrameIndex = 0;
|
||||
gCurrentPinballGame->gulpinAnimFrameTimer = 0;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->seedotExitSequenceActive = 1;
|
||||
gCurrentPinballGame->seedotExitSequenceTimer = 0;
|
||||
LoadPortraitGraphics(0, 0);
|
||||
gCurrentPinballGame->portraitDisplayState = 0;
|
||||
gMain.fieldSpriteGroups[13]->available = 0;
|
||||
gCurrentPinballGame->trapAnimState = 0;
|
||||
gCurrentPinballGame->bonusTrapEnabled = 0;
|
||||
gCurrentPinballGame->prevTravelArrowTiles[0] = gCurrentPinballGame->travelArrowTiles[0] = 0;
|
||||
gCurrentPinballGame->prevTravelArrowTiles[1] = gCurrentPinballGame->travelArrowTiles[1] = 0;
|
||||
gCurrentPinballGame->prevTravelArrowTiles[2] = gCurrentPinballGame->travelArrowTiles[2] = 0;
|
||||
ResetEventState();
|
||||
}
|
||||
|
||||
void InitTravelMode(void)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->boardModeType = 2;
|
||||
gCurrentPinballGame->eventTimer = gCurrentPinballGame->timerBonus + 3600;
|
||||
gCurrentPinballGame->timerBonus = 0;
|
||||
gCurrentPinballGame->saverTimeRemaining = 1800;
|
||||
DmaCopy16(3, gDefaultBallPalette, (void *)0x05000180, 0x20);
|
||||
}
|
||||
|
||||
void UpdateTravelMode(void)
|
||||
{
|
||||
s16 var0;
|
||||
|
||||
if (gCurrentPinballGame->boardModeType && gCurrentPinballGame->eventTimer < 2 && gCurrentPinballGame->boardSubState < 6)
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
m4aSongNumStart(MUS_END_OF_BALL2);
|
||||
gCurrentPinballGame->stageTimer = 200;
|
||||
gCurrentPinballGame->boardSubState = 6;
|
||||
}
|
||||
|
||||
switch (gCurrentPinballGame->boardSubState)
|
||||
{
|
||||
case 0:
|
||||
if (gMain.modeChangeFlags == MODE_CHANGE_NONE)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->portraitCycleFrame = 0;
|
||||
}
|
||||
gCurrentPinballGame->travelRouletteSlotHitType = 0;
|
||||
break;
|
||||
case 1:
|
||||
LoadPortraitGraphics(4, 0);
|
||||
if (gCurrentPinballGame->stageTimer == 35)
|
||||
m4aSongNumStart(MUS_TRAVEL_MODE);
|
||||
|
||||
if (gCurrentPinballGame->travelRouletteSlotHitType)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
if (gCurrentPinballGame->stageTimer < 35)
|
||||
m4aSongNumStart(MUS_TRAVEL_MODE);
|
||||
|
||||
gCurrentPinballGame->seedotCount = 0;
|
||||
gCurrentPinballGame->seedotExitSequenceActive = 1;
|
||||
gCurrentPinballGame->seedotExitSequenceTimer = 0;
|
||||
}
|
||||
|
||||
var0 = (gCurrentPinballGame->stageTimer % 40) / 10;
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
if (var0 == 0)
|
||||
{
|
||||
gCurrentPinballGame->travelArrowTiles[0] = 0;
|
||||
gCurrentPinballGame->travelArrowTiles[1] = 0;
|
||||
gCurrentPinballGame->travelArrowTiles[2] = 0;
|
||||
}
|
||||
else if (var0 == 1)
|
||||
{
|
||||
gCurrentPinballGame->travelArrowTiles[0] = 3;
|
||||
gCurrentPinballGame->travelArrowTiles[1] = 1;
|
||||
gCurrentPinballGame->travelArrowTiles[2] = 0;
|
||||
}
|
||||
else if (var0 == 2)
|
||||
{
|
||||
gCurrentPinballGame->travelArrowTiles[0] = 3;
|
||||
gCurrentPinballGame->travelArrowTiles[1] = 3;
|
||||
gCurrentPinballGame->travelArrowTiles[2] = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->travelArrowTiles[0] = 3;
|
||||
gCurrentPinballGame->travelArrowTiles[1] = 3;
|
||||
gCurrentPinballGame->travelArrowTiles[2] = 3;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->prevTravelArrowTiles[0] = gCurrentPinballGame->travelArrowTiles[0];
|
||||
gCurrentPinballGame->prevTravelArrowTiles[1] = gCurrentPinballGame->travelArrowTiles[1];
|
||||
gCurrentPinballGame->prevTravelArrowTiles[2] = gCurrentPinballGame->travelArrowTiles[2];
|
||||
break;
|
||||
case 2:
|
||||
ShowBonusTrapSprite();
|
||||
gCurrentPinballGame->trapAnimState = 2;
|
||||
LoadPortraitGraphics(0, 0);
|
||||
gCurrentPinballGame->prevTravelArrowTiles[0] = gCurrentPinballGame->travelArrowTiles[0] = 0;
|
||||
gCurrentPinballGame->prevTravelArrowTiles[1] = gCurrentPinballGame->travelArrowTiles[1] = 0;
|
||||
gCurrentPinballGame->prevTravelArrowTiles[2] = gCurrentPinballGame->travelArrowTiles[2] = 0;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 3:
|
||||
AnimateBonusTrapSprite();
|
||||
if (gCurrentPinballGame->ballCatchState == 4)
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 4:
|
||||
gCurrentPinballGame->boardModeType = 3;
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
gCurrentPinballGame->portraitCycleFrame = 0;
|
||||
gCurrentPinballGame->modeOutcomeValues[0] = 47;
|
||||
LoadPortraitGraphics(7, 0);
|
||||
break;
|
||||
case 5:
|
||||
if (gCurrentPinballGame->modeAnimTimer == 145)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
gCurrentPinballGame->modeOutcomeValues[0] = 47;
|
||||
LoadPortraitGraphics(7, 0);
|
||||
if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 144;
|
||||
m4aMPlayAllStop();
|
||||
LoadPortraitGraphics(0, 0);
|
||||
if (gCurrentPinballGame->areaVisitCount < 5)
|
||||
{
|
||||
var0 = gCurrentPinballGame->areaRouletteFarSlot;
|
||||
if (gCurrentPinballGame->travelRouletteSlotHitType == 1)
|
||||
gCurrentPinballGame->areaRouletteSlotIndex = gCurrentPinballGame->areaRouletteNextSlot;
|
||||
else
|
||||
gCurrentPinballGame->areaRouletteSlotIndex = gCurrentPinballGame->areaRouletteFarSlot;
|
||||
|
||||
gCurrentPinballGame->areaRouletteNextSlot = (var0 + 1) % 6;
|
||||
gCurrentPinballGame->areaRouletteFarSlot = (var0 + 2) % 6;
|
||||
gCurrentPinballGame->areaVisitCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->areaRouletteSlotIndex = 6;
|
||||
gCurrentPinballGame->areaVisitCount = 0;
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON))
|
||||
{
|
||||
m4aMPlayAllStop();
|
||||
m4aSongNumStart(SE_MENU_CANCEL);
|
||||
gCurrentPinballGame->modeAnimTimer = 60;
|
||||
gCurrentPinballGame->boardSubState = 6;
|
||||
if (gCurrentPinballGame->allHolesLit)
|
||||
gCurrentPinballGame->allHolesLitDelayTimer = 120;
|
||||
}
|
||||
}
|
||||
|
||||
if (gCurrentPinballGame->modeAnimTimer == 130)
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer++;
|
||||
if (gCurrentPinballGame->stageTimer < 490)
|
||||
{
|
||||
RunTravelEventCutscene();
|
||||
if (gCurrentPinballGame->scoreCounterAnimationEnabled && gCurrentPinballGame->stageTimer >= 428)
|
||||
gCurrentPinballGame->stageTimer = 428;
|
||||
|
||||
if (gCurrentPinballGame->stageTimer == 394)
|
||||
{
|
||||
gCurrentPinballGame->scoreCounterAnimationEnabled = TRUE;
|
||||
gCurrentPinballGame->scoreAddedInFrame = 500000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gCurrentPinballGame->modeAnimTimer = 120;
|
||||
}
|
||||
|
||||
gCurrentPinballGame->stageTimer++;
|
||||
}
|
||||
else if (gCurrentPinballGame->modeAnimTimer == 0)
|
||||
{
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
gCurrentPinballGame->stageTimer = 0;
|
||||
if (gCurrentPinballGame->travelModeCompletionCount < 99)
|
||||
gCurrentPinballGame->travelModeCompletionCount++;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
AnimateBonusTrapSprite();
|
||||
gMain.fieldSpriteGroups[13]->available = 0;
|
||||
CleanupTravelModeState();
|
||||
gCurrentPinballGame->boardSubState++;
|
||||
break;
|
||||
case 7:
|
||||
if (gCurrentPinballGame->stageTimer)
|
||||
{
|
||||
gCurrentPinballGame->stageTimer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestBoardStateTransition(1);
|
||||
gCurrentPinballGame->boardSubState = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
52
src/util.c
52
src/util.c
|
|
@ -290,3 +290,55 @@ void SetMatrixScale(s16 xScale, s16 yScale, s16 matrixNum)
|
|||
gOamBuffer[matrixNum * 4 + 2].affineParam = c2;
|
||||
gOamBuffer[matrixNum * 4 + 3].affineParam = a; // TODO fake match as above
|
||||
}
|
||||
|
||||
|
||||
u16 IsInVblank(void)
|
||||
{
|
||||
if ((REG_IME & 1) // Interrupts enabled
|
||||
&& (REG_DISPSTAT & DISPSTAT_VBLANK_INTR) // In VBLANK
|
||||
&& (REG_IE & INTR_FLAG_VBLANK) // VBlank interrupt enabled
|
||||
&& !(REG_DISPCNT & DISPCNT_FORCED_BLANK)) // Ignore VBlank interrupts during forced blank
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SetMainCallback(void (*func)(void))
|
||||
{
|
||||
gMainCallbackShadow = func;
|
||||
if (!IsInVblank())
|
||||
gMainCallback = func;
|
||||
}
|
||||
|
||||
void ResetMainCallback(void)
|
||||
{
|
||||
gMainCallback = DefaultMainCallback;
|
||||
gMainCallbackShadow = DefaultMainCallback;
|
||||
}
|
||||
|
||||
void SetVBlankIntrFunc(void (*func)(void))
|
||||
{
|
||||
gVBlankIntrFuncShadow = func;
|
||||
if (!IsInVblank())
|
||||
*gVBlankIntrFuncPtr = func;
|
||||
}
|
||||
|
||||
void ResetVBlankIntrFunc(void)
|
||||
{
|
||||
*gVBlankIntrFuncPtr = VBlankIntr;
|
||||
gVBlankIntrFuncShadow = VBlankIntr;
|
||||
}
|
||||
|
||||
void SetVCountIntrFunc(void (*func)(void))
|
||||
{
|
||||
gVCountIntrFuncShadow = func;
|
||||
if (!IsInVblank())
|
||||
*gVCountIntrFuncPtr = func;
|
||||
}
|
||||
|
||||
void ResetVCountIntrFunc(void)
|
||||
{
|
||||
*gVCountIntrFuncPtr = VCountIntr;
|
||||
gVCountIntrFuncShadow = VCountIntr;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user