diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/assets.s | 2 | ||||
| -rw-r--r-- | src/driver.s | 8 | ||||
| -rw-r--r-- | src/items.s | 110 | ||||
| -rw-r--r-- | src/jetpac.s | 1 | ||||
| -rw-r--r-- | src/over.s | 58 |
5 files changed, 150 insertions, 29 deletions
diff --git a/src/assets.s b/src/assets.s index cfcddbf..26f6546 100644 --- a/src/assets.s +++ b/src/assets.s @@ -180,7 +180,7 @@ ;; 2: enemy 2, fuel & bonuses .byte $0F, $16, $24, $28 ;; 3: SUSE easter egg - .byte $0F, $16, $10, $2B + .byte $0F, $16, $1B, $2B .endproc ;; Having 2KB for screen data is quite wasteful, but since it's such a diff --git a/src/driver.s b/src/driver.s index e1c2eb7..bfa6294 100644 --- a/src/driver.s +++ b/src/driver.s @@ -323,12 +323,16 @@ and #%00000110 bne @reset_timer - ;; No! Toggle the game over bit. - ;; TODO: missing the coin game over. + ;; No! Set the game over bit (with or without coin). lda Globals::zp_flags ora #%00000010 sta Globals::zp_flags + lda Items::zp_state + and #$04 + beq @invalidate_items + inc Globals::zp_flags + @invalidate_items: ;; Invalidate items, which were skipped on move_sprites_out() on purpose ;; to keep them after each death. But since we are about to go to the ;; title screen, now they are no longer useful. diff --git a/src/items.s b/src/items.s index 731756d..de0a28e 100644 --- a/src/items.s +++ b/src/items.s @@ -44,7 +44,7 @@ ;; |- F: falling. ;; |- D: dropping: together with 'falling', but the player cannot re-grab it. ;; |- C: 1: collectable (i.e. disappears on collision); 0: part (i.e. follows the player) - ;; |- K: object kind (00: high shuttle; 01: mid shuttle; 10: fuel; 11: regular item; 100: coin) + ;; |- K: object kind (000: high shuttle; 001: mid shuttle; 010: fuel; 011: regular item; 100: coin) ;; ;; 2. Y coordinate. ;; 3. X coordinate. @@ -72,11 +72,12 @@ ;; Bitmap which holds different boolean values for the state of items in ;; general. ;; - ;; |GNS- --FF| + ;; |GNS- -CFF| ;; | ;; |- G: the player is Grabbing an item ;; |- N: a fuel tank is Needed. ;; |- S: there is a fuel tank on Screen. + ;; |- C: SUSE's Coin has been collected. ;; |- F: number of Falling items. zp_state = $CA @@ -128,7 +129,9 @@ lda Globals::zp_level_kind bne @other_screens - lda #0 + ;; Zero out the state except for the 'C' bit. + lda Items::zp_state + and #$04 sta Items::zp_state ;; We haven't collected anything yet, but it's convenient for us to mock @@ -179,13 +182,16 @@ ;; Palettes. lda #0 - sta Items::zp_current_tiles + 6, x + sta Items::zp_current_tiles + 5, x - beq @invalidate_third + beq @coin_or_invalidate_third @other_screens: - ;; Fuel tanks are needed, that's all. - lda #%01000000 + ;; Zero out the state except for the 'C' bit. The 'N' bit needs to be + ;; set always. + lda Items::zp_state + and #$04 + ora #$40 sta Items::zp_state ;; Shuttle parts are counted as "collected". This makes the @@ -197,6 +203,46 @@ lda #$FF sta Items::zp_pool_base, x sta Items::zp_pool_base + 3, x + bne @invalidate_third + + @coin_or_invalidate_third: + ;; If we have finished the game once, and we have not collected the + ;; SUSE's coin yet, let it be. + lda Globals::zp_level + cmp #8 + bne @invalidate_third + lda Items::zp_state + and #$04 + bne @invalidate_third + + ;; SUSE's coin will fall from the sky. Hence, compute this new item as a + ;; falling one. + inc Items::zp_state + + ;; SUSE's coin can be Collected, is identified by the '100' kind, and is + ;; in a Falling state. + lda #%01001100 + sta Items::zp_pool_base + 6, x + + ;; Falling from the sky at the right platform. + lda #Background::UPPER_MARGIN_Y_COORD + sta Items::zp_pool_base + 7, x + lsr + lsr + lsr + sta Items::zp_current_tiles + 6, x + lda #$D0 + sta Items::zp_pool_base + 8, x + lsr + lsr + lsr + sta Items::zp_current_tiles + 7, x + + ;; Default palette, the tile ID is simply ignored. + lda #0 + sta Items::zp_current_tiles + 8, x + + rts @invalidate_third: ;; Always invalidate the third item. @@ -248,26 +294,23 @@ cmp #$01 bne @do_fuel_or_regular lda #$06 - bne @no_attributes + beq @do_fuel_or_regular + + @no_attributes: + sta Globals::zp_arg0 + lda #0 + sta Globals::zp_arg1 + JAL allocate_metasprite_x_y @do_fuel_or_regular: - ;; Is it a fuel tank? + ;; Switch statement for the kind of item (regular, fuel, coin). lda Items::zp_pool_base, x - and #$03 + and #$07 cmp #2 - bne @regular + beq @fuel cmp #4 beq @coin - ;; Then just pick the tile from the fuel tank and pick the right - ;; palette. - lda #$0C - sta Globals::zp_arg0 - lda #2 - sta Globals::zp_arg1 - JAL allocate_metasprite_x_y - - @regular: ;; This is a regular item lda Items::zp_current_tiles + 2, x lsr @@ -284,12 +327,19 @@ sta Globals::zp_arg0 JAL allocate_metasprite_x_y + @fuel: + ;; Then just pick the tile from the fuel tank and pick the right + ;; palette. + lda #$0C + sta Globals::zp_arg0 + lda #2 + sta Globals::zp_arg1 + JAL allocate_metasprite_x_y + @coin: lda #$0A - - @no_attributes: sta Globals::zp_arg0 - lda #0 + lda #3 sta Globals::zp_arg1 JAL allocate_metasprite_x_y @@ -709,8 +759,6 @@ ;; We start by generating a new state. If the state is asking for a fuel ;; tank, let it be. Otherwise it will be a regular item. - ;; - ;; TODO: coin support. lda Items::zp_state and #$40 beq @regular @@ -862,6 +910,18 @@ .proc collect ldx Items::zp_pool_index + ;; Are we collecting the one and only SUSE coin?! + lda Items::zp_pool_base, x + and #$07 + cmp #4 + bne @check_fall + + ;; Hell, yeah! + lda Items::zp_state + ora #$04 + sta Items::zp_state + + @check_fall: ;; If the collected item was actually falling down, decrease the number ;; of falling items. lda Items::zp_pool_base, x diff --git a/src/jetpac.s b/src/jetpac.s index 2d397ac..f6a53a9 100644 --- a/src/jetpac.s +++ b/src/jetpac.s @@ -129,6 +129,7 @@ sta Joypad::zp_buttons sta Joypad::zp_prev sta Player::zp_state + sta Items::zp_state ;; Initialize the level. We allow the build system to pass its own value for ;; this in `LEVEL`, just in case we want to debug the enemy of a specific @@ -67,9 +67,16 @@ @do_render: jsr Over::clear_out_screen - ;; TODO: coin game over. + lda Globals::zp_flags + and #$03 + cmp #2 + beq @regular + jsr Over::render_coin_game_over + jmp @next + @regular: jsr Over::render_regular_game_over + @next: ;; Enable back the PPU (only background). lda #%00001110 sta PPU::zp_mask @@ -234,4 +241,53 @@ ;; "OVER" .byte $29, $30, $1F, $2C, $FF .endproc + + ;; Render the "Game over" in the case the player has collected SUSE's coin. + ;; TODO: see how much it can be merged + ;; TODO: not centered nor fully realized. + .proc render_coin_game_over + ;; Set the position. + bit PPU::m_status + ldx #$29 + stx PPU::m_address + ldx #$6C + stx PPU::m_address + + ;; And just iterate over the "message" until we reach the end of string + ;; $FF character. + ldx #0 + @message_loop: + lda message, x + cmp #$FF + beq @out + sta PPU::m_data + inx + bne @message_loop + + @out: + ;; Reset attributes for the end of the message. + bit PPU::m_status + ldx #$2B + stx PPU::m_address + ldx #$D5 + stx PPU::m_address + lda #0 + sta PPU::m_data + sta PPU::m_data + sta PPU::m_data + + rts + + message: + ;; "YOU " + .byte $33, $29, $2F, $00 + ;; "ARE " + .byte $1B, $2C, $1F, $00 + ;; "A " + .byte $1B, $00 + ;; "SUPER " + .byte $2D, $2F, $2A, $1F, $2C, $00 + ;; "PLAYER!" TODO + .byte $2A, $26, $1B, $33, $1F, $2C, $FF + .endproc .endscope |
