pong-more-or-less/main.asm

246 lines
4.2 KiB
NASM

;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.include "c64.inc"
.include "enum.asm"
VMBASE = $0400
.org PROGSTART
.include "init.asm" ;must come first
.include "utilities.asm"
;; Start screen, waits for space key to be pressed.
titlescreen:
;; More visually interesting sprite positioning for
;; the title screen. Overrides default from init.
lda #$82
sta SPRITE_0Y
ldx #%01111111
ldy #%00010000
jsr keydown
bne @dontstart
;; Start the game here.
jsr loadgamefield ;set the background
lda #mode::MainGame ;don't forget that #
sta gamemode ;set the game mode to MainGame
@dontstart:
rts
;; Wait and highlight the score change for half a second.
;; Happens every time a player scores or whatever it's called in tennis
scorewait:
;; While waiting we play a buzz
lda #$0f
sta SIDFMV
lda #$08
sta SIDAD1
lda #$68
sta SIDSR1
lda #$45
sta SIDF1L
lda #$1d
sta SIDF1H
lda #$11
sta SIDCR1
dec timer
bne @dontresume
;; Reset gamemode
lda #mode::MainGame
sta gamemode
;; Reset background color
lda #0
sta BGCOL0
;; Stop sound
lda #$10
sta SIDCR1
@dontresume:
rts
;; Call after a player scores to highlight the win
highlightscore:
lda #mode::ScoreHighlight
sta gamemode
lda #25
sta timer
lda #2
sta BGCOL0
rts
.include "gameloop.asm"
;; "Victory" mode when 100 points has been reached.
win:
dec timer
bne @skip
dec timer2
bne @continue
;; After five seconds (10 half-seconds) we reset the game
jmp PROGSTART
@continue:
lda #25
sta timer
lda BGCOL0
eor #8
sta BGCOL0
@skip:
rts
winstop:
lda #25
sta timer
lda #10
sta timer2
lda #$0d
sta BGCOL0
lda #mode::Win ;DO NOT FORGET THE #
sta gamemode
rts
ball_x_inc:
inc ball_x
bne @done
;; If ball_x incremented to zero we have either looped around
;; the screen (shouldn't happen) or crossed the bit 8 boundry.
;; So we set the MSB to one, since we're going right.
lda #%00000100
ora SPRITE_X_MSB
sta SPRITE_X_MSB
@done:
rts
ball_x_dec:
dec ball_x
lda ball_x
cmp #$ff
bne @done
;; If ball_x incremented to zero we have either looped around
;; the screen (shouldn't happen) or crossed the bit 8 boundry.
;; So we set the MSB to one, since we're going right.
lda #%11111011
and SPRITE_X_MSB
sta SPRITE_X_MSB
@done:
rts
ball_bounce_vert:
jsr color_change
lda #%10000000
eor balldata
sta balldata
rts
ball_bounce_hori:
jsr color_change
lda #%01000000
eor balldata
sta balldata
rts
reset_ball:
jsr ball_bounce_hori
lda #$90
sta ball_y
lda #$c0
sta ball_x
lda #%11111011
and SPRITE_X_MSB
sta SPRITE_X_MSB
rts
color_change:
inc bordercol
lda bordercol
and #$0f
cmp #2
bcs @fine
lda #2
sta bordercol
@fine:
lda bordercol
sta BORDER
rts
handle_collision:
jsr ball_bounce_hori ;obvious, flip the ball's horizontal direction
lda #$00
sta col ;clear the collision flag
rts
;; Cheap trick to make a hexprinted number look decimal.
;; Score comes in the A register, clamped score returned in A
clampscore:
tax
and #%00001111
cmp #$0a
bcc @noclamplower
;; yes clamp, inc upper nybble, ex. $19 -> $20
txa
and #%11110000
clc
adc #$10
tax
@noclamplower:
txa
and #%11110000
cmp #$a0
bcc @noclamp
;; over 99? just stop at that point, we'll flash some colors then reset
jsr winstop
pla
pla
@noclamp:
txa
rts
modedispatch:
jsr jumpwithtable
.addr titlescreen
.addr game ;normal gameplay
.addr scorewait
.addr win
;; Main IRQ subroutine. CPU gets sent here by the interrupts from the
;; VIC-II's raster and collision interrupts, and is responsible for
;; calling everything else. Since the game is interrupt-driven, you
;; could add a RTS to the init code and have the game run together
;; with BASIC. Would be pretty stupid but you *can* do it. That does
;; give me an idea though...
irq:
lda SSCOL ;need to do this for collision checking to work
lda #%00000100 ;check if irq is for collision or not
and VICINT
beq @nocol
;; Collision
sta col ;set the collision flag
lda #$7f
and VICINT
sta VICINT
jmp @skipgame
@nocol:
lda gamemode
jsr modedispatch
@skipgame:
lda #$7f
and VICINT
sta VICINT
jmp $ea31
.include "variables.asm"
BALLVERT = %10000000
BALLHORI = %01000000
BALLVSPEED = %00000010
BALLHSPEED = %00000001
.include "graphics.asm"
.include "zeropage.asm"