; ================›; = Air Hockey =›; = by =›; = Chris Page =›; ================››; Copyright (c) 1985 ANALOG Computing››; Special Thanks to:›; David Sullivan & David Becker››DEFINE› OPTION="3",SELECT="5",START="6",› NONE="7",LEFT="96",RIGHT="60",› TOP="56",BOT="144"››BYTE› NINDEX,VOLUME,FRICTION=[1],› BOUNCE=[90],WIN=[10],PLAYERS=[2],› HUE,LUM,OPT,PUCKXD,PUCKYD,HITFLAG,› SERVER,GAMEOVER,SERVEIT,SDMCTL=559,› CONSOL=53279,CHACT=755,WSYNC=54282,› VCOUNT=54283,CRSINH=752,› COLOR0=53270,COLOR1=53271,› COLOR2=53272,COLOR3=53273,› COLOR4=53274,RTCLOK=20,› DMACTL=54272,LMARGN=82,RMARGN=83,› CHBAS=756,PMBASE=54279,› HITCLR=53278,P2PL=53262,› GRACTL=53277,GPRIOR=623,› RANDOM=53770,COLPM0=53266,› COLPM1=53267,CH=764,RAMTOP=106,› AUDCTL=53768,ATRACT=77,KEY››BYTE ARRAY› DLIST,SCRMEM,RAMFONT,PMMEM($800),› BAR(0)=[$FF$FF],› PUCK(0)=[$60$F0$F0$F0$F0$F0$F0$60],› TTOP(0)=['Q'R'R'R'R'R'R'Ó'Ó'Ó'Ó'R› 'R'R'R'R'R'E],› TMID(0)=['R'T'T'T'T'T'T'T'T'T'T'T› 'T'T'T'T'T'R],› TBOT(0)=['Z'R'R'R'R'R'R'Ó'Ó'Ó'Ó'R› 'R'R'R'R'R'C],› NOTE(0)=[243 243 217 243 204 243› 193 204],› YTOP(0)=[6 80],YBOT(0)=[62 144],› SCORE(2),PDLX(2),PDLY(2),OSTIK(2),› ROMSET($400)=$E000,HPOSP(4)=53248,› HPOSM(4)=53252,PCOLR(4)=704››CARD› PUCKXV,PUCKYV,PUCKX,PUCKY,› MAXV=[500],DLISTL=560,SAVMSC=88,› XITVBV=$E462›››; --- Miscellaneous Procedures ---››PROC SETVBV=$E45C(BYTE CMD,VBIHI,› VBILO)›››PROC VBI()›; VBI to play music› SOUND(0,NOTE(NINDEX),10,VOLUME)› SOUND(1,NOTE(NINDEX)-2,10,VOLUME)› VOLUME==-1› IF VOLUME=0 THEN› VOLUME=15› NINDEX==+1› IF NINDEX=8 THEN› NINDEX=0› FI› FI›; JMP XITVBV› [$4C XITVBV]›RETURN›››PROC INITVBI()›; Initialize music VBI› NINDEX=0› VOLUME=15› SNDRST()› ; set deferred vbi vector› SETVBV(7,VBI RSH 8,VBI)›RETURN›››PROC DEBOUNCE()›CARD I›; Debounce console keys› FOR I=0 TO 5000 DO› DO› UNTIL CONSOL=NONE› OD› OD›RETURN›››; --- Title Screen ---››PROC INITTITLE()›BYTE I›; Initialize title screen› GRAPHICS(0)› GPRIOR=17› GRACTL=0› SDMCTL=0› CRSINH=1› HUE=0› DLIST=DLISTL› DO› UNTIL VCOUNT=0› OD› FOR I=3 TO 5 DO› DLIST(I+7)=DLIST(I)› OD› SETBLOCK(DLIST,10,$70)› FOR I=13 TO 25 STEP 2 DO› DLIST(I)=0› OD› SETBLOCK(DLIST+27,2,$70)› SETCOLOR(1,0,14)› SETCOLOR(2,0,8)› POSITION(11,0)› PRINT("Air Hockey")› POSITION(1,1)› PRINT("By: Chris Page")› POSITION(29,1)› PRINT("Thanks: D.S. and D.B.")› POSITION(17,2)› PRINT(› "June 30, 1984 - August 9, 1985")› POSITION(7,4)› PRINT("Copyright (c) 1984")› POSITION(34,5)› PRINT("Press ÓÔÁÒÔ")› SDMCTL=33›RETURN›››PROC TITLECOLORS()›BYTE I›; Mid-screen color changes› HUE==+2› IF HUE&2 THEN› CHACT==+1&3› FI› FOR I=0 TO 30 DO› DO› WSYNC=0› COLOR4=VCOUNT LSH 1+HUE› IF VCOUNT=48 THEN› COLOR1=0› FI› UNTIL VCOUNT&128› OD› OD›RETURN›››PROC TITLE()›; Display title screen› INITTITLE()› INITVBI()› DO› TITLECOLORS()› UNTIL CONSOL=START› OD› SDMCTL=0›RETURN›››; --- Game Options ---››PROC INITOPTIONS()›; Initialize procedure OPTIONS()› GRAPHICS(17)› SDMCTL=0› GRACTL=0› DO› UNTIL VCOUNT=0› OD› DEBOUNCE()› SCRMEM=SAVMSC› DLIST=DLISTL› DLIST(3)==+1› SETCOLOR(0,3,14)› SETCOLOR(2,0,14)› PRINTDE(6," GAME OPTIONS")› POSITION(0,2)› PRINTD(6,"ÏÐÔÉÏÎ - NEXT OPTION")› PRINTDE(6,"ÓÅÌÅÃÔ - CHOOSE")› PRINTDE(6," ÓÔÁÒÔ - PLAY GAME")› POSITION(3,6)› PRINTD(6,"FRICTION: O")› IF FRICTION THEN› PRINTD(6,"N")› ELSE› PRINTD(6,"FF")› FI› POSITION(3,8)› PRINTD(6,"VELOCITY: ")› PRINTBD(6,MAXV/100)› POSITION(3,10)› PRINTD(6,"BOUNCE : ")› PRINTBD(6,BOUNCE/10)› POSITION(3,12)› PRINTD(6,"WIN AT : ")› PRINTBD(6,WIN)› POSITION(3,14)› PRINTD(6,"PLAYERS : ")› PRINTBD(6,PLAYERS)› SDMCTL=34› OPT=0›RETURN›››PROC OPTIONCOLORS(BYTE OPT)›; Mid-screen color changes›; OPT=option line to hi-light› DO› WSYNC=0› UNTIL VCOUNT=15› OD› LUM=0› WSYNC=0› DO› WSYNC=0› COLOR0=LUM&$0F%$20› LUM==+2› UNTIL VCOUNT=25› OD› WSYNC=0› COLOR0=0› COLOR4=6› DO› WSYNC=0› UNTIL VCOUNT=40› OD› COLOR0=$F8› OPT==LSH 3+41› DO› WSYNC=0› UNTIL VCOUNT=OPT› OD› COLOR0=$FE› DO› WSYNC=0› UNTIL VCOUNT=OPT+8› OD› COLOR0=$F8›RETURN›››PROC OPTIONS()›CARD I›; Get game options from player(s)› INITOPTIONS()› DO› FOR I=0 TO 10 DO› OPTIONCOLORS(OPT)› UNTIL CONSOL=START› OD› IF CONSOL=OPTION THEN› OPT==+1› IF OPT=5 THEN› OPT=0› FI› FI› IF CONSOL=SELECT THEN› IF OPT=0 THEN› FRICTION==!1› IF FRICTION THEN› SCRMEM(134)=46› SCRMEM(135)=0› ELSE› SCRMEM(134)=38› SCRMEM(135)=38› FI› ELSEIF OPT=1 THEN› IF MAXV=900 THEN› SCRMEM(173)==-7› MAXV=200› ELSE› SCRMEM(173)==+1› MAXV==+100› FI› ELSEIF OPT=2 THEN› IF BOUNCE=90 THEN› SCRMEM(213)==-9› BOUNCE=0› ELSE› SCRMEM(213)==+1› BOUNCE==+10› FI› ELSEIF OPT=3 THEN› IF WIN=90 THEN› SCRMEM(253)==-8› WIN=10› ELSE› SCRMEM(253)==+1› WIN==+10› FI› ELSE› IF PLAYERS=2 THEN› SCRMEM(293)==-1› PLAYERS=1› ELSE› SCRMEM(293)==+1› PLAYERS=2› FI› FI› FI› UNTIL CONSOL=START› OD› SDMCTL=0› SNDRST()›RETURN›››; --- Play Air Hockey ---››PROC MAKEFONT()›BYTE I›CARD J›; Change character set››BYTE ARRAY› CDAT(8)=[$55$55$55$55$54$54$50$40],› EDAT(8)=[$40$50$54$54$55$55$55$55],› QDAT(8)=[$01$05$15$15$55$55$55$55],› RDAT(8)=[$55$55$55$55$55$55$55$55],› SDAT(8)=[$FF$FF$FF$FF$FF$FF$FF$FF],› TDAT(8)=[$AA$AA$2A$AA$AA$AA$A2$AA],› ZDAT(8)=[$55$55$55$55$15$15$05$01]›› RAMFONT=(RAMTOP-8)*$100› MOVEBLOCK(RAMFONT,ROMSET,$400)› ZERO(RAMFONT+536,192)› CHBAS=RAMTOP-8› SDMCTL=61› FOR I=0 TO 7 DO› FOR J=0 TO 3000 DO OD› RAMFONT(536+I)=CDAT(I)› RAMFONT(552+I)=EDAT(I)› RAMFONT(648+I)=QDAT(I)› RAMFONT(656+I)=RDAT(I)› RAMFONT(664+I)=SDAT(I)› RAMFONT(672+I)=TDAT(I)› RAMFONT(720+I)=ZDAT(I)› OD›RETURN›››PROC POSPLAYER(CARD PLAYER› BYTE X,Y,LENGTH› BYTE ARRAY SHAPE)›; Position Player› HPOSP(PLAYER)=X+LEFT› PLAYER==*$100+$400› MOVEBLOCK(PMMEM+PLAYER+Y+TOP,› SHAPE,LENGTH)›RETURN›››PROC POSPDL(BYTE PADDLE,X,Y)›; Position paddle› POSPLAYER(PADDLE,X,Y,2,BAR)›RETURN›››PROC POSPUCK(CARD X,Y)›; Position puck› X==/100› Y==/100› POSPLAYER(2,X,Y,8,PUCK)›RETURN›››PROC ERASEPDL(CARD PADDLE BYTE Y)›; Erase paddle› PADDLE==*$100+$400› ZERO(PMMEM+PADDLE+Y+TOP,2)›RETURN›››PROC ERASEPUCK(CARD Y)›; Erase puck› Y==/100+TOP› ZERO(PMMEM+$600+Y,8)›RETURN›››PROC ERASEALL()›; Clear Player memory› ERASEPDL(0,PDLY(0))› ERASEPDL(1,PDLY(1))› ERASEPUCK(PUCKY)›RETURN›››PROC INITPMG()›; Initialize PMG› PMMEM=(RAMTOP-16)*$100› Zero(PMMEM,$800)› PCOLR(0)=$76› PCOLR(1)=$76› PCOLR(2)=$36› PMBASE=RAMTOP-16› GRACTL=3›RETURN›››PROC INITPLAY()›CARD I›; Initialize game› GRAPHICS(0)› SDMCTL=0› DO› UNTIL VCOUNT=0› OD› SETVBV(7,$E4,$62)› SNDRST()› DEBOUNCE()› INITPMG()› SCRMEM=SAVMSC› SCORE(0)=0› SCORE(1)=0› OSTIK(0)=15› OSTIK(1)=15› SERVER=0› GAMEOVER=0› CRSINH=1› DLIST=DLISTL› DLIST(2)=DLIST(3)+4› DLIST(3)=DLIST(4)› DLIST(4)=DLIST(5)› DLIST(5)=$30› DLIST(7)=$30› SETBLOCK(DLIST+8,21,4)› SETCOLOR(0,3,6)› SETCOLOR(1,0,14)› SETCOLOR(2,0,4)› SETCOLOR(3,2,14)› SETCOLOR(4,0,6)› POSITION(3,0)› PRINTE("air hockey")› SAVMSC==+16› POSITION(0,0)› PRINTF(› " One : 00 | Win : %B | Two : 00",› win)› MOVEBLOCK(SCRMEM+55,TTOP,18)› FOR I=87 TO 663 STEP 32 DO› MOVEBLOCK(SCRMEM+I,TMID,18)› OD› MOVEBLOCK(SCRMEM+695,TBOT,18)› MAKEFONT()› SOUND(3,0,0,3)› KEY=0› CH=$FF›RETURN›››PROC SERVE(BYTE PLAYER)›CARD I›; Initialize positions› ERASEALL()› PDLX(0)=28› PDLX(1)=28› PDLY(0)=YTOP(0)› PDLY(1)=YBOT(1)› PUCKX=3000› PUCKY=4000+6800*PLAYER› PUCKXV=0› PUCKYV=0› POSPDL(0,PDLX(0),PDLY(0))› POSPDL(1,PDLX(1),PDLY(1))› POSPUCK(PUCKX,PUCKY)› HITCLR=0› HITFLAG=0› VOLUME=0›RETURN›››PROC MOVEPADDLE(BYTE P)›BYTE STIK›; Move paddle› ERASEPDL(P,PDLY(P))› STIK=STICK(P)› ; move puck 2 for one player game› IF PLAYERS=P THEN› STIK=$F› IF PDLX(1)+2PUCKY/100 THEN› STIK==-1› ELSE› STIK==-2› IF RAND(2) THEN› STIK==+1› FI› FI› FI› ; save stick position› OSTIK(P)=STIK› ; move paddle verticaly› IF (STIK&1)=0 THEN› PDLY(P)==-2› IF PDLY(P)YBOT(P) THEN› PDLY(P)=YBOT(P)› FI› FI› ; move paddle horizontaly› IF (STIK&8)=0 THEN› PDLX(P)==+2› IF PDLX(P)>RIGHT-4 THEN› PDLX(P)=RIGHT-4› FI› ELSEIF (STIK&4)=0 THEN› PDLX(P)==-2› IF PDLX(P)>240 THEN› PDLX(P)=0› FI› FI› POSPDL(P,PDLX(P),PDLY(P))›RETURN›››PROC REVERSEPX()›; Reverse horizontal puck direction› VOLUME=14› PUCKXD==!1› IF PUCKXV<(90-BOUNCE) THEN› PUCKXV=0› ELSE› PUCKXV==-(90-BOUNCE)› FI›RETURN›››PROC REVERSEPY()›; Reverse vertical puck direction› VOLUME=14› PUCKYD==!1› IF PUCKYV<(90-BOUNCE) THEN› PUCKYV=0› ELSE› PUCKYV==-(90-BOUNCE)› FI›RETURN›››PROC MOVEPUCK()›BYTE PADDLE,XDIF,YDIF,STIK,ABOVE›CARD ARRAY› XVELOC(0)=[400 140 100 80 40 0› 40 80 100 140 400]›; Move the puck› ERASEPUCK(PUCKY)›; check for paddle collisions› PADDLE=0› IF PUCKY/100>70 THEN› PADDLE=1› FI› STIK=OSTIK(PADDLE)› IF P2PL THEN› IF HITFLAG=0 THEN› VOLUME=14› ; new x velocity & direction› XDIF=PUCKX/100+3-PDLX(PADDLE)› PUCKXV=XVELOC(XDIF)› PUCKXD=0› IF XDIF>5 THEN› PUCKXD=1› FI› ; new y velocity & direction› YDIF=PUCKY/100-PDLY(PADDLE)› ABOVE=0› IF PADDLE THEN› IF PUCKY/100200 THEN› PUCKYD==!1› FI› ELSE› PUCKYV==+200› FI› ELSEIF PUCKYD=0 AND› (STIK&3)=2 THEN› IF ABOVE=0 THEN› PUCKYV==-200› IF PUCKYV>200 THEN› PUCKYD==!1› FI› ELSE› PUCKYV==+200› FI› ELSEIF PUCKYD=1 AND› (STIK&3)=2 THEN› IF ABOVE THEN› PUCKYD==!1› PUCKYV==+200› FI› ELSEIF PUCKYD=0 AND› (STIK&3)=1 THEN› IF ABOVE=0 THEN› PUCKYD==!1› PUCKYV==+200› FI› FI› FI› FI› HITFLAG=1› ELSE› HITFLAG=0› FI› HITCLR=0›; move horizontaly› IF PUCKXV>MAXV THEN› PUCKXV=MAXV› FI› IF PUCKXD THEN› PUCKX==+PUCKXV› ELSE› PUCKX==-PUCKXV› FI›; check boundaries› IF PUCKX>24000 THEN› REVERSEPX()› PUCKX=0› ELSEIF PUCKX>RIGHT*100 THEN› REVERSEPX()› PUCKX=RIGHT*100› FI› IF PUCKYV>MAXV THEN› PUCKYV=MAXV› FI›; move verticaly› IF PUCKYD THEN› PUCKY==+PUCKYV› ELSE› PUCKY==-PUCKYV› FI›; check boundaries› IF PUCKY>24000 THEN› REVERSEPY()› PUCKY=0› ELSEIF PUCKY>BOT*100 THEN› REVERSEPY()› PUCKY=BOT*100› FI›; handle friction› IF PUCKXV THEN› PUCKXV==-FRICTION› FI› IF PUCKYV THEN› PUCKYV==-FRICTION› FI›; fading collision sound› IF VOLUME THEN› VOLUME==-2› SOUND(0,10,8,VOLUME)› SOUND(1,10,10,VOLUME)› ELSE› SOUND(0,0,0,0)› SOUND(1,0,0,0)› FI› POSPUCK(PUCKX,PUCKY)›RETURN›››PROC GOAL(BYTE PLAYER)›BYTE I›CARD J›; Inc score, check for a winner› SNDRST()› ERASEPUCK(PUCKY)› VOLUME=0› SERVEIT=1› SERVER=PLAYER› SCORE(PLAYER)==+1› IF SCORE(PLAYER)=WIN THEN› GAMEOVER=1› FI›; flash score› FOR I=0 TO 5 DO› SETBLOCK(SCRMEM+23+22*PLAYER,2,0)› FOR J=0 TO 5000 DO OD› SCRMEM(23+22*PLAYER)=› 16+SCORE(PLAYER)/10› SCRMEM(24+22*PLAYER)=› 16+SCORE(PLAYER) MOD 10› SOUND(0,20,10,8)› FOR J=0 TO 5000 DO OD› SOUND(0,0,0,0)› OD›; cheering› IF GAMEOVER=0 THEN› FOR I=0 TO 30 DO› FOR J=0 TO 1000 DO OD› SOUND(0,10,8,I RSH 1)› OD› FOR J=0 TO 40000 DO OD› FOR I=0 TO 30 DO› FOR J=0 TO 1000 DO OD› SOUND(0,10,8,15-I RSH 1)› OD› FI› SNDRST()› SOUND(3,0,0,3)›RETURN›››PROC MOVEALL()›; Move paddles and puck›; keep attract mode at bay› ATRACT=0›; check for goal› IF PUCKX>2400 AND PUCKX<3700 THEN› IF PUCKY=0 THEN› GOAL(1)› ELSEIF PUCKY=BOT*100 THEN› GOAL(0)› FI› FI› IF GAMEOVER=0 THEN› MOVEPUCK()› MOVEPADDLE(0)› MOVEPADDLE(1)› FI›RETURN›››PROC ENDGAME()›BYTE I›CARD J,K›; Cheer profusly and end game› SNDRST()› FOR I=0 TO 30 DO› FOR J=0 TO 1000 DO OD› SOUND(0,10,8,I RSH 1)› OD› FOR J=0 TO 200 DO› FOR K=0 TO 500 DO OD› IF RAND(130)=0 THEN› FOR I=0 TO 15 DO› FOR K=0 TO 1200 DO OD› SOUND(1,30-I,10,I)› OD› FOR I=0 TO 15 DO› FOR K=0 TO 1200 DO OD› SOUND(1,15+I,10,15-I)› OD› FI› OD› FOR I=0 TO 30 DO› FOR J=0 TO 1000 DO OD› SOUND(0,10,8,15-I RSH 1)› OD› FOR J=0 TO 40000 DO OD›RETURN›››PROC PLAY()›; Play Air Hockey› INITPLAY()› SERVE(SERVER)› DO› DO› UNTIL VCOUNT=100› OD› IF CH<>$FF THEN› KEY=GETD(1)› FI› IF KEY=32 OR SERVEIT=1 THEN› SERVE(SERVER)› KEY=0› CH=$FF› SERVEIT=0› FI› MOVEALL()› UNTIL GAMEOVER=1 OR KEY=27 OR› CONSOL=6› OD› IF KEY<>27 AND CONSOL<>6 THEN› ENDGAME()› FI› SNDRST()›RETURN›››; --- Main Procedure ---››PROC MAIN()› LMARGN=0› CLOSE(1)› OPEN(1,"K:",4,0)› DO› TITLE()› WHILE CONSOL=6 DO› OPTIONS()› PLAY()› OD› UNTIL KEY=27› OD› CLOSE(1)› GRAPHICS(0)› GRACTL=0›RETURN››