Baby Bowser - brunovalads/yoshisisland-disassembly GitHub Wiki

States

; baby bowser states
  dw $C7D5                                      ; $0DC50D | 00: prepare to jump attack / idle
  dw $C81A                                      ; $0DC50F | 01: jump attack
  dw $C834                                      ; $0DC511 | 02: pre-slam flip at apex of jump
  dw $C876                                      ; $0DC513 | 03: jump slam
  dw $C916                                      ; $0DC515 | 04: idle after slam attack
  dw $C985                                      ; $0DC517 | 05: prepare to idle jump
  dw $C9B3                                      ; $0DC519 | 06: idle jump to prepare for next slam attack
  dw $C9E4                                      ; $0DC51B | 07:
  dw $CA06                                      ; $0DC51D | 08:
  dw $CA0E                                      ; $0DC51F | 09: idle animations after non-attack (flying off yoshi / hit by eggs)
  dw $CADC                                      ; $0DC521 | 0A: hit by yoshi
  dw $CAFD                                      ; $0DC523 | 0B: flip around on ground after being hit
  dw $CB4C                                      ; $0DC525 | 0C: laying on ground after being hit
  dw $CB6C                                      ; $0DC527 | 0D: prepare to jump attack after being hit
  dw $CB82                                      ; $0DC529 | 0E: idle after last hit (before cutscene)
  dw $CBC9                                      ; $0DC52B | 0F: idle after last (during cutscene)
  dw $CC11                                      ; $0DC52D | 10: prepare to expand
  dw $CC28                                      ; $0DC52F | 11: fade baby bowser's color to black
  dw $CE3C                                      ; $0DC531 | 12: pre-fight cutscene (with kamek)

; midpoint respawn cutscene states
  dw $EBAA                                      ; $0DC533 | 13: pre-cutscene idle (without kamek)
  dw $EBE7                                      ; $0DC535 | 14: pre-cutscene centering screen on baby bowser (without kamek)
  dw $CE3C                                      ; $0DC537 | 15: pre-fight cutscene (without kamek)

; prepare mecha bowser states
  dw $D267                                      ; $0DC539 | 16: baby bowser expanding
  dw $D300                                      ; $0DC53B | 17: prepare fight (black screen)
  dw $D4AC                                      ; $0DC53D | 18: prepare fade in (black screen)
  dw $D617                                      ; $0DC53F | 19: idle before fight (no bowser)
  dw $D65E                                      ; $0DC541 | 1A: mecha-bowser rising into frame
  dw $D71D                                      ; $0DC543 | 1B: idle (summon rocks)
  dw $DA15                                      ; $0DC545 | 1C: walk forward

; mecha bowser states
  dw $D77B                                      ; $0DC547 | 1D: shoot fireballs
  dw $D913                                      ; $0DC549 | 1E: knockback after hit by egg
  dw $F1A9                                      ; $0DC54B | 1F: explode after final hit

; post-fight cutscene states
  dw $D617                                      ; $0DC54D | 20: fade into victory cutscene (no bowser)
  dw $F32A                                      ; $0DC54F | 21: baby bowser falling in frame
  dw $F358                                      ; $0DC551 | 22: flopping around on the ground
  dw $F360                                      ; $0DC553 | 23: cutscene with kamek
  dw $F383                                      ; $0DC555 | 24: unload baby bowser sprite
  dw $F4F7                                      ; $0DC557 | 25: prepare stork cutscene
  dw $F5B2                                      ; $0DC559 | 26: stork cutscene

Baron von Zeppelin w/ Egg Spawning

