From 9ff2033e936689135210989a5fee057a4a13527e Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Thu, 13 Mar 2025 22:52:49 +0100 Subject: Add a title and a main screens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds the skeleton for having a title and a main screen. For now the title menu doesn't do much, as the selection is simply ignored, but at least it already knows how to cycle between these two states. Signed-off-by: Miquel Sabaté Solà --- src/assets.s | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/assets.s (limited to 'src/assets.s') diff --git a/src/assets.s b/src/assets.s new file mode 100644 index 0000000..8e839d3 --- /dev/null +++ b/src/assets.s @@ -0,0 +1,142 @@ +.segment "CODE" + +;; The game is so simple that it can fit in both nametables. This scope has all +;; the functions and data that initializes and resets all of them properly. +.scope Assets + ;; Initialize palettes and nametables. + .proc init + jsr init_palettes + + ;; Load the title screen on the first nametable. + lda #.lobyte(title_screen) + sta Globals::zp_arg0 + lda #.hibyte(title_screen) + sta Globals::zp_arg1 + ldx #$20 + jsr load_screen_x + + ;; Ensure that the title looks as expected. + jsr prepare_for_title_screen + + ;; Load the main screen on the second nametable. + lda #.lobyte(main_screen) + sta Globals::zp_arg0 + lda #.hibyte(main_screen) + sta Globals::zp_arg1 + ldx #$28 + jsr load_screen_x + + rts + .endproc + + ;; Load the 1KB worth of screen data located via the 16-bit pointer on + ;; Globals::zp_arg{0,1}. Set the `x` register to the high byte of the + ;; nametable to be used. + .proc load_screen_x + bit PPU::STATUS + + stx PPU::ADDRESS + lda #$00 + sta PPU::ADDRESS + + ldy #0 + ldx #4 + @loop: + lda (Globals::zp_arg0), y + sta PPU::DATA + iny + bne @loop + + dex + beq @end + + inc Globals::zp_arg1 + jmp @loop + + @end: + rts + .endproc + + ;; Performs all the needed tricks in order to get the first nametable as + ;; expected. + .proc prepare_for_title_screen + bit PPU::STATUS + + lda #$23 + sta $2006 + lda #$C8 + sta $2006 + + ldx #$10 + @upper_title_bar_loop: + lda #%10101010 + sta $2007 + dex + bne @upper_title_bar_loop + + ;; TODO: store back palettes after game over. + + rts + .endproc + + ;; Performs all the needed tricks in order to get the second nametable as + ;; expected. + .proc prepare_for_main_screen + ;; TODO: second palette for background should be: + ;; .byte $0F, $14, $2C, $28 + ;; + ;; TODO: first palette for the foreground should be: + ;; .byte $0F, $16, $10, $30 + rts + .endproc + + ;; Copies all the palettes for our game into the proper PPU address. + .proc init_palettes + lda #$3F + sta PPU::ADDRESS + lda #$00 + sta PPU::ADDRESS + + ldx #0 + @load_palettes_loop: + lda palettes, x + sta PPU::DATA + inx + cpx #$20 + bne @load_palettes_loop + rts + palettes: + ;; Background + ;; 0: score + .byte $0F, $30, $2C, $28 + ;; 1: floating platforms + .byte $0F, $2C, $30, $2A + ;; 2: ground + .byte $0F, $28, $2C, $16 + ;; 3: ship + .byte $0F, $16, $30, $00 + + ;; TODO: fuel tank needs color $24 + ;; Foreground + ;; 0: player & ship + .byte $0F, $30, $10, $30 + ;; 1: enemy 1 & bonuses + .byte $0F, $16, $2C, $2A + ;; 2: enemy 2, fuel & bonuses + .byte $0F, $16, $14, $28 + ;; 3: SUSE easter egg + .byte $0F, $16, $00, $2B + .endproc + + ;; Having 2KB for screen data is quite wasteful, but since it's such a + ;; simple game, I have so much space left in the cartridge that I can go + ;; bananas with it. This helps out loading the screen as we can go faster + ;; and it is less error prone. + title_screen: + .incbin "../assets/title.nam" + main_screen: + .incbin "../assets/main.nam" +.endscope + +.segment "CHARS" + .incbin "../assets/jetpac.chr" -- cgit v1.2.3