Boss Closer - brunovalads/yoshisisland-disassembly GitHub Wiki

The boss closer sprite is a sprite spawned by Salvo, Naval and Hookbill which locks Yoshi into the arena, either by creating a wall (Salvo), moving the ground upwards (Naval) or destroying the ground behind Yoshi (Hookbill). It also sets the arena borders. It is not naturally placed but spawned from these bosses. The wall closer is split into 8 different states, each containing a varying amount of values $7960,x

States

The table for the states starts from $01A259 and is indexed by $7978,x (shorted as $18,x in the code). Each state can have got up to different 5 words, stored into sprite tables $79D6,x, $7A96,x, $79D8,x, $7A36,x and $7A38,x. $79D6,x and $7A96,x have got a predermined function, namely next state and state timer, respectively (some states set $7A96,x to 0xFFFF so the state runs quasi "indefinitively") but $79D8,x, $7A36,x and $7A38,x have got no predetermined function (they are named as wildcards 1 - 3).

State 0 - Wait (3 words)

This one does nothing except wasting for a set amount of frames. It also stores wildcard 1 into $617A and $617C (TODO: Find out what these addresses do).

State 1 - Set Camera (3 words)

This state moves the camera so that Yoshi's X position relative to the screen is set to the value set in wildcard 1. This might be a weird implementation but keep in mind that this state is solely used for Hookbill whose battle takes place on a seemingly endless stone platform and he doesn't appear until the fog clears out which happens after some time, not from a fixed position. It can move in both ways depending on whether Yoshi's position to the camera is bigger or smaller than wildcard 1.

State 2 - Set Camera 2 (5 words)

Unlike state 1, this state moves the camera to a fixed X position. Wildcard 1 is the scroll rate, wildcard 2 is the final camera X position and wildcard 3 is the direction the camera moves ($0001 is the right direction and $FFFF is the left direction). The rate of change should be thought as a hexadecimal fraction because the game only moves the camera if the sum of wildcard 1 + the previous sum ($7900,x) is bigger than 0x0100 (this result is subtracted by 0x0100 and then stored $7900,x) but it won't move otherwise. Interestingly, the scroll rate can be larger than 0x0100, in which the game loops and moves the camera for so long until the value becomes smaller 0x0100 (this is why wildcard 3 should be either $0001 or $FFFF). It also can be set to scroll to the left even if the original game never makes use of that too.

State 3 - Set Screen Borders (4 words)

This state is pretty simple: It sets borders where the camera can scroll (set from wildcards 1 and 2).

State 4 - Destroy Sprite (2 words)

This one has got the least amount of words to use because the outcome is always the same: It removes the wall closer, marking this the end of the sprite. Interestingly, there exists another remove, one which sets

State 5 - Salvo Closer (5 words)

Salvo's wall closer spawns a brick wall to close the arena. Wildcard 1 is the initial X position where the block spawns, wildcard 2 the initial Y position and wildcard 3 the initial block to place (though by default, this should be realistically $0000 or $0003). Wildcard 3 is the index for the block to spawn which means it indexes five different tables. The table at $01A3B2 contains the timer until the next block is placed, $01A3BC is the currently placed Map16 tile, $01A3C6 is the X offset for the next block, $01A3D0 is the Y offset for the next block and $01A3DA is whether to spawn a smoke ($0001) or not ($0000). The block's index is incremented by 2 and if that value is bigger than 10 (5 different blocks), the counter resets. Especially $01A3DA and the fact that there are five blocks to spawn might seem weird but the games spawns for the 32x16 brick at first a 16x16 brick before connecting it with the second tile. This also explains why the amount of frames isn't fixed to 0x20 frames but one block set the timer to 0x00 and another one to 0x1F frames.

The closer stops until the next block is on a specific Y position (exact value is in $01A42C, set to 0x01A0 in the original game).

State 6 - Naval Closer (5 words)

Naval's closer raises the wall to close this arena unlike Salvo's. This also means, the code works differently. Like in Salvo's closer, wildcard 1 and 2 function as the initial positions but wildcard 3 is the loop count, how often the wall "moves" until it stops. It also features only one table, $01A478, all of them contain the wall's Map16 tiles. The table works is indexed a bit differently. Most notably, the wall doesn't actually move but multiple blocks replace the old blocks and the amount of blocks is dependent on the value in wildcard 3. More specifically, the game subtracts a constant (in this case 0x0006) by the value in wildcard 3 and multiply it by 4 (because the Map16 number is 16-bit and there are two block per row). It also adds 0x0008 (two blocks) because of two additional rows which translates into this code: LDA #$0006 SEC : SBC $7A38,x ASL #2 CLC : ADC #$0008 The value is stored twice into scratch RAM. One ($00) function as the loop counter or blocks to place times 2 whereas the other one ($02) function as the total amount of blocks to place times 2. This is done so to determine the current Map16 tile by taking the difference between $02 and $00: LDA $02 SEC : SBC $00 TAY Depending on whether bit 1 of $00 is set or not, the game moves places the next block to the right (bit 2 is clear) or reset the X position and place the next block to the bottom (bit 2 is set). This is done so often until $00 is zero.

Once all blocks have been placed, the game moves the first block's Y position upwards by one block it also decreases $7A38,x and if that value becomes zero, the game loads the next (this is why the constant is 6 instead of 5 because the code never executes if $7A38,x is zero).

State 7 - Hookbill Closer (3 words)

This one is the most unique closer. Hookbill only appears after the fog clears which happens on a timer, not from a fixed position. As such, it is the only Boss "Closer" which uses the camera's position to determine which stone block to destroy (that is the stone block which touches the left screen border). It also initialises wildcard 1 to 0x0000 which tells to the game to initialise the position. LDA $78,x BNE .skip LDA #$0003 STA $7900,x LDA $0039 STA $78,x LDA $003B CLC : ADC #$00B0 STA $7A36,x .skip Other then that, Hookbill's Closer is very straightforeward: It destroys three stone blocks in a delayed manner and spawns a smoke on the destroyed block.