; áîáìïç’îïö¸µ’ðç³³’øó›; Sneak Attack by David Plotkin››MODULE››BYTE› ChrBase=756,Max,Bkgrnd=710,› Fate=53770,Level=[1],CursIn=752,› Stick=632,Ps,Loud=[0],Indx=[0],› DownL=[0],DownR=[0],Loud1=[0],› Snd1=$D208,Snd2=$D20F,Freq=[169],› Wsync=$D40A,Colbk=$D018,› Nmien=$D40E,Hard=[15],› Consol=53279››CARD› Scrn=88,RamSet,HiMem=$2E5,› Score=[0],Comp=[300],Sdlst=560,› Vdslst=512››CARD ARRAY Linept(24)››BYTE ARRAY› Charset,Chopperstatus(30),› Chopperx(30),Choppery(30),› Expx(60),Expy(60),ExpStatus(60),› TrStatus(30),Trx(30),Try(30),› MisStatus(30),Misx(30),Misy(30),› Ll(20),Rr(20),Dlist,› ShapeTable(0)=› [254 16 124 71 127 12 62 0› 127 8 62 226 254 24 126 0› 96 96 48 48 24 60 231 255› 24 24 24 24 24 60 231 255› 6 6 12 12 24 60 231 255› 128 85 17 66 24 170 91 131› 60 126 255 255 195 66 36 24› 60 36 24 255 60 24 36 102› 0 0 0 0 0 0 0 0› 60 36 24 255 60 24 36 102› 60 36 219 255 60 24 36 102› 60 60 24 60 60 24 24 28› 60 60 24 60 60 60 102 195]››PROC Download()›;Step back HiMem and move the›;character set into RAM›CARD Index›BYTE Val› RamSet=(HiMem-$400)&$FC00› ChrBase=RamSet RSH 8› HiMem=RamSet› FOR Index=0 TO 1023 DO› Val=Peek(57344+Index)› Poke(RamSet+Index,Val)› OD› Charset=RamSet›RETURN››PROC Dlint()›;the display list interrupt routine› [$48 $8A $48 $98 $48]› Wsync=1› Colbk=50› [$68 $A8 $68 $AA $68 $40]››PROC Scoreline()›;set up the dli› Dlist=Sdlst› Vdslst=Dlint› Dlist(27)=130› Nmien=$C0›RETURN››PROC Update()›;print score and level› Position(1,23)› Print("Score: ")› Position(8,23)› PrintC(Score)› Position(18,23)› Print("Level: ")› Position(25,23)› PrintB(Level)›RETURN››PROC Title()›BYTE colpf0=53270,colpf1=53271,› colpf2=53273,colpf3=53273,› rtclock=20,vcount=54283› Graphics(18)› Position(3,4)› PrintD(6,"SNEAK ATTACK")› Position(8,5)› PrintD(6,"BY")› Position(3,7)› PrintD(6,"david plotkin")› Position(3,9)› PrintD(6,"ÐÒÅÓÓ óôáòô")› WHILE Consol<>6 DO› colpf3=Fate› Wsync=0› colpf0=128-vcount+rtclock RSH 2› colpf1=vcount+rtclock RSH 2› OD›RETURN››PROC Gr0Init()›;Set up the address of each screen›;line and initialize›CARD xx› Graphics(0)› CursIn=1› Print(" ")› FOR xx=0 TO 23 DO› Linept(xx)=Scrn+(40*xx)› OD› FOR xx=0 TO 29 DO› Chopperstatus(xx)=0› Chopperx(xx)=0› Choppery(xx)=0› Misx(xx)=0› Misy(xx)=0› MisStatus(xx)=0› TrStatus(xx)=0› OD› FOR xx=0 TO 59 DO› ExpStatus(xx)=0› OD› FOR xx=0 TO 19 DO› Ll(xx)=0› Rr(xx)=0› OD› Bkgrnd=0› Update()›RETURN››PROC Plot0(BYTE x,y,ch)›;Plot a char at location x,y›BYTE ARRAY line› line=Linept(y)› line(x)=ch›RETURN››BYTE FUNC Locate0(BYTE x,y)›;Returns the value of the char at x,y›BYTE ARRAY line› line=Linept(y)›RETURN(line(x))››PROC Noise()›;the explosion noises› IF Loud=0 AND Loud1=0› AND Freq=169 THEN› RETURN› FI› IF Loud THEn› Loud==-2› Sound(0,90,8,Loud)› FI› IF Loud1 THEN› Loud1==-2› Sound(1,150,8,Loud1)› FI› IF Freq<168 THEN› Freq==+8› Sound(2,Freq,10,4)› ELSE› Freq=169› Sound(2,0,0,0)› FI›RETURN››PROC HitChute(BYTE wh)›;see which chute was hit by missile wh›BYTE lp› FOR lp=0 TO 29 DO› IF Misx(wh)=Trx(lp) AND› (Misy(wh)=Try(lp) OR› Misy(wh)=Try(lp)+1) THEN› TrStatus(lp)=2› Plot0(trx(lp),Try(lp),0)› Plot0(Trx(lp),Try(lp)+1,10)› Plot0(Trx(lp),Try(lp)+2,0)› EXIT› FI› OD› IF Try(lp) LSH 3 < Freq THEN› Freq=Try(lp) LSH 3› FI›RETURN››PROC HitMan(BYTE wh)›;see which man was hit by missile wh›BYTE lp› FOR lp=0 TO 29 DO› IF Misx(wh)=Trx(lp) AND› (Misy(wh)=Try(lp)+1 OR› Misy(wh)=Try(lp)+2) THEN› TrStatus(lp)=3› Plot0(Trx(lp),Try(lp)+1,6)› Plot0(Trx(lp),Try(lp),0)› Plot0(Trx(lp),Try(lp)+2,0)› FI› OD› Loud1=12›RETURN››PROC ExplodeChopper(BYTE lp)›;explosions in place of Chopper lp›BYTE lq› FOR lq=0 TO 59 STEP 2 DO ;find empty› IF ExpStatus(lq)=0 THEN› ExpStatus(lq)=1 › ExpStatus(lq+1)=1› Expx(lq)=Chopperx(lp)› Expx(lq+1)=Chopperx(lp)+1› Expy(lq)=Choppery(lp)› Expy(lq+1)=Choppery(lp)› Chopperstatus(lp)=0› Plot0(Expx(lq),Expy(lq),6)› Plot0(Expx(lq+1),Expy(lq+1),6)› EXIT› FI› OD›RETURN››PROC HitChopper(BYTE wh)›;which chopper was hit by missile wh›BYTE lp› FOR lp=0 TO 29 DO› IF Misy(wh)=Choppery(lp) AND› (Misx(wh)=Chopperx(lp) OR› Misx(wh)=Chopperx(lp)+1) THEN› ExplodeChopper(lp)› EXIT› FI› OD› Loud=12›RETURN››PROC MissileHit(BYTE wh)›;see if missile wh hit anything›BYTE dum› dum=Locate0(Misx(wh),Misy(wh))› IF dum=0 THEN› Plot0(Misx(wh),Misy(wh),84)› RETURN› FI› MisStatus(wh)=0› IF dum=1 OR dum=2 THEN› HitChopper(wh)› Score==+1› ELSEIF (dum=7 AND Indx<6 OR› dum=8 AND Indx>3) THEN› HitChute(wh)› Score==+2› ELSEIF (dum=8 AND Indx<4 OR› dum=9 AND Indx>1) THEN› HitMan(wh)› Score==+1› FI›RETURN››PROC Modify()›;Modify the RAM character set›CARD xx› FOR xx=0 TO 103 DO› Charset(xx+8)=ShapeTable(xx)› OD›RETURN››PROC LaunchTrooper(BYTE wh)›;drop a paratrooper from chopper wh›BYTE lp› IF Fate>240-(Level LSH 1) THEN› FOR lp=0 TO 29 DO ;find MT trooper› IF TrStatus(lp)=0 THEN ;got one› TrStatus(lp)=1› Trx(lp)=Chopperx(wh)› IF Trx(lp)=0 THEN› Trx(lp)=1› FI› Try(lp)=Choppery(wh)+1› Plot0(Trx(lp),Try(lp),7)› Plot0(Trx(lp),Try(lp)+1,8)› Plot0(Trx(lp),Try(lp)+2,9)› EXIT› FI› OD› FI›RETURN››PROC EraseChopper(BYTE wh)›;erase chopper number wh› Plot0(Chopperx(wh),Choppery(wh),0)› Plot0(Chopperx(wh)+1,Choppery(wh),0)› Chopperstatus(wh)=0› Chopperx(wh)=0› Choppery(wh)=0›RETURN››PROC DrawChopper(BYTE wh)›;draw chopper number wh› Plot0(Chopperx(wh),Choppery(wh),1)› Plot0(Chopperx(wh)+1,Choppery(wh),2)›RETURN››PROC ClearScreen()›;clear the screen›BYTE lp› FOR lp=0 TO 29› DO› IF Chopperstatus(lp) THEN› EraseChopper(lp)› FI› IF TrStatus(lp) THEN› TrStatus(lp)=0› Plot0(Trx(lp),Try(lp),0)› Plot0(Trx(lp),Try(lp)+1,0)› Plot0(Trx(lp),Try(lp)+2,0)› FI› IF MisStatus(lp)=1 THEN› MisStatus(lp)=0› Plot0(Misx(lp),Misy(lp),0)› FI› OD› FOR lp=0 TO 59 STEP 2 DO› IF ExpStatus(lp)=1 THEN› ExpStatus(lp)=0› ExpStatus(lp+1)=0› Plot0(Expx(lp),Expy(lp),0)› Plot0(Expx(lp+1),Expy(lp+1),0)› FI› OD›RETURN››PROC MoveChopper()›;move the choppers›BYTE lp,ps=[0]› FOR lp=0 TO 29 DO› IF Chopperstatus(lp)=1 THEN ;right› IF Chopperx(lp)=38 THEN› EraseChopper(lp)› ELSE› Plot0(Chopperx(lp),› Choppery(lp),0)› Chopperx(lp)==+1› DrawChopper(lp)› LaunchTrooper(lp)› FI› FI› IF Chopperstatus(lp)=2 THEN ;left› IF Chopperx(lp)=0 THEN› EraseChopper(lp)› ELSE› Plot0(Chopperx(lp)+1,› Choppery(lp),0)› Chopperx(lp)==-1› DrawChopper(lp)› LaunchTrooper(lp)› FI› FI› OD› IF ps=0 THEN › Charset(8)=56› Charset(16)=28› ps=1› ELSE› ps=0› Charset(8)=254› Charset(16)=127› FI›RETURN››PROC LaunchChopper()›;Decide whether to send off a new›;chopper, which side, how high up›BYTE lp› IF Fate>230-(Level LSH 1) THEN› FOR lp=0 TO 29 DO ;find MT chopper› IF Chopperstatus(lp)=0 THEN› Choppery(lp)=Rand(Hard)› IF Fate>128 THEN› Chopperx(lp)=38 ;right side› Chopperstatus(lp)=2› ELSE› Chopperx(lp)=0 ;left side› Chopperstatus(lp)=1› FI› DrawChopper(lp)› EXIT› FI› OD› FI›RETURN››PROC DrawBase()›;draw the base›BYTE lp› FOR lp=19 TO 21 DO› Plot0(lp,22,128)› OD› Plot0(20,21,4)›RETURN››PROC AimGun()›;read the joystick and move the base› IF Stick=11 THEN› Ps=3› ELSEIF Stick=7 THEN› Ps=5› ELSE› Ps=4› FI› Plot0(20,21,Ps)›RETURN››PROC Shoot()›;send off a bullet›BYTE trig=644,lp,flg=[0]› IF trig=1 OR flg=0 THEN› flg=1› RETURN› FI› FOR lp=0 TO 29 DO ;find empty shot› IF MisStatus(lp)=0 THEN ;got one› MisStatus(lp)=1› Misy(lp)=20› IF Ps=3 THEN› Misx(lp)=19› ELSEIF Ps=5 THEN› Misx(lp)=21› ELSE› MISX(lp)=20› FI› MissileHit(lp)› EXIT› FI› OD› flg=0›RETURN››PROC MoveShots()›;move the fired bullets›BYTE lp› FOR lp=0 TO 29 DO ;for each shot› IF MisStatus(lp)=1 THEN› Plot0(Misx(lp),Misy(lp),0)› IF Stick=11 THEN› Misx(lp)==-1› ELSEIF Stick=7 THEN› Misx(lp)==+1› ELSE› Misy(lp)==-1› FI› IF (Misx(lp)<>39 AND› Misy(lp)<>255 AND› Misx(lp)<>0) THEN› MissileHit(lp)› ELSE› MisStatus(lp)=0› FI› FI› OD›RETURN››PROC MoveExplosions()›;move the explosions›BYTE lp› FOR lp=0 TO 59 STEP 2 DO› IF ExpStatus(lp)=1 THEN› Plot0(Expx(lp),Expy(lp),0)› Plot0(Expx(lp+1),Expy(lp+1),0)› Expy(lp)==+1› Expy(lp+1)==+1› Expx(lp)==-1› Expx(lp+1)==+1› IF Expy(lp)<>22 AND Expx(lp)<>0› AND Expx(lp+1)<>39 THEN› Plot0(Expx(lp),Expy(lp),6)› Plot0(Expx(lp+1),Expy(lp+1),6)› ELSE› ExpStatus(lp)=0› ExpStatus(lp+1)=0› FI› FI› OD›RETURN››PROC BaseExplode()›;explode the base›BYTE ARRAY endx(0)=[16 24 17 23 20],› endy(0)=[22 22 19 19 17]›BYTE lp,time=20› color=38› FOR lp=0 TO 4 DO› Plot(20,22)› DrawTo(endx(lp),endy(lp))› OD› FOR lp=0 TO 16 DO› Sound(0,Fate,8,16-lp)› Sound(1,Fate,8,16-lp)› time=0› DO› UNTIL time=15› OD› OD› SndRst()› color=32› FOR lp=0 TO 4 DO› Plot(20,22)› DrawTo(endx(lp),endy(lp))› OD›RETURN››PROC EndRight()›;move the troopers from the right›;to the base›BYTE lp,lq,nn,time=20› FOR lp=0 TO 19 DO› IF Rr(lp)=1 THEN› lq=21+lp› WHILE lq>20 DO› IF nn=12 THEN› nn=13› ELSE› nn=12› FI› Plot0(lq,22,nn)› time=0› DO› UNTIL time=10› OD› Plot0(lq,22,0)› lq==-1› OD› Plot0(21,22,11)› FI› OD› FOR lp=0 TO 3 DO› Plot0(21,22-lp,11)› time=0› DO› UNTIL time=10› OD› OD› BaseExplode()›RETURN››PROC EndLeft()›;Move the troopers from the left to›;the base›BYTE lp,lq,lc,nn,time=20› FOR lp=0 TO 19 DO› lq=19-lp› IF Ll(lq)=1 THEN› FOR lc=lq TO 19 DO› IF nn=12 THEN› nn=13› ELSE› nn=12› FI› Plot0(lc,22,nn)› time=0› DO› UNTIL time=10› OD› Plot0(lc,22,0)› OD› Plot0(19,22,11)› FI› OD› FOR lp=0 TO 3 DO› Plot0(19,22-lp,11)› time=0› DO› UNTIL time=10› OD› OD› BaseExplode()›RETURN››PROC EndPrint()›;print the end of game message and›;test for new game›BYTE trig=644,lp› Position(10,7)› Print("Game Over...Final Score:")› Position(15,8)› PrintC(Score)› Position(15,9)› Print("FINAL LEVEL :")› PrintB(Level)› Position(10,20)› Print("Press ÆÉÒÅ to play again")› DO› UNTIL trig=0› OD› DownL=0› DownR=0› Put(125)› FOR lp=0 TO 19 DO› Ll(lp)=0› Rr(lp)=0› OD› Score=0› Level=1› DrawBase()› Update()› Hard=15›RETURN››PROC GameOverTwo()›;game over when four troopers down›BYTE lp› SndRst()› ClearScreen()› Loud=0› Loud1=0› Freq=169› FOR lp=0 TO 19 DO› IF Ll(lp)=1 THEN› Plot0(lp,22,11)› FI› IF Rr(lp)=1 THEN› Plot0(lp+21,22,11)› FI› OD› IF DownL=4 THEN› EndLeft()› ELSE› EndRight()› FI› EndPrint()›RETURN››PROC GameOverOne()›;game over when trooper lands on base›BYTE lp› SndRst()› ClearScreen()› Loud=0› Loud1=0› Freq=169› FOR lp=0 TO 19 DO› IF Ll(lp)=1 THEN› Plot0(lp,22,11)› FI› IF Rr(lp)=1 THEN› Plot0(lp+21,22,11)› FI› OD› BaseExplode()› EndPrint()›RETURN››PROC TrooperDown(BYTE wh)›;redraw trooper wh at bottom of screen›BYTE cc› TrStatus(wh)=0› cc=Trx(wh)› Plot0(Trx(wh),Try(wh),0) ;erase chute› Plot0(Trx(wh),Try(wh)+1,11) ;replace› IF Trx(wh)<20 AND Ll(cc)=0 THEN› Ll(cc)=1› DownL==+1› ELSEIF Trx(wh)>20 AND› Rr(cc-21)=0 THEN› Rr(cc-21)=1› DownR==+1› ELSEIF Trx(wh)=20 THEN› GameOverOne()› FI› IF DownL=4 OR DownR=4 THEN› GameOverTwo()› FI›RETURN››PROC TrooperFall()›;make trooper fall when chute hit›BYTE lp,qq,cc› FOR lp=0 TO 29 DO› IF TrStatus(lp)=2 THEN› Plot0(Trx(lp),Try(lp)+1,0)› Try(lp)==+1› If Try(lp)=21 THEN› cc=Trx(lp)› IF Trx(lp)<20 AND Ll(cc)=1 THEN› DownL==-1› Ll(cc)=0› ELSEIF Trx(lp)>20 AND› Rr(cc-21)=1 THEN› Rr(cc-21)=0› DownR==-1› FI› FI› IF (Try(lp)<22 AND Trx(lp)<>20)› OR (Try(lp)<20 AND› Trx(lp)=20) THEN› Plot0(Trx(lp),Try(lp)+1,10)› ELSE› TrStatus(lp)=0› FI› FI› OD›RETURN››PROC MoveTroopers()›;move paratroopers down screen›BYTE lp,qq›BYTE ARRAY Trooper(0)=› [60 126 255 255 195 66 36 24› 60 36 24 255 60 24 36 102› 0 0 0 0 0 0 0 0]› FOR lp=0 TO Indx DO› Charset(56+lp)=0› OD› MoveBlock(Charset+56+Indx+1,› Trooper,16)› Indx==+1› IF Indx<8 THEN› RETURN› FI› Indx=0› FOR lp=0 TO 29 DO› IF TrStatus(lp)=1 THEN› Plot0(Trx(lp),Try(lp),0)› Try(lp)==+1› IF Try(lp)=21 THEN› TrooperDown(lp)› FI› FI› IF TrStatus(lp)=3 THEN› TrStatus(lp)=0› Plot0(Trx(lp),Try(lp)+1,0)› FI› OD› MoveBlock(Charset+56,Trooper,24)› FOR lp=0 TO 29 DO› IF TrStatus(lp)=1 THEN› Plot0(Trx(lp),Try(lp),7)› Plot0(Trx(lp),Try(lp)+1,8)› Plot0(Trx(lp),Try(lp)+2,9)› FI› OD›RETURN››PROC NewLevel()›;go to higher level›BYTE lp,time=20› Level==+1› IF Level>100 THEN› Level=100› FI› SndRst()› Loud=0› Loud1=0› Freq=169› Comp==+300› FOR lp=10 TO 150 STEP 10 DO› Sound(0,lp,10,4)› Sound(1,lp+10,10,4)› time=0› DO› UNTIL time=2› OD› OD› Position(25,23)› PrintB(Level)› IF Level>8 THEN› Hard=19› FI› SndRst()›RETURN››PROC Main()›BYTE time=20,lp,ch=764› Title()› Gr0Init()› Snd1=0› Snd2=3› Download()› Modify()› DrawBase()› ScoreLine()› DO› LaunchChopper()› MoveChopper()› MoveExplosions()› Noise()› TrooperFall()› MoveTroopers()› Position(8,23)› PrintC(Score)› IF Score>Comp THEN› NewLevel()› FI› time=0› FOR lp=2 TO 6 STEP 2 DO› AimGun()› Shoot()› MoveShots()› DO› UNTIL time=lp› OD› OD› OD›RETURN› ›