Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extra-Crappy Birds for Easy68K
*-----------------------------------------------------------
* Title : Less-Extra-Crappy Birds
* Description: A port of the JS version found at
* https://www.ktbyte.com/java-tutorial/game-walkthroughs
*
* Revisions : 1.0 Release
* : 1.1 Pretty Pipes
* Evened out wall distances.
* Pretty Bird.
* Better "Colours".
*-----------------------------------------------------------
ORG $1000
Width EQU 642
Height EQU 800
HalfWidth EQU Width/2
HalfHeight EQU Height/2
WallGapHeight EQU 100
WallWidth EQU 62
PlayerSize EQU 24
PlayerHeadWidth EQU 10
PlayerHeadHeight EQU 8
PlayerBeakWidth EQU 14
PlayerBeakHeight EQU 3
PlayerTailWidth EQU 16
PlayerTailHeight EQU 4
PlayerFastUp EQU -6
PlayerUp EQU -3
PlayerDown EQU 3
PlayerFastDown EQU 6
PipeCapHeight EQU 28
PipeCapLeftWidth EQU 32
PipeCapRightWidth EQU 31
PipeLeftWidth EQU 21
PipeRightWidth EQU 26
*------------------------
* Subroutines
flipBuffer MACRO
move.l #94, d0
trap #15
ENDM
clearScreen MACRO
move.l #0, d1
move.l #0, d2
move.l #Width, d3
move.l #Height, d4
move.l #87, d0
trap #15
ENDM
blackFill MACRO
move.l #0,d1
move.l #81, d0
trap #15
move #80, d0
trap #15
ENDM
whiteFill MACRO
move.l #$e6e6e6,d1
move.l #81, d0
trap #15
move #80, d0
trap #15
ENDM
lightGreyFill MACRO
move.l #$bfbfbf, d1
move.l #81, d0
trap #15
move #80, d0
trap #15
ENDM
darkGreyFill MACRO
move.l #$8b8b8b, d1
move.l #81, d0
trap #15
move #80, d0
trap #15
ENDM
drawTopPipe MACRO
; Pipe
whiteFill
; First rectangle
move.w \1, d1
add.w #8, d1 ; X1
move.w d1, d3
add.w #PipeLeftWidth, d3 ; X2
move.w #0, d2 ; Y1
move.w \2, d4
sub.w #WallGapHeight, d4 ; Y2
move.w #87, d0 ; Rectangle mode
trap #15
lightGreyFill
; Second Rectangle
move.w d3, d1
add.w #1, d1 ; X1
add.w #PipeRightWidth, d3 ; X2
move.w #87, d0 ; Rectangle mode
trap #15
; Cap
whiteFill
; First Rectangle
move.w \1, d1 ; X1
move.w d1, d3
add.w #PipeCapLeftWidth, d3 ; X2
move.w d4, d2
sub.w #PipeCapHeight, d2 ; Y1
move.w #87, d0 ; Rectangle mode
trap #15
lightGreyFill
; Second Rectangle
move.w d3, d1
add.w #1, d1 ; X1
add.w #PipeCapRightWidth, d3 ; X2
move.w #87, d0 ; Rectangle mode
trap #15
ENDM
drawBottomPipe MACRO
; Pipe
whiteFill
; First rectangle
move.w \1, d1
add.w #8, d1 ; X1
move.w d1, d3
add.w #PipeLeftWidth, d3 ; X2
move.w \2, d2
add.w #WallGapHeight, d2 ; Y1
move.w #Height, d4 ; Y2
move.w #87, d0 ; Rectangle mode
trap #15
lightGreyFill
; Cap Shadow
move.w \1, d1
add.w #8, d1 ; X1
move.w \2, d4
add.w #WallGapHeight+PipeCapHeight+5, d4 ; Y2
move.w #87, d0 ; Rectangle mode
trap #15
; Reset Y2
move.w #Height, d4
; Second Rectangle
move.w d3, d1
add.w #1, d1 ; X1
add.w #PipeRightWidth, d3 ; X2
move.w #87, d0 ; Rectangle mode
trap #15
darkGreyFill
; Cap Shadow
move.w \1, d1
add.w #8+PipeLeftWidth+1, d1 ; X1
move.w \2, d4
add.w #WallGapHeight+PipeCapHeight+5, d4 ; Y2
move.w #87, d0 ; Rectangle mode
trap #15
; Cap
whiteFill
; First Rectangle
move.w \1, d1 ; X1
move.w d1, d3
add.w #PipeCapLeftWidth, d3 ; X2
move.w d2, d4
add.w #PipeCapHeight, d4 ; Y2
move.w #87, d0 ; Rectangle mode
trap #15
lightGreyFill
; Second Rectangle
move.w d3, d1
add.w #1, d1 ; X1
add.w #PipeCapRightWidth, d3 ; X2
move.w #87, d0 ; Rectangle mode
trap #15
ENDM
buttonPress:
move.l #-17, d7
IF.b (a0) <EQ> #1 THEN.s
move.l #HalfHeight, d6
move.b #0, (a0)
move.b #0, (a2)
move.w #Width, 0(a4)
move.w #Width+HalfWidth+WallWidth, 2(a4)
move.w #HalfHeight, 0(a5)
move.w #600, 2(a5)
ENDI
rte
* Pre:
* D1 = Byte Value.
* A1 = Buffer.
itoa:
divu #10, d1
move.l d1, d2
swap d2
add.b #'0', d2
move.b d2, 2(a1)
and.l #$FF, d1
divu #10, d1
move.l d1, d2
swap d2
add.b #'0',d2
move.b d2, 1(a1)
and.l #$FF, d1
divu #10, d1
add.b #'0',d1
move.b d1, 0(a1)
rts
* Pre:
* A6 = Address to seed.
* Post:
* D1 = Random value.
rand:
move.l (a6),d1
move.l #$AF-$100, d3
move.l #18, d2
Ninc0:
lsl.l #1,d1
bcc.s Ninc1
eor.b d3, d1
Ninc1:
dbf d2, Ninc0
move.l d1,(a6)
rts
* Post:
* D1 = Random value.
randRange MACRO
jsr rand
; We know we won't need more than 400, so clear the lower half and swap
move.w #0, d1
swap d1
divu #\2-\1, d1
move.w #0, d1
swap d1
add.l #\1, d1
ENDM
*------------------------
* Put program code here
setup: ; first instruction of program
; Set resolution to 642x800.
move.l #33, d0
move.l #Width<<16+Height, d1
trap #15
; Enable double buffer.
move.l #92, d0
move.l #17, d1
trap #15
; Load addresses.
lea gameState, a0
lea score, a2
lea highScore, a3
lea wx, a4
lea wy, a5
lea seed, a6
; Set level 7 interrupt vector.
lea buttonPress, a1
move.l a1, $7C
; Enable keyboard IRQ.
move.l #62, d0
move.l #$701,d1
trap #15
; Set seed
move.l #8,d0
trap #15
move.l d1, (a6)
reset:
blackFill
clearScreen
; Setup variables.
move.b #1, (a0) ; Game state
move.l #0, d6 ; y
move.l #0, d7 ; vy
; Draw title text
move.l #95, d0
lea titleText, a1
move.l #247, d1
move.l #377, d2
trap #15
lea titleText2, a1
move.l #243, d1
move.l #410, d2
trap #15
lea highScoreText, a1
move.l #5, d1
move.l #5, d2
trap #15
; Convert int to string.
move.b (a3), d1
lea scoreBuffer, a1
jsr itoa
;Output string.
move.l #101, d1
move.l #5, d2
trap #15
flipBuffer
* D6 = y
* D7 = vy
* A0 = gamestate
* A2 = score
* A3 = highScore
* A4 = wx
* A5 = wy
mainLoop:
; Get hundredths of a second since midnight.
move.l #8,d0
trap #15
lea tStamp, a1
move.l d1, (a1)
IF.b (a0) <EQ> #1 THEN.s
jmp nextLoop
ENDI
clearScreen
; Update Player
add.l #1, d7
add.l d7, d6
; Update and draw the pipes.
; Unroll the loop from the JS version.
drawTopPipe 0(a4), 0(a5)
drawBottomPipe 0(a4), 0(a5)
; Update wall 1
sub.w #6, 0(a4)
IF.w 0(a4) <LT> #0-WallWidth THEN.s
move.w #Width+WallWidth, 0(a4)
randRange 200, height-200
move.w d1, 0(a5)
ENDI
; Update Score
move.l #0, d1
move.b (a2), d1
IF.w 0(a4) <LT> #HalfWidth AND.w 0(a4) <GT> #HalfWidth-6 THEN.s
add.b #1, d1
move.b d1, (a2)
move.l #0, d2
move.b (a3), d2
IF.b d1 <HI> d2 THEN.s
move.b d1, (a3)
ENDI
ENDI
drawTopPipe 2(a4), 2(a5)
drawBottomPipe 2(a4), 2(a5)
; Update wall 2
sub.w #6, 2(a4)
IF.w 2(a4) <LT> #0-WallWidth THEN.s
move.w #Width+WallWidth, 2(a4)
randRange 200, height-200
move.w d1, 2(a5)
ENDI
; Update Score
move.l #0, d1
move.b (a2), d1
IF.w 2(a4) <LT> #HalfWidth AND.w 2(a4) <GT> #HalfWidth-6 THEN.s
add.b #1, d1
move.b d1, (a2)
move.l #0, d2
move.b (a3), d2
IF.b d1 <HI> d2 THEN.s
move.b d1, (a3)
ENDI
ENDI
; Out of bounds check.
IF.w D6 <GT> #Height OR.w D6 <LT> #0 THEN.s
move.b #1, (a0)
jmp reset
ENDI
; Collision Check
; First
move.w 0(a4), d1 ; Wall left
move.w d1, d2 ; Wall right
add.w #WallWidth, d2
move.l #HalfWidth-(PlayerSize/2), d3 ; Player left
move.l d3,d4
add.w #PlayerSize, d4 ; Player right
; Has overlap
IF.w d4 <GT> d1 AND.w d3 <LT> d2 THEN.s
move.w 0(a5), d1
move.w d1, d2
sub.w #WallGapHeight, d1 ; Gap top
add.w #WallGapHeight, d2 ; Gap bottom
move.l d6, d3 ; Player top
move.l d6, d4
add.w #PlayerSize/2, d4 ; Player Bottom
IF.w d3 <LT> d1 OR.w d4 <GT> d2 THEN.s
* Collision
move.b #1, (a0)
jmp reset
ENDI
ENDI
; Collision Check
; second
move.w 2(a4), d1 ; Wall left
move.w d1, d2 ; Wall right
add.w #WallWidth, d2
move.l #HalfWidth-(PlayerSize/2), d3 ; Player left
move.l d3,d4
add.w #PlayerSize, d4 ; Player right
; Has overlap
IF.w d4 <GT> d1 AND.w d3 <LT> d2 THEN.s
move.w 2(a5), d1
move.w d1, d2
sub.w #WallGapHeight, d1 ; Gap top
add.w #WallGapHeight, d2 ; Gap bottom
move.l d6, d3 ; Player top
move.l d6, d4
add.w #PlayerSize/2, d4 ; Player Bottom
IF.w d3 <LT> d1 OR.w d4 <GT> d2 THEN.s
* Collision
move.b #1, (a0)
jmp reset
ENDI
ENDI
; Draw Player
darkGreyFill
move.l #87, d0 ; Rectangle Mode
move.l #HalfWidth-(PlayerSize/2),d1 ; X1
move.l d6,d2 ; Y1
move.l d1,d3
add.l #PlayerSize,d3 ; X2
move.l d2,d4
add.l #PlayerSize,d4 ; Y2
trap #15
; Calculate Head/Tail offset
IF.w d7 <LT> #-9 THEN.s
move.l #PlayerFastUp, d5
jmp drawHead
ENDI
IF.w d7 <LT> #-3 THEN.s
move.l #PlayerUp, d5
jmp drawHead
ENDI
IF.W d7 <GT> #3 THEN.s
move.l #PlayerDown, d5
jmp drawHead
ENDI
if.w d7 <GT> #9 THEN.s
move.l #PlayerFastDown, d5
jmp drawHead
ENDI
move.l #0, d5
drawHead:
whiteFill
; Draw Head
move.l #87, d0 ; Rectangle Mode
move.l #HalfWidth+(PlayerSize/2)-4, d1 ; X1
move.l d1, d3
add.l #PlayerHeadWidth, d3 ; X2
move.l d6, d2
add.l d5, d2
add.l #8, d2 ; Y1
move.l d2, d4
add.l #PlayerHeadHeight, d4 ; Y2
trap #15
; Draw Beak
add.l #5, d2 ; Y1
add.l #PlayerBeakWidth-PlayerHeadWidth, d3 ; X2
trap #15
; Draw Tail
move.l #(HalfWidth-(PlayerSize/2))-(PlayerTailWidth-5), d1 ; X1
move.l d6, d2
add.l #11, d2
sub.l d5, d2 ; Y1
move.l d1, d3
add.l #PlayerTailWidth, d3 ; X2
move.l d2, d4
add.l #PlayerTailHeight, d4 ; Y2
trap #15
; Draw Score
blackFill
move.l #95, d0
lea scoreText, a1
move.l #5, d1
move.l #5, d2
trap #15
move.b (a2), d1
lea scoreBuffer, a1
jsr itoa
move.l #61, d1
move.l #5, d2
trap #15
nextLoop:
flipBuffer
; Now wait untill two-hundredths of a second have passed.
lea tStamp, a1
move.l (a1), d3 ; D3 = Time at frame start.
move.l #8, d0
move.l #0, d1
WHILE.l d1 <LO> #2 DO.s
trap #15
sub.l d3,d1
ENDW
jmp mainLoop
SIMHALT ; halt simulator
*------------------------
* Put variables and constants here
gameState: dc.b 0
score: dc.b 0
highScore: dc.b 0
wx: ds.w 2
wy: ds.w 2
tStamp: dc.l 0
seed: dc.l 0
scoreBuffer dc.l 0
titleText: dc.b 'Extra-Crappy Birds',0
titleText2: dc.b 'Press Space to jump',0
highScoreText: dc.b 'High Score: ',0
scoreText: dc.b 'Score: ',0
END setup ; last line of source
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.