Balloons with eggs spawn in during the Final Bowser fight to allow Yoshi to harm Bowser. The first balloon immediately spawns once Bowser's state (address $701A2E) reaches $1B and $7E1070 >= $08, so after the initial intro sequence. Each time a new balloon spawns, the timer at address $701AF0 restarts to $0100 (256 frames, roughly 4.2 seconds). A new balloon shall not spawn until this timer hits $0000. Upon hitting $0000, there are some extra conditions checked before the next balloon spawns:

   cache                                     ; $09F757 |\
   ibt   r12,#$0018                          ; $09F758 | | begin loop of all sprites
   move  r13,r15                             ; $09F75A |/
   ldw   (r2)                                ; $09F75C |\
   lob                                       ; $09F75D | | if sprite's state is uninitialized
   beq .next_sprite                          ; $09F75E | | skip to next
   nop                                       ; $09F760 |/
   ldw   (r3)                                ; $09F761 |\
   sub   r5                                  ; $09F762 | | if sprite ID is balloon w/ bowser egg
   beq .return_flag_on                       ; $09F763 | | flag on return value and go to next
   add   r5                                  ; $09F765 |/
   sub   r6                                  ; $09F766 |\  if sprite ID is NOT bowser egg
   bne .next_sprite                          ; $09F767 | | skip to next
   nop                                       ; $09F769 |/
   ldw   (r4)                                ; $09F76A |\  if bowser egg's collision state
   sub   #0                                  ; $09F76B | | is anything but $00, meaning
   bne .next_sprite                          ; $09F76D | | tonguable/collidable with everything
   nop                                       ; $09F76F |/  then skip to next

 .return_flag_on
   inc   r1                                  ; $09F770 | return value flag on

To summarize, if there is currently no balloon sprite or egg sprite (unless the egg is being thrown), then we're good to spawn a new balloon. The return flag is r1, $0000 means we're good to spawn, anything else means do not spawn. This can be clearly seen after GSU returns:

 ; this routine checks to see if a new balloon w/ egg
 ; needs to be spawned and if so, spawns it
 spawn_balloon_egg:
   LDA $7A98,x                               ; $0DD8D3 |\ balloon timer not expired?
   BNE .ret                                  ; $0DD8D6 |/ skip balloon spawning
   LDX #$09                                  ; $0DD8D8 |\
   LDA #$F743                                ; $0DD8DA | | gsu_check_bowser_egg_spawn
   JSL $7EDE44                               ; $0DD8DD |/
   LDX $12                                   ; $0DD8E1 |
   LDA $3002                                 ; $0DD8E3 |\
   BNE .ret                                  ; $0DD8E6 | | spawn Baron von Zeppelin w/ bowser egg
   LDA #$00CD                                ; $0DD8E8 | | if GSU r1 flag returned 0
   JSL $03A34C                               ; $0DD8EB | |
   BCC .ret                                  ; $0DD8EF |/

Upon spawning, a 50/50 random dice roll is done to determine which side the balloon spawns on, left or right. If left, it spawns at camera X - 48 pixels, if right, camera X + 288 pixels, and Y is always $0770. The timer also restarts upon spawning:

   LDA $10                                   ; $0DD8F1 |\
   AND #$0002                                ; $0DD8F3 | | 50/50 random facing direction
   STA $7400,y                               ; $0DD8F6 | |
   TAX                                       ; $0DD8F9 |/
   LDA $0039                                 ; $0DD8FA |\
   CLC                                       ; $0DD8FD | | spawn at camera X + 288 (right)
   ADC $D8CF,x                               ; $0DD8FE | | or - 48 (left)
   STA $70E2,y                               ; $0DD901 |/
   LDA #$0770                                ; $0DD904 |\ exactly $0770 y position
   STA $7182,y                               ; $0DD907 |/
   LDX $12                                   ; $0DD90A |\
   LDA #$0100                                ; $0DD90C | | restart balloon timer
   STA $7A98,x                               ; $0DD90F |/  at 256 frames

 .ret
   RTS                                       ; $0DD912 |

This timer also gets cleared to $0000 during the second falling rock near the beginning, explicitly:

   STZ $7A98,x                               ; $0DDAD0 | clear balloon timer

This will be after the first balloon already spawned, meaning another one can spawn just as soon as you throw the first egg after the second rock, which is much earlier than the full 256 frames it normally has to wait.