Last active
August 29, 2015 14:13
-
-
Save Measter/f6ffeac26a05b61f6966 to your computer and use it in GitHub Desktop.
Extra-Crappy Birds for Easy68K
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*----------------------------------------------------------- | |
* 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