-> -> ANNVIT CÆPTIS MDCCLXXVI! -> -> KRSNAke v1.17 Stab -> -> $NSAREG: 23F07N07OR2748D5944.7 [Fnord!] -> -> Copyright © 1995, 1996 Psilocybe Software -> -> This program is free software; you can redistribute it and/or modify -> it under the terms of the GNU General Public License as published by -> the Free Software Foundation; either version 2 of the License, or -> (at your option) any later version. -> -> This program is distributed in the hope that it will be useful, -> but WITHOUT ANY WARRANTY; without even the implied warranty of -> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -> GNU General Public License for more details. -> -> You should have received a copy of the GNU General Public License -> along with this program; if not, write to the Free Software -> Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -> -> $HISTORY: -> -> 22 Feb 1996 : 001.017 : Notifies user about important dates :) -> 26 Jan 1996 : 001.016 : Optimised and debugged ARexx interface -> 24 Oct 1995 : 001.015 : Uses new server notification system -> 24 Oct 1995 : 001.014 : Resets itself when prefs are changed -> 19 Oct 1995 : 001.013 : Graphic snake is scaled and masked -> 14 Oct 1995 : 001.012 : Snake can be graphic now -> 13 Oct 1995 : 001.011 : Added locale support -> 08 Oct 1995 : 001.010 : Optimised the score updating a little. -> 08 Oct 1995 : 001.009 : Oops.. Rnd() wasn't properly seeded. Fixed now. -> 22 Sep 1995 : 001.008 : Now is a commodity, can appear/disappear. -> 19 Sep 1995 : 001.007 : Added ARexx port and cleaned up imsg handling. -> 10 Sep 1995 : 001.006 : Uses new prefs system and datatype backgrounds. -> 12 Jul 1995 : 001.005 : Uses krsnake.library instead of internal c/s code. -> 11 Jul 1995 : 001.004 : Autostarts clients. -> 07 Jul 1995 : 001.003 : Now sends SNAKE_MOVES event to clients. -> 27 Jun 1995 : 001.002 : Added client/server interface. -> 23 Jun 1995 : 001.001 : Initial revision -> -> NOVUS ORDO SECLORUM! -> OPT OSVERSION=39 OPT PREPROCESS MODULE 'intuition/intuition','intuition/screens','dos/dos','graphics/text' MODULE 'graphics/view','datatypes/datatypes','datatypes/datatypesclass' MODULE 'datatypes/soundclass','datatypes','exec/execbase','exec/lists','utility' MODULE 'exec/semaphores','exec/nodes','dos/dostags','exec/libraries','dos/dosextens' MODULE 'krsnake','libraries/krsnake','tools/trapguru','exec/ports' MODULE 'libraries/lowlevel','lowlevel','datatypes/pictureclass','graphics/gfx' MODULE 'commodities','libraries/commodities','tools/ports','amigalib/cx' MODULE 'wb','icon','workbench/workbench','locale','utility/tagitem' MODULE 'tools/arexx','rexx/errors','utility/date','class/hash','other/split' MODULE '*tiledbitmap','*krsnakecat','*graphic' RAISE "SCR" IF LockPubScreen()=0, "WIN" IF OpenWindowTagList()=0, "DRI" IF GetScreenDrawInfo()=0, "FONT" IF OpenFont()=0, "DOBJ" IF AllocDosObject()=0, "LSEG" IF LoadSeg()=0, "CXBR" IF CxBroker()=0, "PORT" IF CreateMsgPort()=0 #define KRSNAKEVER {krsnakever}+6 OBJECT rexxcommand OF hashlink id:INT ENDOBJECT DEF krs=0 DEF w=0:PTR TO window,s=0:PTR TO screen,dri=0:PTR TO drawinfo DEF font:PTR TO textfont,dripens[NUMDRIPENS]:ARRAY OF INT DEF bw=4,bh=4,fw=128,fh=128,fy,ww,wh,wx=0,wy=-1,th DEF chunk=0,hx=15,hy=15,sx=0,sy=-1,eaten=0,playing=0,cx=-1,cy=-1,counter=3,speed=3 DEF fifox[1024]:ARRAY OF INT,fifoy[1024]:ARRAY OF INT,fifos=0,fifoe=0,fifol=1 DEF matrix[1024]:ARRAY OF INT,killtask=FALSE,gameover=0 DEF keybuf[256]:ARRAY OF CHAR,keybufs=1,keybufe=0,keybufl=0 DEF fillp[7]:ARRAY OF LONG,datatype[7]:ARRAY OF LONG,cp=0,paused=0 DEF wantobtainpens=0,pensobtained=0,visible=0 DEF bgs=0,efs=0,crs=0,nsx,nsw,nsh DEF kp=0:PTR TO kprefs,rexxPort=0:PTR TO mp DEF broker=0,brokerPort=0:PTR TO mp DEF appicon=0,appmenu=0,myicon=0:PTR TO diskobject,appPort=0:PTR TO mp DEF head,graphic[7]:ARRAY OF LONG,newprefs=0 DEF rexxwait=0,rexxwaitmode=0,rexxhash=0:PTR TO hashtable ENUM CXID_POPKEY=1 ENUM APPID_ICON=1,APPID_MENU ENUM AREXX_ERROR=0, AREXX_CHECK=1, AREXX_DOWN, AREXX_GET, AREXX_HIDE, AREXX_LEFT, AREXX_NEWGAME, AREXX_PAUSE, AREXX_QUIT, AREXX_RIGHT, AREXX_SET, AREXX_SHOW, AREXX_UP, AREXX_WAIT, AREXX_MAX PROC randomise() DEF ds:datestamp DateStamp(ds) Rnd(0-And(ds.tick+ds.days+ds.minute,$7fffffff)) ENDPROC PROC launchclients() HANDLE DEF fib=0:PTR TO fileinfoblock,lock=0,olddir,cc=0 fib:=AllocDosObject(DOS_FIB,NIL) lock:=Lock('PROGDIR:Clients',ACCESS_READ) IF lock=0 THEN Raise(1) IF Examine(lock,fib) olddir:=CurrentDir(lock) WHILE ExNext(lock,fib) IF fib.direntrytype<0 IF launchClient(fib.filename)=0 THEN INC cc ENDIF ENDWHILE CurrentDir(olddir) ENDIF EXCEPT DO IF lock THEN UnLock(lock) IF fib THEN FreeDosObject(DOS_FIB,fib) IF exception>1 THEN ReThrow() ENDPROC PROC launchClient(name) IS SystemTagList(name,[SYS_ASYNCH,TRUE,SYS_INPUT,NIL,SYS_OUTPUT,NIL,TAG_DONE]) PROC readsounds() IF StrLen(kp.startgamesound) THEN bgs:=KsReadSoundObject(kp.startgamesound) IF StrLen(kp.eatfruitsound) THEN efs:=KsReadSoundObject(kp.eatfruitsound) IF StrLen(kp.crashsound) THEN crs:=KsReadSoundObject(kp.crashsound) ENDPROC PROC freesounds() KsDeleteSoundObject(bgs) KsDeleteSoundObject(efs) KsDeleteSoundObject(crs) bgs:=0 efs:=0 crs:=0 ENDPROC PROC obtainpen(a) SELECT 4 OF kp.fill[a].type CASE FILLTYPE_RGB fillp[a]:=ObtainBestPenA(s.viewport.colormap,v32(kp.fill[a].red),v32(kp.fill[a].green),v32(kp.fill[a].blue),[OBP_PRECISION,PRECISION_EXACT,NIL]) CASE FILLTYPE_DATATYPE datatype[a]:=createImageData(kp.fill[a].file,s) CASE FILLTYPE_GRAPHIC graphic[a]:=loadGraphic(kp.fill[a].file,s) ENDSELECT ENDPROC PROC scaleGraphics() DEF i FOR i:=0 TO 6 IF kp.fill[i].type=FILLTYPE_GRAPHIC THEN scaleGraphic(graphic[i],bw,bh,s) ENDFOR ENDPROC PROC v32(x) IS Or(Shl(x,24),Or(Shl(x,16),Or(Shl(x,8),x))) PROC obtainpens() DEF gfxver,a MOVE.L gfxbase,A0 MOVE.W 20(A0),gfxver IF gfxver>=39 pensobtained:=1 FOR a:=0 TO 6 DO obtainpen(a) ENDIF ENDPROC PROC freepens() DEF a FOR a:=0 TO 6 SELECT 4 OF kp.fill[a].type CASE FILLTYPE_RGB IF fillp[a]<>-1 THEN ReleasePen(s.viewport::viewport.colormap,fillp[a]) CASE FILLTYPE_DATATYPE IF datatype[a] THEN disposeImageData(datatype[a]) CASE FILLTYPE_GRAPHIC IF graphic[a] THEN freeGraphic(graphic[a]) ENDSELECT fillp[a]:=-1 datatype[a]:=0 graphic[a]:=0 ENDFOR ENDPROC PROC dumpsettings() HANDLE DEF f=0 f:=Open('ENVARC:KRSNAke/KRSNAke.snapshot',MODE_NEWFILE) IF f=0 THEN Raise("URK") VfPrintf(f,'%ld\n%ld\n%ld\n%ld\n%ld\n',[w.leftedge,w.topedge,bw,bh,speed]) EXCEPT DO IF f THEN Close(f) ENDPROC PROC readnumeral(f) DEF i,b[256]:ARRAY OF CHAR IF (Fgets(f,b,255)=0) THEN Raise("URK") i:=Val(b) ENDPROC i PROC readsettings() DEF f=0 kp:=KsReadKRSNAkePrefs() IF kp=0 THEN Raise("Pref") wantobtainpens:=TRUE IF (f:=Open('ENVARC:KRSNAke/KRSNAke.snapshot',MODE_OLDFILE)) wx:=readnumeral(f) wy:=readnumeral(f) bw:=readnumeral(f) fw:=bw*32 bh:=readnumeral(f) fh:=bh*32 speed:=readnumeral(f) Close(f) ENDIF ENDPROC PROC bevelbox(x1,y1,x2,y2,dir=TRUE,bf=0) DEF shine,shadow IF dir shine:=dripens[SHINEPEN] shadow:=dripens[SHADOWPEN] ELSE shine:=dripens[SHADOWPEN] shadow:=dripens[SHINEPEN] ENDIF SetAPen(stdrast,shine) RectFill(stdrast,x1,y1,x1,y2) RectFill(stdrast,x1+1,y1,x2-1,y1) SetAPen(stdrast,shadow) RectFill(stdrast,x1+1,y2,x2,y2) RectFill(stdrast,x2,y1,x2,y2-1) IF bf SetAPen(stdrast,bf) RectFill(stdrast,x1+1,y1+1,x2-1,y2-1) ENDIF ENDPROC PROC renderlink(x,y,p) DEF sx,sy,a sx:=(x*bw)+4 sy:=(y*bh)+fy IF kp.fill[p].type<>FILLTYPE_GRAPHIC IF p>FILL_BACK bevelbox(sx,sy,sx+bw-1,sy+bh-1,TRUE) renderfill(sx+1,sy+1,sx+bw-2,sy+bh-2,p) ELSE renderfill(sx,sy,sx+bw-1,sy+bh-1,FILL_BACK) ENDIF ELSE IF p<FILL_FRUIT1 THEN a:=matrix[(y*32)+x]-1 ELSE a:=0 drawGraphic(stdrast,graphic[p],a,sx,sy) ENDIF ENDPROC PROC renderfill(x1,y1,x2,y2,p) DEF r:rectangle,d:PTR TO imagedata SELECT 4 OF kp.fill[p].type CASE FILLTYPE_RGB SetAPen(stdrast,fillp[p]) RectFill(stdrast,x1,y1,x2,y2) CASE FILLTYPE_DRIPEN SetAPen(stdrast,dripens[kp.fill[p].dripen]) RectFill(stdrast,x1,y1,x2,y2) CASE FILLTYPE_DATATYPE d:=datatype[p] r.minx:=x1 r.maxx:=x2 r.miny:=y1 r.maxy:=y2 copyTiledBitMap(d,stdrast,r) ENDSELECT ENDPROC PROC rendersnake() DEF i,p renderfill(4,fy,fw+3,fh+fy-1,FILL_BACK) i:=fifol p:=fifos REPEAT IF i>1 renderlink(fifox[p],fifoy[p],FILL_LINK) ELSE renderlink(fifox[p],fifoy[p],FILL_HEAD) ENDIF p:=p+1 IF p>=1024 THEN p:=0 i:=i-1 UNTIL i=0 IF (cx>=0) AND (cy>=0) THEN renderlink(cx,cy,FILL_FRUIT+cp) ENDPROC PROC pushlink(x,y,l) fifoe:=fifoe+1 fifol:=fifol+1 IF fifoe>=1024 THEN fifoe:=0 fifox[fifoe]:=x fifoy[fifoe]:=y matrix[(y*32)+x]:=l ENDPROC PROC poplink() DEF x,y,l x:=fifox[fifos] y:=fifoy[fifos] l:=matrix[(y*32)+x] fifos:=fifos+1 fifol:=fifol-1 IF fifos>=1024 THEN fifos:=0 matrix[(y*32)+x]:=0 ENDPROC x,y,l PROC pushkey(key) IF (key<$80) AND (key<>keybuf[keybufe]) keybufe:=keybufe+1 keybufl:=keybufl+1 IF keybufe>=256 THEN keybufe:=0 keybuf[keybufe]:=key ENDIF ENDPROC PROC popkey() DEF key IF keybufl<=0 THEN RETURN 0 key:=keybuf[keybufs] keybufs:=keybufs+1 keybufl:=keybufl-1 IF keybufs>=256 THEN keybufs:=0 ENDPROC key PROC renderscore(redraw=TRUE,newscore=FALSE) DEF ss[64]:STRING IF redraw SetAPen(stdrast,dripens[BACKGROUNDPEN]) IF newscore RectFill(stdrast,nsx,3,nsx+nsw-1,2+nsh) ELSE RectFill(stdrast,1,3,ww-2,th+2) ENDIF ENDIF IF playing THEN lStringF(ss,getstr(ID_INGAMESTATUS),[fifol,chunk]) IF (playing=0) AND (gameover=0) THEN lStringF(ss,getstr(ID_INITIALSTATUS),[bw,bh]) IF (playing=0) AND (gameover=1) THEN lStringF(ss,getstr(ID_GAMEOVERSTATUS),[fifol]) nsw:=TextLength(stdrast,ss,EstrLen(ss)) SetAPen(stdrast,dripens[TEXTPEN]) nsx:=(ww-nsw)/2 nsh:=font.ysize Move(stdrast,nsx,3+font.baseline) Text(stdrast,ss,EstrLen(ss)) ENDPROC PROC render() DEF rw,rh ww:=w.width-w.borderleft-w.borderright wh:=w.height-w.bordertop-w.borderbottom fw:=ww-8 fh:=wh-th-14 fy:=th+10 bw:=fw/32 bh:=fh/32 rw:=bw*32 rh:=bh*32 IF (fw-rw) OR (fh-rh) THEN JUMP done scaleGraphics() SetRast(stdrast,dripens[BACKGROUNDPEN]) bevelbox(0,0,ww-1,th+5) bevelbox(0,fy-4,ww-1,wh-1) bevelbox(3,fy-1,ww-4,wh-4,FALSE) renderscore(FALSE) rendersnake() done: ENDPROC PROC verifysize() DEF rw,rh,aw,ah aw:=w.width ah:=w.height fw:=aw-w.borderleft-w.borderright-8 fh:=ah-w.bordertop-w.borderbottom-th-14 bw:=fw/32 bh:=fh/32 rw:=bw*32 rh:=bh*32 IF (fw-rw) OR (fh-rh) aw:=aw-(fw-rw) ah:=ah-(fh-rh) ChangeWindowBox(w,w.leftedge,w.topedge,aw,ah) ENDIF ENDPROC PROC newchunk() REPEAT cx:=Rnd(32) cy:=Rnd(32) UNTIL matrix[(cy*32)+cx]=0 chunk:=Rnd(9)+1 cp:=Rnd(4) KsNotifyClients(krs,SNAKE_NEWCHUNK,Shl(chunk,24) OR Shl(cp,16) OR Shl(cy,8) OR cx) renderlink(cx,cy,FILL_FRUIT+cp) ENDPROC PROC transformhead(x,y,h) DEF p,nh p:=(y*32)+x nh:=matrix[p] SELECT nh CASE 5 SELECT h CASE 5 matrix[p]:=1 CASE 6 matrix[p]:=15 CASE 8 matrix[p]:=16 ENDSELECT CASE 6 SELECT h CASE 5 matrix[p]:=14 CASE 6 matrix[p]:=2 CASE 7 matrix[p]:=20 ENDSELECT CASE 7 SELECT h CASE 6 matrix[p]:=17 CASE 7 matrix[p]:=3 CASE 8 matrix[p]:=18 ENDSELECT CASE 8 SELECT h CASE 5 matrix[p]:=13 CASE 7 matrix[p]:=19 CASE 8 matrix[p]:=4 ENDSELECT ENDSELECT ENDPROC PROC transformtail(x,y) DEF p,h p:=(y*32)+x h:=matrix[p] SELECT 21 OF h CASE 1,5,13,14 matrix[p]:=9 CASE 2,6,15,17 matrix[p]:=10 CASE 3,7,19,20 matrix[p]:=11 CASE 4,8,16,18 matrix[p]:=12 ENDSELECT ENDPROC PROC movesnake() DEF alive=1,x,y,key key:=popkey() IF paused=1 IF key KsNotifyClients(krs,SNAKE_RESTARTED,fifol) WaitTOF() paused:=0 ELSE RETURN 1 ENDIF ENDIF IF playing=0 IF key=$40 resetgame() ELSE RETURN 0 ENDIF ENDIF IF (key>0) AND (key<11) speed:=key ELSE SELECT key CASE $4C IF (sy<>1) OR And(kp.flags,KPF_LETHAL180) sx:=0 sy:=-1 head:=8 ENDIF CASE $4D IF (sy<>-1) OR And(kp.flags,KPF_LETHAL180) sx:=0 sy:=1 head:=6 ENDIF CASE $4E IF (sx<>-1) OR And(kp.flags,KPF_LETHAL180) sx:=1 sy:=0 head:=5 ENDIF CASE $4F IF (sx<>1) OR And(kp.flags,KPF_LETHAL180) sx:=-1 sy:=0 head:=7 ENDIF CASE $45 killtask:=TRUE CASE $19 KsNotifyClients(krs,SNAKE_PAUSED,fifol) WaitTOF() paused:=1 ENDSELECT ENDIF hx:=hx+sx hy:=hy+sy SELECT 4 OF rexxwaitmode CASE 1 IF hx=rexxwait THEN rexxwaitmode:=0 IF rexxwaitmode=0 THEN rexxwait:=0 checkRexxCommands() CASE 2 IF hy=rexxwait THEN rexxwaitmode:=0 IF rexxwaitmode=0 THEN rexxwait:=0 checkRexxCommands() CASE 3 IF rexxwait>0 THEN DEC rexxwait IF rexxwait=0 THEN rexxwaitmode:=0 checkRexxCommands() DEFAULT rexxwait:=0 rexxwaitmode:=0 ENDSELECT IF (hx<0) OR (hx>31) OR (hy<0) OR (hy>31) OR (matrix[(hy*32)+hx]>0) OR (fifol>=1023) KsNotifyClients(krs,SNAKE_GAMEOVER,fifol) KsPlaySoundObject(crs) alive:=0 playing:=0 gameover:=1 keybufs:=1 keybufe:=0 keybufl:=0 rexxwait:=0 rexxwaitmode:=0 renderscore() ELSE KsNotifyClients(krs,SNAKE_MOVES,Shl(head,16) OR Shl(hy,8) OR hx) transformhead(fifox[fifoe],fifoy[fifoe],head) IF kp.fill[FILL_LINK].type=FILLTYPE_GRAPHIC THEN renderlink(fifox[fifoe],fifoy[fifoe],FILL_BACK) renderlink(fifox[fifoe],fifoy[fifoe],FILL_LINK) pushlink(hx,hy,head) renderlink(hx,hy,FILL_HEAD) IF (hx=cx) AND (hy=cy) KsNotifyClients(krs,SNAKE_EATEN,chunk) KsPlaySoundObject(efs) eaten:=eaten+chunk newchunk() ENDIF IF eaten eaten:=eaten-1 KsNotifyClients(krs,SNAKE_NEWSCORE,fifol) renderscore(TRUE,TRUE) ELSE x,y:=poplink() renderlink(x,y,FILL_BACK) transformtail(fifox[fifos],fifoy[fifos]) IF kp.fill[FILL_LINK].type=FILLTYPE_GRAPHIC THEN renderlink(fifox[fifos],fifoy[fifos],FILL_BACK) renderlink(fifox[fifos],fifoy[fifos],FILL_LINK) ENDIF ENDIF ENDPROC alive PROC resetgame(real=1) DEF i IF real KsNotifyClients(krs,SNAKE_NEWGAME,NIL) IF And(kp.flags,KPF_CONTSOUND)=0 THEN KsPlaySoundObject(bgs) ENDIF FOR i:=0 TO 1023 DO matrix[i]:=0 playing:=real fifos:=0 fifoe:=1 fifol:=2 fifox[0]:=15 fifoy[0]:=16 fifox[1]:=15 fifoy[1]:=15 matrix[(15*32)+15]:=8 matrix[(16*32)+15]:=12 sx:=0 sy:=-1 head:=8 chunk:=0 eaten:=0 hx:=15 hy:=15 cx:=-1 cy:=-1 gameover:=0 paused:=0 IF real newchunk() renderscore() rendersnake() ENDIF ENDPROC PROC waitimessage(win:PTR TO window) DEF msg:PTR TO intuimessage,icl=0,ico=0,sigs=0 DEF jpv IF visible WaitTOF() IF lowlevelbase jpv:=ReadJoyPort(1) AND JP_DIRECTION_MASK SELECT jpv CASE JPF_JOY_UP pushkey($4C) CASE JPF_JOY_DOWN pushkey($4D) CASE JPF_JOY_RIGHT pushkey($4E) CASE JPF_JOY_LEFT pushkey($4F) ENDSELECT ENDIF IF playing=0 THEN paused:=0 IF counter counter:=counter-1 ELSE counter:=speed playing:=movesnake() ENDIF WHILE KsGetNotifyEvent(krs,{icl},{ico}) SELECT icl CASE SNAKE_NEWPREFS killtask:=1 newprefs:=1 KsNotifyClients(krs,SNAKE_QUIT,NIL) ENDSELECT ENDWHILE WHILE (msg:=GetMsg(win.userport)) icl:=msg.class ico:=msg.code ReplyMsg(msg) SELECT icl CASE IDCMP_CLOSEWINDOW killtask:=TRUE CASE IDCMP_REFRESHWINDOW render() CASE IDCMP_NEWSIZE verifysize() render() CASE IDCMP_INACTIVEWINDOW IF playing KsNotifyClients(krs,SNAKE_PAUSED,fifol) paused:=1 ENDIF CASE IDCMP_RAWKEY IF ico=$45 THEN killtask:=TRUE pushkey(ico) ENDSELECT ENDWHILE sigs:=SetSignal(0,0) IF (sigs AND Shl(1,rexxPort.sigbit)) THEN checkRexxCommands() IF (sigs AND Shl(1,brokerPort.sigbit)) THEN checkCxPort() ELSE sigs:=Wait(Shl(1,appPort.sigbit) OR Shl(1,brokerPort.sigbit) OR Shl(1,rexxPort.sigbit)) IF (sigs AND Shl(1,rexxPort.sigbit)) THEN checkRexxCommands() IF (sigs AND Shl(1,brokerPort.sigbit)) THEN checkCxPort() IF (sigs AND Shl(1,appPort.sigbit)) THEN checkAppPort() ENDIF ENDPROC PROC checkCxPort() DEF msg:PTR TO mn,id,type WHILE (msg:=GetMsg(brokerPort)) id:=CxMsgID(msg) type:=CxMsgType(msg) SELECT type CASE CXM_IEVENT SELECT id CASE CXID_POPKEY IF visible THEN vanish() ELSE appear() ENDSELECT CASE CXM_COMMAND SELECT id CASE CXCMD_KILL killtask:=1 CASE CXCMD_DISAPPEAR IF visible THEN vanish() CASE CXCMD_APPEAR IF visible=0 THEN appear() CASE CXCMD_UNIQUE IF visible=0 THEN appear() ENDSELECT ENDSELECT ReplyMsg(msg) ENDWHILE ENDPROC PROC checkAppPort() DEF msg:PTR TO appmessage WHILE (msg:=GetMsg(appPort)) IF msg.numargs>0 DisplayBeep(NIL) ELSE appear() ENDIF ReplyMsg(msg) ENDWHILE ENDPROC PROC uffGetMsg(port,uff:PTR TO LONG) DEF m,s m,s:=rx_GetMsg(port) ^uff:=s ENDPROC m PROC checkRexxCommands() DEF msg,rc,a,b,st[32]:STRING,sr:PTR TO CHAR, ps:PTR TO LONG,cs[256]:STRING IF rexxwaitmode<>0 THEN RETURN WHILE (rexxwaitmode=0) AND (msg:=uffGetMsg(rexxPort,{ps})) rc:=0 sr:=0 StrCopy(cs,ps) UpperStr(cs) ps:=argSplit(cs) SELECT AREXX_MAX OF getRexxId(ps[0]) CASE AREXX_UP IF playing pushkey($4C) rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_DOWN IF playing pushkey($4D) rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_RIGHT IF playing pushkey($4E) rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_LEFT IF playing pushkey($4F) rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_QUIT killtask:=1 rc:=RC_OK CASE AREXX_NEWGAME IF playing=0 pushkey($40) rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_HIDE IF visible vanish() rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_SHOW IF visible=0 appear() rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_WAIT IF playing IF StrCmp(ps[1],'UNTIL') IF StrCmp(ps[2],'X') rexxwaitmode:=1 rexxwait:=Val(ps[3]) rc:=RC_OK ELSEIF StrCmp(ps[2],'Y') rexxwaitmode:=2 rexxwait:=Val(ps[3]) rc:=RC_OK ENDIF ELSEIF StrCmp(ps[1],'FOR') rexxwaitmode:=3 rexxwait:=Val(ps[2]) rc:=RC_OK ELSE rc:=RC_ERROR ENDIF ELSE rc:=RC_WARN ENDIF CASE AREXX_SET IF StrCmp(ps[1],'SPEED') speed:=Val(ps[2]) rc:=RC_OK ELSE rc:=RC_ERROR ENDIF CASE AREXX_GET IF StrCmp(ps[1],'FRUIT') IF StrCmp(ps[2],'X') StringF(st,'\d',cx) sr:=st rc:=RC_OK ELSEIF StrCmp(ps[2],'Y') StringF(st,'\d',cy) sr:=st rc:=RC_OK ELSE rc:=RC_ERROR ENDIF ELSEIF StrCmp(ps[1],'HEAD') IF StrCmp(ps[2],'X') StringF(st,'\d',hx) sr:=st rc:=RC_OK ELSEIF StrCmp(ps[2],'Y') StringF(st,'\d',hy) sr:=st rc:=RC_OK ELSE rc:=RC_ERROR ENDIF ELSEIF StrCmp(ps[1],'LENGTH') IF playing StringF(st,'\d',fifol) sr:=st rc:=RC_OK ELSE rc:=RC_WARN ENDIF ELSEIF StrCmp(ps[1],'PLAYING') StringF(st,'\d',playing) sr:=st rc:=RC_OK ELSE rc:=RC_ERROR ENDIF CASE AREXX_PAUSE IF playing KsNotifyClients(krs,SNAKE_PAUSED,fifol) paused:=1 rc:=RC_OK ELSE rc:=RC_WARN ENDIF CASE AREXX_CHECK IF playing b:=Val(ps[1]) a:=Val(ps[2]) StringF(st,'\d',matrix[Shl(a,5)+b]) sr:=st rc:=RC_OK ELSE rc:=RC_WARN ENDIF DEFAULT rc:=RC_ERROR ENDSELECT rx_ReplyMsg(msg,rc,sr) DisposeLink(ps) ENDWHILE ENDPROC PROC openKRSNAkeLib() DEF base=0:PTR TO lib base:=OpenLibrary('krsnake.library',1) IF base=0 THEN OpenLibrary('Libs/krsnake.library',1) IF base=0 THEN OpenLibrary('PROGDIR:Libs/krsnake.library',1) IF base IF base.revision<6 CloseLibrary(base) Throw("LIB",getstr(ERRORID_OLDKRSNAKELIB)) ENDIF ENDIF ENDPROC base PROC createBroker() brokerPort:=CreateMsgPort() broker:=CxBroker([NB_VERSION,0, 'KRSNAke',KRSNAKEVER, getstr(ID_BROKERINFO), NBU_UNIQUE,COF_SHOW_HIDE,0,0, brokerPort,0]:newbroker,NIL) AttachCxObj(broker,hotKey(kp.popkey,brokerPort,CXID_POPKEY)) ActivateCxObj(broker,TRUE) ENDPROC broker PROC initrexx() rexxPort:=rx_OpenPort('KRSNAKE') NEW rexxhash.hashtable(HASH_NORMAL) addRexxCommand('CHECK',AREXX_CHECK) addRexxCommand('DOWN',AREXX_DOWN) addRexxCommand('GET',AREXX_GET) addRexxCommand('HIDE',AREXX_HIDE) addRexxCommand('LEFT',AREXX_LEFT) addRexxCommand('NEWGAME',AREXX_NEWGAME) addRexxCommand('PAUSE',AREXX_PAUSE) addRexxCommand('QUIT',AREXX_QUIT) addRexxCommand('RIGHT',AREXX_RIGHT) addRexxCommand('SET',AREXX_SET) addRexxCommand('SHOW',AREXX_SHOW) addRexxCommand('UP',AREXX_UP) addRexxCommand('WAIT',AREXX_WAIT) ENDPROC PROC endrexx() IF rexxPort THEN rx_ClosePort(rexxPort) END rexxhash ENDPROC PROC addRexxCommand(cmd:PTR TO CHAR,id) DEF hl:PTR TO rexxcommand,hv hl,hv:=rexxhash.find(cmd,StrLen(cmd)) IF hl THEN RETURN FALSE NEW hl hl.id:=id rexxhash.add(hl,hv,cmd,StrLen(cmd)) ENDPROC PROC getRexxId(cmd:PTR TO CHAR) DEF hl:PTR TO rexxcommand hl:=rexxhash.find(cmd,StrLen(cmd)) IF hl=0 THEN RETURN 0 RETURN hl.id ENDPROC PROC appear() IF visible=0 IF appicon THEN RemoveAppIcon(appicon) IF appmenu THEN RemoveAppMenuItem(appmenu) appicon:=0;appmenu:=0 IF StrLen(kp.pubscreen) s:=LockPubScreen(kp.pubscreen) ELSE s:=LockPubScreen(NIL) ENDIF font:=OpenFont(s.font) dri:=GetScreenDrawInfo(s) dripens:=dri.pens th:=font.ysize IF wy=-1 THEN wy:=s.barheight+1 ww:=fw+8 wh:=fh+th+14 IF wantobtainpens THEN obtainpens() IF And(kp.flags,KPF_FREESOUNDS) THEN readsounds() w:=OpenWindowTagList(NIL,[WA_INNERWIDTH,ww,WA_INNERHEIGHT,wh, WA_LEFT,wx,WA_TOP,wy, WA_TITLE,'KRSNAke v1.17', WA_SIZEGADGET,TRUE, WA_DRAGBAR,TRUE, WA_DEPTHGADGET,TRUE, WA_CLOSEGADGET,TRUE, WA_ACTIVATE,TRUE, WA_SMARTREFRESH,TRUE, WA_SIZEBBOTTOM,TRUE, WA_GIMMEZEROZERO,TRUE, WA_NEWLOOKMENUS,TRUE, WA_SCREENTITLE,'KRSNAke v1.17 - IGNE NATURA RENOVATUR INTEGRA!', WA_AUTOADJUST,TRUE, WA_PUBSCREEN,s, WA_RMBTRAP,TRUE, WA_IDCMP,IDCMP_CLOSEWINDOW OR IDCMP_REFRESHWINDOW OR IDCMP_INACTIVEWINDOW OR IDCMP_NEWSIZE OR IDCMP_RAWKEY, NIL]) WindowLimits(w,w.borderleft+w.borderright+136,w.bordertop+w.borderbottom+th+142,-1,-1) SetStdRast(w.rport) SetFont(stdrast,font) render() visible:=1 IF krs THEN KsShowInterface(krs) IF And(kp.flags,KPF_CONTSOUND) THEN IF And(kp.flags,KPF_FREESOUNDS) THEN KsPlaySoundObject(bgs) ENDIF ENDPROC PROC vanish(forever=FALSE) IF visible IF w THEN CloseWindow(w) IF And(kp.flags,KPF_FREESOUNDS) THEN freesounds() IF pensobtained THEN freepens() IF dri THEN FreeScreenDrawInfo(s,dri) IF font THEN CloseFont(font) IF s THEN UnlockPubScreen(NIL,s) IF playing=1 THEN paused:=1 IF krs THEN KsHideInterface(krs) w:=0;pensobtained:=0;dri:=0;font:=0;s:=0;visible:=0 IF forever=0 IF And(kp.flags,KPF_APPICON) THEN appicon:=AddAppIconA(APPID_ICON,0,'KRSNAke',appPort,NIL,myicon,NIL) IF And(kp.flags,KPF_APPMENU) THEN appmenu:=AddAppMenuItemA(APPID_MENU,0,'KRSNAke',appPort,NIL) ENDIF ENDIF ENDPROC PROC main() HANDLE -> trapguru() randomise() IF (krsnakebase:=openKRSNAkeLib())=0 THEN Throw("LIB",'krsnake.library') IF (utilitybase:=OpenLibrary('utility.library',37))=0 THEN Throw("LIB",'utility.library') IF (cxbase:=OpenLibrary('commodities.library',37))=0 THEN Throw("LIB",'commodities.library') IF (iconbase:=OpenLibrary('icon.library',37))=0 THEN Throw("LIB",'icon.library') IF (workbenchbase:=OpenLibrary('workbench.library',37))=0 THEN Throw("LIB",'workbench.library') datatypesbase:=OpenLibrary('datatypes.library',39) localebase:=OpenLibrary('locale.library',37) openCatalog() IF (lowlevelbase:=OpenLibrary('lowlevel.library',40)) THEN SetJoyPortAttrsA(1,[SJA_TYPE,SJA_TYPE_JOYSTK,NIL]) myicon:=GetDiskObjectNew('PROGDIR:KRSNAke') krs:=KsRegisterServer() launchclients() readsettings() resetgame(0) SetTaskPri(FindTask(NIL),kp.priority) IF And(kp.flags,KPF_FREESOUNDS)=0 THEN readsounds() appPort:=CreateMsgPort() createBroker() initrexx() appear() IF And(kp.flags,KPF_CONTSOUND) THEN IF And(kp.flags,KPF_FREESOUNDS)=0 THEN KsPlaySoundObject(bgs) checkStubing() REPEAT waitimessage(w) UNTIL killtask dumpsettings() EXCEPT DO vanish(TRUE) closeCatalog() IF krs THEN KsRemoveServer(krs) IF rexxPort THEN endrexx() IF broker THEN DeleteCxObj(broker) IF brokerPort THEN deletePortSafely(brokerPort) IF appicon THEN RemoveAppIcon(appicon) IF appmenu THEN RemoveAppMenuItem(appmenu) IF appPort THEN deletePortSafely(appPort) IF myicon THEN FreeDiskObject(myicon) IF kp THEN FreeVec(kp) freesounds() IF krsnakebase THEN CloseLibrary(krsnakebase) IF localebase THEN CloseLibrary(localebase) IF utilitybase THEN CloseLibrary(utilitybase) IF iconbase THEN CloseLibrary(iconbase) IF workbenchbase THEN CloseLibrary(workbenchbase) IF cxbase THEN CloseLibrary(cxbase) IF lowlevelbase THEN CloseLibrary(lowlevelbase) IF datatypesbase THEN CloseLibrary(datatypesbase) IF exception>0 THEN report_exception() ELSE IF newprefs THEN RETURN reLaunch() ENDPROC PROC report_exception() DEF e[5]:ARRAY,s[256]:STRING,t[256]:STRING IF exception StrCopy(s,getstr(ERRORID_EXCEPTION)) IF exception<10000 StringF(t,' \d\n',exception) StrAdd(s,t) ELSE SELECT exception CASE "MEM"; StrCopy(t,getstr(ERRORID_MEM)) CASE "OPEN"; lStringF(t,getstr(ERRORID_OPEN),[IF exceptioninfo THEN exceptioninfo ELSE '']) CASE "LOCK"; lStringF(t,getstr(ERRORID_LOCK),[IF exceptioninfo THEN exceptioninfo ELSE '']) CASE "WIN"; lStringF(t,getstr(ERRORID_WIN),[IF exceptioninfo THEN exceptioninfo ELSE '']) CASE "LIB"; lStringF(t,getstr(ERRORID_LIB),[IF exceptioninfo THEN exceptioninfo ELSE '']) CASE "SCR"; lStringF(t,getstr(ERRORID_SCR),[IF exceptioninfo THEN exceptioninfo ELSE '']) CASE "^C"; StrCopy(t,getstr(ERRORID_BREAK)) CASE "DOUB"; StrCopy(t,getstr(ERRORID_DOUB)) CASE "SIG"; StrCopy(t,getstr(ERRORID_SIG)) CASE "CXBR"; StrCopy(t,getstr(ERRORID_CXBR)) DEFAULT e[4]:=0 ^e:=exception WHILE e[]=0 DO e++ StringF(t,IF exceptioninfo<1000 THEN '"\s" [\d]' ELSE '"\s" [\s]',e,exceptioninfo) ENDSELECT StrAdd(s,t) ENDIF EasyRequestArgs(NIL,[SIZEOF easystruct,0,getstr(ID_EXCEPTION),s,getstr(ABOUTID_OK)],NIL,NIL) ENDIF ENDPROC PROC reLaunch() DEF p[1024]:ARRAY OF CHAR,n[256]:ARRAY OF CHAR NameFromLock(GetProgramDir(),p,1024) IF GetProgramName(n,256)=0 THEN StrCopy(n,'KRSNAke') AddPart(p,n,1024) RETURN launchClient(p) ENDPROC PROC checkStubing() DEF cd:PTR TO clockdata,secs:LONG,micros:LONG NEW cd CurrentTime({secs},{micros}) Amiga2Date(secs,cd) IF (cd.mday=28) AND (cd.month=2) THEN EasyRequestArgs(NIL,[SIZEOF easystruct,0,'Halelujah!','Today, Gavin MacLeod is %ld years old!\n\nHappy Birthday, Captain Stubing!','Rejoice!'],NIL,[cd.year-1930]) IF (cd.mday=8) AND (cd.month=1) THEN EasyRequestArgs(NIL,[SIZEOF easystruct,0,'Elvis be praised!','Today the King is %ld years old!\nEnter your congratulation in alt.elvis.king now!','You ain''t nuthin'' but a hound dog!'],NIL,[cd.year-1935]) IF (cd.mday=13) AND (cd.month=10) THEN EasyRequestArgs(NIL,[SIZEOF easystruct,0,'Fnord!','On this very day, %ld years ago,\nJacques de Molay was arrested!','Good riddance!'],NIL,[cd.year-1307]) END cd ENDPROC krsnakever: CHAR '$VER: KRSNAke 1.017 (22 Feb 1996)',0