<*+M2EXTENSIONS *> <*-CHECKDIV *> <*-CHECKRANGE *> <*-GENFRAME*> <*+NOPTRALIAS*> <*-DOREORDER*> <*-GENPTRINIT*> <*HEAPLIMIT="1000000000"*> <*CPU="PENTIUM"*> <*NEW WITHHTML*> <*NEW SAVESTAT *> <*NEW MYMATH *> <*-MYMATH *> <* IF TARGET_FAMILY="WIN32" THEN *> <*-WITHHTML*> <*-SAVESTAT*> <* ELSIF TARGET_FAMILY="UNIX" THEN *> <*-WITHHTML*> <*-SAVESTAT*> <* END *> MODULE aprsmap; (* aprs tracks on osm map by oe5dxl *) FROM SYSTEM IMPORT FILL, ADR, INT16, INT8, CAST, MOVE, CARD8, CARD16, SHIFT; FROM useri IMPORT refresh, redraw, CONFSET, killallmenus, saveconfig, CURSDOWN, CURSLEFT, CURSUP, CURSRIGHT, CURSBS, CURSENTER, CMDRDLOG, CMDFZOOMOUT, CMDFZOOMIN, CMDZOOMSQUARE, CMDVIDEO, CMDDOWNLOAD, CMDSTARTDOWNLOAD, CMD1USER, CMD1USERRF, CMDANIMATE1, CMDANIMATEMENU, CMDINTERNSTAT, CMDFIND, CMDDELWAYPOINT, CMDMH, CMDLISTWINLINE, CMDRADIORANGE, CMDCLICKWATCH, CURSHOME, CMDRESETIMGPARMS, CFGHEARD, CFGRAWDECODED, CMDCENTER, CMDCENTERMOUSE, CMDSETMARK1LOCK, CMDSETMARK2LOCK, CONFPOISYMFIND, SCREENSHOT, mainpop, conf2int, textautosize, newxsize, newysize, postoconfig, killmenuid, initmenus, loadconfig, textautomenu, ColConfset, sayonoff, debugmem, getview, refrinfo, localtime, refrlog, isblown, confstr, confappend, configon, configbool, AddConfLine, setcfg, clrconfig, starthint, Setmap, helptext, saveXYtocfg, maximized, getstartxysize, copypaste, conf2real, guesssize, hoverinfo, say, MINMHZ, ALTINVAL, gpsalt, confflags, textbubble, mapbritocfg, findopl, popwatchcall, allocimage, panoimage, xmouse, mainys, rdonesymb, DOCKX, int2cfg, BRIMUL, resetimgparms, beaconediting, beaconed, poligonmenu, DEFAULTLUMOBJ, CMDZOOMTOMARKS, cMULTISYMBOL, MAXANTALT, CMDFOLLOW, anywatchfollow, keychar, DoDirectConf; FROM osi IMPORT WrStr, WrStrLn, WrInt, FdValid, InvalidFd, File, Exists, RdBin, WrBin, Close, OpenRead, OpenReadLong, OpenWrite, floor, power, pi, sqrt, exp, ln, Seekcur, Seek, Erase, DIRSEP, DIRSEP2, time, ALLOCATE, DEALLOCATE; FROM xosi IMPORT Eventloop, InitX, allocxbuf, Shift, Ctrl, Gammatab, closewin, pulling, StopProg, WrHeadline, headmh; FROM maptool IMPORT pIMAGE, IMAGE, xsize, ysize, waypoint, vector, mercator, mapxy, drawsym, drawstr, shine, loadmap, addmap, SimpleRelief, drawpois, shiftx, shifty, xytodeg, cc, area, shiftmap, center, saveppm, POIfind, Colset, startmapdelay,limpos, makebw, realzoom, setmark, cleanfind, cmpwild, zoominout, IsMapLoaded, clr, loadfont, vistime, drawarrow, ruler, POIname, FLOATERRCORR, StartMapPackage, mappack, MINZOOM, MAXZOOM, geoprofile, Radiorange, drawareasym, drawpoligon, drawpoliobj, findmultiline, poisactiv; FROM aprsdecode IMPORT DAT, TYPES, Decode, Stoframe, lums, finezoom, parmzoom, initparms, quit, parmfinezoom, tracenew, click, ERRSET, ERRFLAGS, FRAMEBUF, LF, systime, realtime, MONCALL, initzoom, CLICKTYPS, MAPNAME, inittilex, inittiley, mappos, pVARDAT, purge, initxsize, Checktracks, DEGSYM, DRAWHINTS, sDRAWHINTS, lasttcprx, updateintervall, initysize, pOPHIST, pFRAMEHIST, ophist, ophist2, trunc, COLTYP, delwaypoint, tcpconnstat, udpsocks, DELETSYM, SYMBOL, CLICKOBJECT, lastanyudprx, objsender, udpconnstat, beeplim, Stopticker, SHOWTEMPWIND, maploadpid, serialpid, serialpid2, MINTEMP, MAXTEMP, rxidle, lastlooped, mountains, pMOUNTAIN, FILENAME, BEGINOFTIME, ismultiline, STORM, AREASYMB, SYMBOLSET, MAPGAMMATAB, logdone, WITHX11, FOLLOWX, FOLLOWWATCH, autoshots, Watchclock; FROM aprspos IMPORT distance, posvalid, KNOTS, PI2, RAD, azimuth, SKNOTS; FROM aprsstr IMPORT POSITION, IntToStr, Append, Assign, DateToStr, FixToStr, Length, posinval, TimeToStr, StrToTime, TIME, cleanfilename, InStr, loctopos, StrToFix, StrCmp; FROM aprstext IMPORT strcp, measure, postostr, deganytopos, getmypos, DateLocToStr, oppo, setmark1, setmarkalti, TEXTCOLLGR, TEXTCOLEND, logfndate; FROM libsrtm IMPORT closesrtmfile, srtmmem; <* IF TARGET_FAMILY="UNIX" THEN *> FROM signal IMPORT signal, SIGTERM, SIGINT, SIGPIPE; <* END *> CONST MINLIG=60; MAXZOOMOBJ=14; MAXCOLORS=10; MINCOLOR=ORD("0"); MAPGETTIMEOUT=30; HISTSIZE=20; VIDEOFN="map.y4m"; VIDEORATE=25; MARKERTIME=10; (* marker life time for unimportant marker settings *) NOSYMT="/"; NOSYMB="/"; (* show this symbol if user has none *) HOVERDIST=0.2; (* part of symbol size *) POIINFOWINID=190; MINPOIINFOTIME=10; (* min opentime for poi info window *) POIINFOREADSPEED=20; (* characters per second extra readtime for poi info *) TYPE SET8=SET OF [0..7]; SET16=SET OF [0..15]; SET32=SET OF [0..31]; VIDBUF=ARRAY[0..10000000] OF CHAR; MHOPS=(OPHEARD, OPSENT, OPOBJ); VIEW=RECORD pos:POSITION; zoom:REAL; mhop:MONCALL; onesymbol:SYMBOL; onesymbolset:SYMBOLSET; rf:INTEGER; mhtxv:MHOPS; wxcol:CHAR; lumtrack, lumwaypoint, lummap, lumsym, lumobj, lumtext:INTEGER; mapname:MAPNAME; maplumcorr:MAPGAMMATAB; -- altimap, focus:BOOLEAN; findpush:BOOLEAN; END; TABS=RECORD stkpo,stktop:CARDINAL; posstk:ARRAY[0..HISTSIZE-1] OF VIEW; END; VAR image, rfimg:pIMAGE; shottrigg, withx:BOOLEAN; lastxupdate, maptime, laststatref, realday, makeimagetime:TIME; cycleorder, maptrys:CARDINAL; uptime:TIME; newpos0, newpos1:POSITION; videofd:File; gammatab:ARRAY[0..1023] OF CHAR; mhtx:MHOPS; pandone, onetipp:BOOLEAN; tabview, alttabview:TABS; vidbuf:POINTER TO VIDBUF; mestxt:ARRAY[0..200] OF CHAR; radio:RECORD wasaltimap, wasradio :BOOLEAN; markpos, measurepos,mappos:POSITION; initzoom :INTEGER; finezoom :REAL; ant1, ant2, ant3 :INTEGER; bri, contr :INTEGER; qual :INTEGER; refrac :REAL; c1, c2 :COLTYP; END; clickwatchpos:POSITION; autoshottime:TIME; batchp, batchlen:CARDINAL; batchbuf:ARRAY[0..9999] OF CHAR; PROCEDURE Error(text:ARRAY OF CHAR); BEGIN WrStr(text); WrStrLn(" error abort"); HALT END Error; PROCEDURE sqr(x:REAL):REAL; BEGIN RETURN x*x END sqr; PROCEDURE makegammatab; VAR i:CARDINAL; PROCEDURE gammac(c:CARDINAL):CARDINAL; CONST GAMMA=1.0/2.2; BEGIN IF c=0 THEN RETURN 0 END; IF c<1024 THEN RETURN trunc(exp(ln(FLOAT(c)/1024.0)*GAMMA)*255.5) END; RETURN 255 END gammac; BEGIN FOR i:=0 TO HIGH(gammatab) DO gammatab[i]:=CHR(gammac(i)) END; END makegammatab; PROCEDURE tooltips(typ:CHAR); VAR s:ARRAY[0..20] OF CHAR; pos:POSITION; BEGIN IF typ=" " THEN IF (initzoom<=1) & (uptime+2=realtime) THEN starthint(10005, TRUE) END; ELSIF typ="n" THEN IF configon(fCONNECT) & (uptime+60>realtime) THEN confstr(fSERVERFILT, s); IF (CAP(s[0])="M") & NOT (getmypos(pos) & configon(fALLOWNETTX)) THEN starthint(10007, TRUE) ELSE starthint(10006, TRUE) END; END; ELSIF typ="m" THEN IF uptime+180>realtime THEN starthint(10010, TRUE) END; ELSIF typ="b" THEN IF NOT onetipp THEN starthint(10015, TRUE) END; onetipp:=TRUE; ELSIF typ="B" THEN IF NOT onetipp THEN starthint(10016, TRUE) END; onetipp:=TRUE; END; END tooltips; PROCEDURE mapbri(v:INTEGER); VAR s,h:ARRAY[0..99] OF CHAR; BEGIN INC(v, VAL(CARDINAL, lums.map)/BRIMUL); IF v<0 THEN v:=0 ELSIF v>100 THEN v:=100 END; lums.map:=v*BRIMUL; int2cfg(fLMAP, v); mapbritocfg; s:="Brightness Map "; IntToStr(v, 1, h); Append(s, h); Append(s, "%"); say(s, 4, "b"); END mapbri; PROCEDURE fullbritime(down:BOOLEAN); VAR s,h:ARRAY[0..99] OF CHAR; d,n:CARDINAL; BEGIN d:=60*30; IF lums.firstdim<60*15 THEN d:=60 ELSIF lums.firstdim<60*60 THEN d:=60*5 ELSIF lums.firstdim<60*60*3 THEN d:=60*15 END; n:=lums.firstdim DIV d; IF down THEN IF n>1 THEN DEC(n) END; ELSE INC(n) END; lums.firstdim:=n*d; IF lums.firstdim>lums.purgetime THEN lums.firstdim:=lums.purgetime END; int2cfg(fTFULL, lums.firstdim DIV 60); s:="Fullbright Time "; IntToStr(lums.firstdim DIV 60, 1, h); Append(s, h); Append(s, "Min"); say(s, 4, "b"); END fullbritime; PROCEDURE movest(width:CARDINAL):REAL; BEGIN RETURN power(2.0, -realzoom(initzoom, finezoom))*FLOAT(width)*FLOAT(lums.movestep)*0.0002; END movest; PROCEDURE shiftfine():REAL; VAR s:REAL; BEGIN IF Shift THEN s:=0.1 ELSE s:=1.0 END; IF configon(fINVMOV) THEN s:=-s END; RETURN s END shiftfine; PROCEDURE rdlogdate(s-:ARRAY OF CHAR; VAR t:TIME; VAR p:CARDINAL):BOOLEAN; (* 20130526:235959 *) CONST MON=ARRAY OF TIME {0,0,31,59,90,120,151,181,212,243,273,304,334}; VAR i:CARDINAL; d, y:TIME; c:CHAR; dt:BOOLEAN; (* second since 1970 or yyyymmdd:hhmmss *) BEGIN dt:=s[8]=":"; i:=0; d:=0; LOOP c:=s[i]; IF (c<"0") OR (c>"9") THEN EXIT END; d:=d*10+ORD(c)-ORD("0"); INC(i); IF dt THEN IF i=4 THEN (* year *) IF (d<1970) OR (d>2100) THEN RETURN FALSE ELSE t:=((d-1970)*365 + (d-1969) DIV 4) END; (* days since 1970 *) y:=d; d:=0; ELSIF i=6 THEN (* month *) IF d>12 THEN RETURN FALSE END; INC(t, MON[d]); IF (y MOD 4=0) & (d>2) THEN INC(t) END; d:=0; ELSIF i=8 THEN (* day *) IF d<=0 THEN RETURN FALSE ELSE t:=(t+d-1)*(60*60*24); INC(i); d:=0 END; ELSIF i=11 THEN INC(t, d*(60*60)); d:=0; ELSIF i=13 THEN INC(t, d*60); d:=0; ELSIF i=15 THEN INC(t, d); EXIT ELSIF i>15 THEN RETURN FALSE END; END; END; IF NOT dt THEN t:=d END; p:=i; RETURN TRUE END rdlogdate; PROCEDURE cmpcall(a-:ARRAY OF CHAR; i:CARDINAL; b-:ARRAY OF CHAR):BOOLEAN; VAR j:CARDINAL; BEGIN j:=0; REPEAT IF a[i]<>b[j] THEN RETURN FALSE END; INC(i); INC(j); UNTIL b[j]=0C; RETURN a[i]=">" END cmpcall; PROCEDURE rdlonglog(VAR optab:pOPHIST; fn:ARRAY OF CHAR; from, to:TIME; VAR firstread, lastread:TIME; VAR lines:INTEGER); CONST MINSTEP=5000; (* stop binary search *) SEEKBUF=1024; (* buffer size while binary search *) RETR=200; (* if unsort file break binary search *) VAR fc:File; rp, len, ret:INTEGER; ib:ARRAY[0..32767] OF CHAR; wp, i, j:CARDINAL; mbuf:FRAMEBUF; start, end, ot:TIME; op:pOPHIST; dat:DAT; lfc:CARDINAL; new:BOOLEAN; PROCEDURE binseek(time:TIME; bof:BOOLEAN; VAR first, last:TIME); VAR rp, len, seekstep:INTEGER; sb:ARRAY[0..1023] OF CHAR; mbuf:FRAMEBUF; lfc, retry:CARDINAL; ftime:TIME; BEGIN retry:=0; first:=0; last:=0; seekstep:=MAX(INTEGER) DIV 2; LOOP len:=0; rp:=0; wp:=0; IF bof THEN lfc:=2 ELSE lfc:=0 END; bof:=FALSE; LOOP IF rp>=len THEN len:=RdBin(fc, sb, SIZE(sb)); rp:=0; END; IF len<=0 THEN lfc:=0; EXIT END; mbuf[wp]:=sb[rp]; IF mbuf[wp]=LF THEN mbuf[wp]:=0C; wp:=0; INC(lfc); IF lfc>=2 THEN EXIT END; ELSIF wp=2) & rdlogdate(mbuf, ftime, i) THEN (* we are in file *) IF first=0 THEN first:=ftime; IF timelast THEN last:=ftime END; ELSE ftime:=MAX(TIME) END; (* we are behind eof *) IF (ftime=0) & (seekstep=RETR) THEN EXIT END; Seekcur(fc, seekstep-VAL(INTEGER,SIZE(sb))); INC(retry); END; IF time<=first THEN Seek(fc, 0); ELSIF retry>=RETR THEN Seek(fc, 0); say("unsort logfile, trying linear search", 180, "r"); -- WrStrLn("unsort logfile, trying linear search"); ELSE Seekcur(fc, -MINSTEP-VAL(INTEGER,SIZE(sb))) END; (* set back for safety *) END binseek; BEGIN lines:=0; cleanfilename(fn); IF fn[0]=0C THEN RETURN END; fc:=OpenReadLong(fn); IF NOT FdValid(fc) THEN RETURN END; firstread:=0; lastread:=0; end:=0; IF from>0 THEN binseek(from, TRUE, start, end); IF from>end THEN from:=end END; IF from=len THEN len:=RdBin(fc,ib,SIZE(ib)); IF len<=0 THEN EXIT END; rp:=0; END; mbuf[wp]:=ib[rp]; IF mbuf[wp]=LF THEN INC(lfc); mbuf[wp]:=0C; IF (lfc>=2) & rdlogdate(mbuf, start, i) & (start>=from) THEN IF firstread=0 THEN firstread:=start END; IF from=to THEN EXIT END; -- systime:=start; INC(i); j:=0; REPEAT mbuf[j]:=mbuf[i]; INC(j); INC(i); UNTIL (i>=HIGH(mbuf)) OR (mbuf[i]=0C); mbuf[j]:=0C; IF Decode(mbuf, dat)>=0 THEN systime:=lastread; ret:=Stoframe(optab, mbuf, start, TRUE, ot, dat); INC(lines); IF firstread=0 THEN firstread:=start END; lastread:=start; END; END; wp:=0; ELSIF wpNIL DO Checktrack(op, NIL); op:=op^.next; END; *) Checktracks; END rdlonglog; PROCEDURE filepath(VAR s:ARRAY OF CHAR); (* get path out of path + filename *) VAR i, j:CARDINAL; BEGIN i:=0; j:=0; WHILE (i0C) DO IF (s[i]=DIRSEP) OR (s[i]=DIRSEP2) THEN j:=i END; (* strip off at last dir separator *) INC(i); END; s[j]:=0C; END filepath; PROCEDURE logpathok(fn:ARRAY OF CHAR; VAR s:ARRAY OF CHAR); BEGIN filepath(fn); IF (fn<>"") & NOT Exists(fn) THEN Assign(s, "Directory ["); Append(s, fn); Append(s,"] not found or readable"); END; END logpathok; PROCEDURE rdlog(VAR optab:pOPHIST; fn:ARRAY OF CHAR; from, to:TIME; find:ARRAY OF CHAR; VAR firstread, lastread:TIME; VAR lines:INTEGER); VAR fc:File; rp, len, ret:INTEGER; ib:ARRAY[0..32767] OF CHAR; s:ARRAY[0..99] OF CHAR; wp, i, j:CARDINAL; mbuf:FRAMEBUF; op:pOPHIST; dat:DAT; t, start, ot:TIME; fnn, fnd:FILENAME; fo:BOOLEAN; BEGIN firstread:=0; lastread:=0; lines:=-1; (* file not found *) cleanfilename(fn); IF fn[0]=0C THEN RETURN END; Assign(fnn, fn); (* check if dayly log *) fnd:=fnn; logfndate(from, fnd); IF fnd=fnn THEN IF find[0]<>0C THEN textautosize(0, 0, 5, 6, "e", LF+"Call search only in dayly-Log Mode"+LF) END; rdlonglog(optab, fn, from, to, firstread, lastread, lines); (* single log file mode *) RETURN END; --WrInt(to-from, 10); WrStrLn(fnd); find[HIGH(find)]:=0C; len:=0; rp:=0; wp:=0; t:=from; Assign(fnn, fn); fo:=FALSE; click.abort:=FALSE; LOOP WHILE rp>=len DO IF lento THEN EXIT END; fnd:=fnn; logfndate(t, fnd); t:=(t DIV (3600*24)+1)*(3600*24); IF fo THEN Close(fc) END; fc:=OpenRead(fnd); UNTIL FdValid(fc); fo:=TRUE; IF lines<0 THEN lines:=0 END; (* file found *) END; say(fnd, 0, "b"); len:=RdBin(fc,ib,SIZE(ib)); rp:=0; END; mbuf[wp]:=ib[rp]; IF mbuf[wp]=LF THEN mbuf[wp]:=0C; IF rdlogdate(mbuf, start, i) & (start>=from) THEN IF (find[0]=0C) OR cmpcall(mbuf, i+1, find) THEN IF start>=to THEN EXIT END; INC(i); j:=0; REPEAT mbuf[j]:=mbuf[i]; INC(j); INC(i); UNTIL (i>=HIGH(mbuf)) OR (mbuf[i]=0C); mbuf[j]:=0C; IF Decode(mbuf, dat)>=0 THEN systime:=lastread; ret:=Stoframe(optab, mbuf, start, TRUE, ot, dat); INC(lines); IF (lines MOD 500=0) & (realtime+2NIL DO Checktrack(op, NIL); op:=op^.next; END; *) Checktracks; END; END rdlog; PROCEDURE moving(op:pOPHIST):BOOLEAN; BEGIN WITH op^ DO RETURN (NOT lums.moving) OR (lastinftyp>0) & (lastinftyp<100) & (lastkmh>0) & (systimeVAL(TIME,lums.maxdim) THEN t0:=lums.maxdim END; IF lums.maxdim>0 THEN l:=MINLIG + (256-MINLIG)*(VAL(TIME,lums.maxdim)-t0) DIV VAL(TIME,lums.maxdim); ELSE l:=256 END; RETURN l END fade; (* PROCEDURE runaway(x0,y0,x1,y1:REAL); BEGIN IF (x0<0.0)<>(x1<0.0) THEN y0:=y0+(y1-y0)*x0/(x1-x0); x0:=0; ELSIF (x0(x1(y1<0.0) THEN x0:=x0+(x1-x0)*y0/(y1-y0); y0:=0; ELSIF (y0(y1NIL DO IF (op^.trackcol>=MINCOLOR) & (op^.trackcol0C) DO INC(c, ORD(opn^.call[i])); INC(i) END; c:=c MOD MAXCOLORS; (* checksum default color *) IF c IN cs THEN (* color in use *) n:=0; max:=0; imax:=0; FOR i:=0 TO MAXCOLORS-1 DO IF i IN cs THEN n:=0; ELSE INC(n); (* count free colors *) IF n>max THEN max:=n; imax:=i END; END; END; IF max>0 THEN c:=imax-max DIV 2 END; (* middle of free colors *) END; c:=c MOD MAXCOLORS + MINCOLOR; END; RETURN c END findfreecol; PROCEDURE changecolor(op:pOPHIST); BEGIN IF (op<>NIL) & (op^.trackcol>=MINCOLOR) THEN op^.trackcol:=(op^.trackcol-MINCOLOR+1) MOD (MAXCOLORS+1)+MINCOLOR; END; END changecolor; PROCEDURE isvis(vismask-:sDRAWHINTS):BOOLEAN; BEGIN WITH click.ops^ DO RETURN (drawhints*vismask<>sDRAWHINTS{}) & (sym.tab<>DELETSYM) & vistime(lasttime) & ((lums.wxcol=0C) OR (lastinftyp>=100) & (temptime+SHOWTEMPWIND>systime)) END; END isvis; PROCEDURE isdrivespeed(inf:CARD8):BOOLEAN; BEGIN RETURN (inf>=10) & (inf<100) END isdrivespeed; PROCEDURE IsTrackObj(op:pOPHIST):BOOLEAN; VAR f:pFRAMEHIST; dat:DAT; BEGIN IF NOT (ISOBJECT IN op^.drawhints) OR isdrivespeed(op^.lastinftyp) THEN RETURN TRUE END; f:=op^.frames; WHILE f<>NIL DO IF (Decode(f^.vardat^.raw, dat)>=0) & ((dat.speed>0) & (dat.speed0)) THEN RETURN TRUE END; (* draw track if has any speed or course *) f:=f^.next; END; RETURN FALSE (* object with no speed or course *) END IsTrackObj; PROCEDURE tracks(img:pIMAGE; op:pOPHIST; tilltime:TIME); CONST MAXDIST=500000.0; MINWPDIST=0.04; (* waypoints on tracks minimum distance *) VAR x0,y0,x1,y1,radius, wpdist:REAL; lig, ligw, thick:CARDINAL; oldpos:POSITION; col:COLTYP; coln:INT8; nfilt, otrk:BOOLEAN; BEGIN click.ops:=op; click.typ:=tTRACK; nfilt:=NOT configon(fTRACKFILT); otrk:=configon(fOBJTRACK); thick:=lums.symsize*28; radius:=FLOAT(lums.symsize)*0.11; wpdist:=sqr(FLOAT(lums.symsize))*MINWPDIST; WHILE click.ops<>NIL DO IF isvis(sDRAWHINTS{MARKED, MOVES}) & (click.ops^.trackcolNIL) & (click.pf^.time<=tilltime) DO WITH click.pf^.vardat^ DO IF (nfilt OR (click.pf^.nodraw<=ERRSET{eDIST})) & posvalid(pos) & vistime(click.pf^.time) THEN IF posvalid(oldpos) THEN lig:=fade(click.pf^.time, click.ops)*600 DIV 256; IF (mapxy(oldpos, x0, y0)>=-1) & (mapxy(pos, x1, y1)>=-1) & (sqr(x0-x1)+sqr(y0-y1)>=wpdist) THEN (* collect short tracks to 1 *) click.ops^.trackcol:=coln; ligw:=lig*VAL(CARDINAL, lums.waypoint) DIV 1024; lig:=lig*VAL(CARDINAL, lums.track) DIV 1024; vector(img, x0, y0, x1, y1, lig*col.r DIV 256, lig*col.g DIV 256, lig*col.b DIV 256, thick, 0.0); IF NOT click.dryrun THEN waypoint(img, x0, y0, radius, ligw,ligw,ligw) END; oldpos:=pos; click.pf0:=click.pf; ELSE click.pf0:=click.pf END; ELSE oldpos:=pos; click.pf0:=click.pf END; END; END; click.pf:=click.pf^.next; END; click.pf0:=NIL; END; click.ops:=click.ops^.next; END; END tracks; PROCEDURE stormcicle(image:pIMAGE; center:POSITION; hurr, storm, whole:REAL; lig:CARDINAL); VAR asymb:AREASYMB; BEGIN asymb.dpos.long:=0.0; IF hurr<>0.0 THEN asymb.typ:="5"; (* circle *) asymb.color:=4; asymb.dpos.lat:=hurr*(PI2*SKNOTS/40000.0); drawareasym(image, center, asymb, lig); END; IF storm<>0.0 THEN asymb.typ:="5"; (* circle *) asymb.color:=1; asymb.dpos.lat:=storm*(PI2*SKNOTS/40000.0); drawareasym(image, center, asymb, lig); END; IF whole<>0.0 THEN asymb.typ:="0"; (* circle *) asymb.color:=0; asymb.dpos.lat:=whole*(PI2*SKNOTS/40000.0); drawareasym(image, center, asymb, lig); END; END stormcicle; PROCEDURE tolastframe(VAR pfm:pFRAMEHIST); BEGIN IF pfm=NIL THEN pfm:=click.ops^.frames; IF pfm<>NIL THEN WHILE pfm^.next<>NIL DO pfm:=pfm^.next END; END; END; END tolastframe; PROCEDURE symbols(op:pOPHIST; objects:BOOLEAN; VAR hoverobj:CLICKOBJECT); VAR x, y, hd, hdmin, hoverx, hovery, hoverdist:REAL; lig:CARDINAL; col:COLTYP; dat:DAT; pfm:pFRAMEHIST; BEGIN hoverdist:=FLOAT(lums.symsize*lums.symsize)*HOVERDIST; (* hover radius^2 *) click.ops:=op; IF objects THEN click.typ:=tOBJECT ELSE click.typ:=tSYMBOL END; hdmin:=MAX(REAL); hoverx:=VAL(REAL, xmouse.x); hovery:=VAL(REAL, mainys())-VAL(REAL, xmouse.y); IF click.entries>0 THEN pfm:=click.table[click.selected].pff0 ELSE pfm:=NIL END; (* to step thru multiline path *) WHILE click.ops<>NIL DO IF isvis(sDRAWHINTS{MARKED}) & ((ISOBJECT IN click.ops^.drawhints)=objects) & (mapxy(click.ops^.lastpos, x, y)>=0) THEN hd:=(x-hoverx)*(x-hoverx) + (y-hovery)*(y-hovery); (* dist mouse to symbol *) IF hd0C THEN IF pfm=NIL THEN drawareasym(image, click.ops^.lastpos, click.ops^.areasymb, lig); ELSE IF Decode(pfm^.vardat^.raw, dat)>=0 THEN drawareasym(image, dat.pos, dat.areasymb, lig) END; END; ELSIF click.ops^.poligon THEN tolastframe(pfm); IF (pfm<>NIL) & (Decode(pfm^.vardat^.raw, dat)>=0) THEN drawpoligon(image, dat.pos, dat.multiline, dat.symt, dat.sym, lig); END; ELSE drawsym(image, click.ops^.sym.tab, click.ops^.sym.pic, MIRRORSYM IN (click.ops^.drawhints), floor(x),floor(y), lig); IF click.ops^.sym.pic="@" THEN (* storm circles *) tolastframe(pfm); IF (pfm<>NIL) & (Decode(pfm^.vardat^.raw, dat)>=0) & (dat.wx.storm>WXNORMAL) THEN stormcicle(image, dat.pos, dat.wx.radiushurr, dat.wx.radiusstorm, dat.wx.wholegale, lig); END; END; END; IF click.ops^.lastkmh>0 THEN IF isdrivespeed(click.ops^.lastinftyp) THEN IF configon(fARROW) & (click.ops^.lasttime+lums.kmhtime>systime) THEN col.r:=500; col.g:=500; col.b:=0; drawarrow(image, x, y, FLOAT(lums.symsize)+6.0, FLOAT(click.ops^.lastinftyp-10)*(-4.0*pi/180.0), 0, lig, col); END; ELSIF (click.ops^.lastinftyp>=110) & (click.ops^.lastinftyp<200) THEN IF configon(fWINDSYM) & (click.ops^.temptime+SHOWTEMPWIND>systime) THEN col.r:=0; col.g:=400; col.b:=400; drawarrow(image, x, y, FLOAT(lums.symsize)+3.0, FLOAT(click.ops^.lastinftyp-110)*(-4.0*pi/180.0), click.ops^.lastkmh, lig, col); END; END; END; END; click.ops:=click.ops^.next; END; END symbols; PROCEDURE clbcolset(VAR c:COLTYP; clb:INTEGER); (* show more red/green altitude text on "Clb=" *) CONST MINUP=240; MINDOWN=160; BEGIN c.b:=0; c.r:=256; c.g:=256; (* yellow no clb *) IF clb>0 THEN clb:=clb*10; IF clb>MINUP THEN clb:=MINUP END; c.r:=MINUP-clb; ELSIF clb<0 THEN clb:=-clb; IF clb>MINDOWN THEN clb:=MINDOWN END; c.g:=MINDOWN-clb; END; END clbcolset; PROCEDURE timestr(VAR s:ARRAY OF CHAR; t:TIME); VAR h:ARRAY[0..20] OF CHAR; ts:TIME; BEGIN IF t<86400 THEN Append(s, " ["); ts:=t MOD 3600; IF t>=3600 THEN IntToStr(t DIV 3600, 1, h); Append(s, h); Append(s,"h") END; IF ts>=60 THEN IntToStr(ts DIV 60, 1, h); Append(s, h); Append(s,"m") END; IF t<3600 THEN IntToStr(t MOD 60, 1, h); Append(s, h); Append(s,"s") END; Append(s, "]"); END; END timestr; PROCEDURE text(op:pOPHIST; yesno, objmove, withvalues:BOOLEAN); VAR x,y:REAL; lig, lumtext:CARDINAL; s, s1:ARRAY[0..255] OF CHAR; col, colw, colo:COLTYP; fix, object, temponly:BOOLEAN; BEGIN temponly:=(lums.wxcol<>0C) & (lums.text=0); (* labels off but wxonly *) IF temponly THEN lumtext:=700 ELSE lumtext:=lums.text END; click.ops:=op; ColConfset(colw, fCOLMAPTEXT); ColConfset(colo, fCOLOBJTEXT); WHILE click.ops<>NIL DO object:=ISOBJECT IN click.ops^.drawhints; IF isvis(sDRAWHINTS{MARKED}) & (objmove & (object=yesno) OR NOT objmove & (moving(click.ops)=yesno)) & (mapxy(click.ops^.lastpos, x, y)>=0) THEN lig:=fade(click.ops^.lasttime, click.ops)*VAL(CARDINAL, lumtext) DIV 256; IF object THEN IF lig>VAL(CARDINAL,lums.obj) THEN lig:=lums.obj END; col:=colo; ELSE col:=colw END; fix:=click.dryrun; click.typ:=tTEXT; Assign(s, click.ops^.call); IF configon(fTIMESTAMP) THEN timestr(s, systime-click.ops^.lasttime) END; IF NOT temponly THEN drawstr(image, s, floor(x+FLOAT(lums.symsize DIV 2-1)), floor(y-FLOAT(lums.fontysize DIV 2)), lig, 1, col, click.ops^.textpos, 3, fix, click.dryrun); END; IF withvalues THEN IF click.ops^.lastinftyp>=100 THEN (* temperature *) IF configon(fTEMP) & (click.ops^.lasttempalt>=MINTEMP) & (click.ops^.lasttempalt<=MAXTEMP) & (click.ops^.temptime+SHOWTEMPWIND>systime) THEN IF object THEN click.typ:=tDEGREEOBJ ELSE click.typ:=tDEGREE END; IntToStr(click.ops^.lasttempalt, 1, s); Append(s, DEGSYM+"C"); IF click.ops^.lasttempalt<0 THEN col.r:=20;col.g:=180;col.b:=255 ELSIF click.ops^.lasttempalt<40 THEN Colset(col, "Y") ELSE Colset(col, "R") END; drawstr(image, s, floor(x+FLOAT(lums.symsize DIV 2-1)), floor(y-FLOAT(lums.fontysize DIV 2)), lig, 0, col, click.ops^.valuepos, 4, fix, click.dryrun); END; ELSE s:=""; IF configon(fKMH) THEN IF object THEN click.typ:=tKMHOBJ ELSE click.typ:=tKMH END; IF (click.ops^.lastinftyp>0) & (click.ops^.lastkmh>0) & (click.ops^.lasttime+lums.kmhtime>systime) THEN IntToStr(click.ops^.lastkmh, 1, s); confappend(fKMH, s); END; END; IF VAL(INTEGER, click.ops^.lasttempalt)+(32768-10000)>conf2int(fALTMIN, 0, -10000, 65535, -10000) THEN IF s[0]<>0C THEN Append(s, " ") END; IntToStr(VAL(INTEGER, click.ops^.lasttempalt)+(32768-10000), 1, s1); Append(s, s1); Append(s, "m"); END; IF (click.ops^.clb<>0) & (ABS(VAL(INTEGER, click.ops^.clb))0C THEN Append(s, " ") END; IntToStr(VAL(INTEGER, click.ops^.clb), 1, s1); Append(s, s1); Append(s, "m/s"); END; -- IF (s[0]=0C) & (systime>=click.ops^.lasttime) -- THEN timestr(s, systime-click.ops^.lasttime) END; (* show last heard time *) IF s[0]<>0C THEN clbcolset(col, click.ops^.clb); drawstr(image, s, floor(x+FLOAT(lums.symsize DIV 2-1)), floor(y-FLOAT(lums.fontysize DIV 2)), lig, 0, col, click.ops^.valuepos, 4, fix, click.dryrun); END; END; END; END; click.ops:=click.ops^.next; END; END text; PROCEDURE getgate(v:pVARDAT; VAR gate:pOPHIST):BOOLEAN; VAR digi:MONCALL; BEGIN WITH v^ DO IF igatelen=0 THEN RETURN FALSE END; strcp(raw, igatepos, igatelen, digi); gate:=ophist; WHILE (gate<>NIL) & (gate^.call<>digi) DO gate:=gate^.next END; IF (gate=NIL) OR NOT vistime(gate^.lasttime) OR NOT posvalid(gate^.lastpos) OR (gate^.sym.tab<=" ") THEN RETURN FALSE END; END; RETURN TRUE END getgate; PROCEDURE rftracks(opcall-:MONCALL; VAR clrimg:BOOLEAN); VAR ig, op :pOPHIST; x0,y0,x,y:REAL; lig :CARDINAL; nofilt, (* track filter off *) trk :BOOLEAN; (* show no waypoints so show no rfpath to this *) BEGIN op:=oppo(opcall); click.ops:=op; click.typ:=tRFPATH; nofilt:=NOT configon(fTRACKFILT); trk:=lums.track>1; IF click.ops<>NIL THEN click.pf:=click.ops^.frames; WHILE click.pf<>NIL DO IF (trk OR (click.pf^.next=NIL)) & vistime(click.pf^.time) THEN WITH click.pf^.vardat^ DO IF (lastref=click.pf) & (nofilt OR (click.pf^.nodraw<=ERRSET{eDIST, eDUPE})) THEN IF getgate(click.pf^.vardat, ig) & (mapxy(pos, x0, y0)>=0) & (mapxy(ig^.lastpos, x, y)>=-1) THEN (* lig:=fade(click.pf^,time, click.ops); lig:=lig*240 DIV 1024*(refcnt+1); *) IF clrimg THEN clr(rfimg); clrimg:=FALSE END; lig:=60*(refcnt+1); vector(rfimg, x0, y0, x, y, lig, lig, lig, lums.symsize*16, 25.0); END; END; END; END; click.pf:=click.pf^.next; END; END; END rftracks; PROCEDURE mhtracks(hcall-:MONCALL; VAR clrimg:BOOLEAN); VAR x0,y0,x,y:REAL; lig :CARDINAL; digi:MONCALL; hop :pOPHIST; nofilt, (* track filter off *) trk :BOOLEAN; (* show no waypoints so show no rfpath to this *) BEGIN hop:=oppo(hcall); IF hop=NIL THEN RETURN END; click.ops:=ophist; click.typ:=tRFPATH; nofilt:=NOT configon(fTRACKFILT); trk:=lums.track>1; WHILE click.ops<>NIL DO IF NOT (ISOBJECT IN click.ops^.drawhints) & (MARKED IN click.ops^.drawhints) & (click.ops^.sym.tab>" ") THEN click.pf:=click.ops^.frames; WHILE click.pf<>NIL DO IF (trk OR (click.pf^.next=NIL)) & vistime(click.pf^.time) THEN WITH click.pf^.vardat^ DO IF (lastref=click.pf) & (nofilt OR (click.pf^.nodraw<=ERRSET{eDIST, eDUPE})) THEN IF (igatelen>0) & (mapxy(pos, x0, y0)>=0) THEN strcp(raw, igatepos, igatelen, digi); IF (hop^.call=digi) & (mapxy(hop^.lastpos, x, y)>=-1) THEN IF clrimg THEN clr(rfimg); clrimg:=FALSE END; lig:=50*(refcnt+1); vector(rfimg, x0, y0, x, y, lig, lig, lig, lums.symsize*16, 25.0); END; END; END; END; END; click.pf:=click.pf^.next; END; END; click.ops:=click.ops^.next; END; END mhtracks; PROCEDURE metercolor(what:CHAR); CONST TMIN=-30; TMAX=50; INCH=25.4/100.0; WXNIL=10000.0; RED=ARRAY OF INTEGER { 33, 63,112,156,199, 47,104,156,255,255, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 255,255,255,255,255, 255,255,255,255,219, 156,128,104, 82, 63, 43, 26, 13, 4}; GRN=ARRAY OF INTEGER { 33, 63,112,156,199, 7, 7, 7, 7, 82, 0, 33, 82,156,255, 47, 81,128,186,255, 255,219,186,156,128, 104, 82, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; BLU=ARRAY OF INTEGER { 33, 63,112,156,199, 47,104,156,255,255, 156,255,255,255,255, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; PROCEDURE getrain(op:pOPHIST):INTEGER; CONST MAX24=50.0; MAX1=5.0; TIMESPAN=3600; VAR f:pFRAMEHIST; dat:DAT; r, max:REAL; ret:INTEGER; BEGIN ret:=0; f:=op^.frames; WHILE f<>NIL DO IF (f^.next=NIL) & (f^.time+TIMESPAN>=systime) & (Decode(f^.vardat^.raw, dat)>=0) THEN IF what="1" THEN max:=MAX1; r:=dat.wx.rain1 ELSE max:=MAX24; r:=dat.wx.rain24 END; IF r200.0 THEN r:=0.0 END; IF r>max THEN r:=max END; IF r>=0.1 THEN ret:=trunc(r/max*32767.0) END; END; END; f:=f^.next; END; RETURN ret END getrain; PROCEDURE gettemp(op:pOPHIST):INTEGER; VAR t:INTEGER; BEGIN t:=op^.lasttempalt; IF (t>=TMIN) & (t<=TMAX) OR (t>=-80) & (t<80) &NOT configon(fTRACKFILT) THEN (* show or not garbage *) IF tTMAX THEN t:=TMAX END; t:=(t-TMIN)*32766 DIV (TMAX-TMIN) + 1; ELSE t:=0 END; RETURN t END gettemp; VAR x,y, f, f1, oor:REAL; t, xi, yi, mx, my, x0, y0, q, radius, rbr, xii:INTEGER; gb, gb1:CARDINAL; BEGIN radius:=trunc(power(2.0, realzoom(initzoom, finezoom)+0.2)); IF radius>1000 THEN radius:=1000 END; IF what="1" THEN radius:=radius DIV 2 END; rbr:=radius*radius; oor:=1.0/FLOAT(radius); click.ops:=ophist; click.typ:=tMETEOCOLOR; WHILE click.ops<>NIL DO IF posvalid(click.ops^.lastpos) & (click.ops^.sym.tab>" ") & ((lums.obj>0) OR NOT (ISOBJECT IN click.ops^.drawhints)) & vistime(click.ops^.lasttime) & (mapxy(click.ops^.lastpos, x, y)>=-1) & (click.ops^.temptime+SHOWTEMPWIND>systime) & ((click.ops^.lastinftyp>=100) OR (what="1") OR (what="R")) THEN x0:=VAL(INTEGER,x); y0:=VAL(INTEGER,y); IF (x0>-radius) & (x0-radius) & (y00 THEN FOR yi:=-radius TO radius DO my:=y0+yi; IF (my>0) & (my0) & (mx0 THEN IF what="T" THEN t:=VAL(CARDINAL, r)*(TMAX-TMIN) DIV 32768; t:=t DIV 2; IF t<0 THEN t:=0 ELSIF t>38 THEN t:=38 END; r:=RED[t]*2; g:=GRN[t]*2; b:=BLU[t]*2; ELSIF what="1" THEN r:=(VAL(CARDINAL, r)*1000+32768*32) DIV (32768*64) * 64; b:=0; g:=0; ELSE b:=(VAL(CARDINAL, r)*1000+32768*32) DIV (32768*64) * 64; r:=0; g:=b; END; END; END; END; END; END metercolor; PROCEDURE revert; VAR o,oo,on:pOPHIST; BEGIN oo:=NIL; o:=ophist; WHILE o<>NIL DO on:=o^.next; o^.next:=oo; oo:=o; o:=on; END; ophist:=oo; END revert; PROCEDURE deletelogfile(all:BOOLEAN):BOOLEAN; CONST DAY=3600*24; VAR fnd,fn:FILENAME; t, days:TIME; cnt:CARDINAL; ok:BOOLEAN; s:ARRAY[0..100] OF CHAR; BEGIN t:=realtime; IF NOT all THEN days:=conf2int(fLOGDAYS, 0, 0, 1000000, 31); IF days=0 THEN RETURN FALSE END; (* keep files forever *) IF t>days*DAY THEN DEC(t, days*DAY) ELSE t:=0 END; IF t0 THEN IntToStr(cnt, 1, s); Append(s, " Rawlog(s) Deleted"); textautosize(0, 0, 5, 6, "b", s); END; RETURN TRUE END deletelogfile; PROCEDURE importlog(cmd:CHAR); CONST TODATE=3C; TOSTART=1C; BACK=2C; FORW=4C; TOEND=5C; TONOW=6C; RDWLOG=7C; ASKDELLOG=10C; NODELLOG=11C; DELLOG=12C; DAY=3600*24; AYEAR=DAY*366; VAR fromto, lastread, logstarttime, th:TIME; fn, h, h1:ARRAY[0..1024] OF CHAR; find:ARRAY[0..12] OF CHAR; color:CHAR; ok:BOOLEAN; logredcnt:INTEGER; PROCEDURE toend; BEGIN fromto:=realtime; LOOP IF quit OR click.abort THEN h:="Aborted"; EXIT END; DEC(fromto, lums.firstdim); rdlog(ophist, fn, fromto, fromto+lums.firstdim, find,logstarttime,lastread,logredcnt); IF logredcnt<0 THEN fromto:=((fromto-1) DIV DAY) * DAY - lums.firstdim END; (* day file not found*) IF logredcnt>0 THEN EXIT END; IF fromto0 THEN EXIT END; IF fromto>realtime THEN h:="No Data since 1 Year"; EXIT END; IF (find[0]<>0C) & (logredcnt>=0) THEN (* look for call so read whole day *) INC(fromto, lums.firstdim); ELSE fromto:=(fromto DIV DAY+1)*DAY END; END; END tobegin; PROCEDURE clrstk; BEGIN tabview.stkpo:=0; tabview.stktop:=0; click.mhop[0]:=0C; click.onesymbol.tab:=0C; click.entries:=0; END clrstk; BEGIN click.abort:=FALSE; h[0]:=0C; find[0]:=0C; fn[0]:=0C; color:="e"; logredcnt:=0; logstarttime:=0; --WrInt(ORD(cmd), 1); WrStrLn(" cmd"); IF cmd=DELLOG THEN confstr(fLOGWFN, fn); ok:=FALSE; IF fn[0]<>0C THEN IF deletelogfile(TRUE) THEN ok:=TRUE ELSE Erase(fn, ok) END; END; IF ok THEN h:="["; Append(h, fn); Append(h, "] deleted"); ELSE h:="cannot delete ["; Append(h, fn); Append(h, "]") END; ELSIF cmd=ASKDELLOG THEN confstr(fLOGWFN, fn); IF fn[0]=0C THEN h:="no logfile defined"; ELSE IF guesssize(fn, h)>=0 THEN Append(fn, "] "); Append(fn, " "); Append(fn, h); h:="Logfile ["; Append(h, fn); ELSE h:="no logfile found" END; color:="r"; END; ELSIF cmd<>NODELLOG THEN confstr(fLOGDATE, h); IF NOT StrToTime(h, fromto) THEN fromto:=0 ELSIF fromto>localtime() THEN DEC(fromto, localtime()) END; lastread:=fromto; IF (cmd=TONOW) OR (cmd=RDWLOG) THEN IF lums.logmode THEN (* exit logmode *) clrstk; purge(ophist, MAX(TIME), MAX(TIME)); ophist:=ophist2; ophist2:=NIL; lums.logmode:=FALSE; systime:=realtime; END; IF cmd=RDWLOG THEN confstr(fLOGWFN, fn); clrstk; purge(ophist, MAX(TIME), MAX(TIME)); systime:=time(); IF fn[0]<>0C THEN rdlog(ophist, fn, systime-lums.purgetime, systime, "",logstarttime,lastread,logredcnt); revert; purge(ophist, systime-lums.purgetime, systime-lums.purgetimeobj); tracenew.winevent:=0; ELSE h:="need filename" END; END; fromto:=systime; ELSE confstr(fLOGFN, fn); h:=""; logpathok(fn, h); IF lums.logmode THEN clrstk; purge(ophist, MAX(TIME), MAX(TIME)); ELSE ophist2:=ophist; ophist:=NIL; lums.logmode:=TRUE; END; IF h="" THEN confstr(fLOGDATE, h); IF NOT StrToTime(h, fromto) THEN fromto:=0 ELSIF fromto>localtime() THEN DEC(fromto, localtime()) END; logredcnt:=0; IF fromto>realtime THEN fromto:=realtime ELSIF fromto0 THEN EXIT END; IF fromto0 THEN EXIT END; IF fromto>realtime THEN h:="No more Data"; EXIT END; END; IF logredcnt<=0 THEN toend END; ELSIF cmd=TODATE THEN rdlog(ophist, fn, fromto, fromto+lums.firstdim, find,logstarttime,lastread,logredcnt); IF logredcnt<=0 THEN h:="No Data at this Date" END; END; IF logredcnt>0 THEN systime:=lastread; revert; purge(ophist, systime-lums.purgetime, systime-lums.purgetime); lastread:=fromto; END; END; tracenew.winevent:=0; END; IF logredcnt>0 THEN DateToStr(lastread+localtime(), h); h[16]:=0C; AddConfLine(fLOGDATE, 0, h); IntToStr(logredcnt, 1, h); Append(h, " Lines "); th:=(systime-logstarttime) DIV 60; IntToStr(th DIV 60, 1, h1); Append(h, h1); Append(h, "h"); th:=th MOD 60; Append(h, CHR(th DIV 10 + ORD("0"))); Append(h, CHR(th MOD 10 + ORD("0"))); Append(h, "m from"+LF); DateLocToStr(logstarttime, h1); Append(h, h1); (* Append(h, LF+"to "); DateLocToStr(systime, h1); Append(h, h1); *) color:="b"; ELSIF logstarttime>0 THEN h:="no data at "; DateLocToStr(fromto+localtime(), h1); Append(h, h1); IF systime=1 THEN Append(h, " (log start "); DateLocToStr(logstarttime, h1); Append(h, h1); Append(h, ")"); END; ELSIF (fn[0]<>0C) & (h="") THEN h:="no Data found" END; IF cmd=TONOW THEN h:="back to Realtime" END; END; say(h, 0, color); refrlog; END importlog; PROCEDURE bootreadlog; VAR s, fn:ARRAY[0..999] OF CHAR; logt, lastt:TIME; logredcnt:INTEGER; BEGIN click.abort:=FALSE; confstr(fLOGWFN, fn); IF NOT configon(fLOGWFN) OR (fn[0]=0C) THEN say("No Log File Enabled", 5, "b"); redraw(image); ELSE say("Reading Log (ESC to abort) ...", 0, "b"); redraw(image); realtime:=time(); logt:=realtime-lums.purgetime; (* start from now - data in ram *) logredcnt:=0; rdlog(ophist, fn, logt, realtime, "",logt,lastt,logredcnt); IF logredcnt>0 THEN IntToStr(logredcnt, 1, s); Append(s, " lines '"); Append(s, fn); Append(s, "' imported "); say(s, 4, "b"); redraw(image); ELSE s:="logfile '"; Append(s, fn); Append(s, "' not found"); say(s, 6, "r"); redraw(image); END; END; revert; purge(ophist, time()-lums.purgetime, time()-lums.purgetimeobj); logdone:=TRUE; END bootreadlog; PROCEDURE IsInbMultisymb(tab, pic:CHAR):BOOLEAN; VAR t:CARDINAL; BEGIN t:=ORD(pic); IF t=192 THEN RETURN FALSE END; IF tab<>"/" THEN INC(t, 96) END; RETURN t IN click.onesymbolset END IsInbMultisymb; PROCEDURE markvisable(singlecall-:MONCALL); VAR op, singleop:pOPHIST; rightdown:POSITION; BEGIN singleop:=oppo(singlecall); xytodeg(VAL(REAL,xsize), 0.0, rightdown); op:=ophist; WHILE op<>NIL DO WITH op^ DO IF posvalid(lastpos) & vistime(lasttime) & ((op=singleop) OR (singleop=NIL) & (margin0.long<=rightdown.long) & (margin0.lat>=rightdown.lat) & (margin1.long>=mappos.long) & (margin1.lat<=mappos.lat) & ((click.onesymbol.tab=0C) OR (click.onesymbol.tab=cMULTISYMBOL) OR (sym.pic=click.onesymbol.pic) & ((sym.tab=click.onesymbol.tab) OR (click.onesymbol.tab="\") & (sym.tab<>"/")))) & ((click.onesymbol.tab<>cMULTISYMBOL) OR IsInbMultisymb(sym.tab, sym.pic)) & ((op=singleop) OR (lums.obj>0) OR NOT (ISOBJECT IN drawhints)) THEN INCL(drawhints, MARKED); ELSE drawhints:=drawhints-sDRAWHINTS{MARKED, MOVES} END; op:=next; END; END; tracenew.winpos0:=mappos; tracenew.winpos1:=rightdown; END markvisable; (* PROCEDURE findop(call-:ARRAY OF CHAR; totable:BOOLEAN):pOPHIST; VAR op, opfound:pOPHIST; mc, Mc:MONCALL; i:CARDINAL; c:CHAR; BEGIN c:=0C; FOR i:=0 TO HIGH(mc) DO IF i<=HIGH(call) THEN mc[i]:=call[i]; IF c<>"*" THEN c:=CAP(call[i]) END; IF c="*" THEN Mc[i]:="?" ELSE Mc[i]:=c END; ELSE mc[i]:=0C; Mc[i]:=0C; END; END; IF totable THEN click.entries:=0; click.selected:=0 END; op:=ophist; WHILE op<>NIL DO opfound:=NIL; IF op^.call=mc THEN opfound:=op; (* full match *) ELSE i:=0; LOOP IF (Mc[i]<>"?") & (Mc[i]<>op^.call[i]) THEN EXIT END; INC(i); IF i>HIGH(mc) THEN opfound:=op; EXIT END; END; END; IF (opfound<>NIL) & vistime(opfound^.lasttime) THEN IF NOT totable THEN RETURN opfound END; IF click.entries>HIGH(click.table) THEN RETURN click.table[0].opf END; click.table[click.entries].opf:=opfound; click.table[click.entries].pff:=NIL; click.table[click.entries].pff0:=NIL; click.table[click.entries].typf:=tSYMBOL; click.selected:=0; INC(click.entries); END; op:=op^.next; END; IF click.entries>0 THEN RETURN click.table[0].opf ELSE RETURN NIL END; END findop; *) PROCEDURE findop(call-:ARRAY OF CHAR; totable:BOOLEAN):pOPHIST; VAR op, opfound:pOPHIST; mc:MONCALL; BEGIN Assign(mc, call); IF totable THEN (* manual search with wildcards *) click.entries:=0; click.selected:=0; cleanfind(mc); END; op:=ophist; WHILE op<>NIL DO opfound:=NIL; IF totable THEN IF cmpwild(op^.call, mc) THEN opfound:=op END; ELSIF op^.call=mc THEN opfound:=op END; IF (opfound<>NIL) & vistime(opfound^.lasttime) & (opfound^.sym.tab>=" ") THEN IF NOT totable THEN RETURN opfound END; IF click.entries>HIGH(click.table) THEN RETURN click.table[0].opf END; click.table[click.entries].opf:=opfound; click.table[click.entries].pff:=NIL; click.table[click.entries].pff0:=NIL; click.table[click.entries].typf:=tSYMBOL; click.selected:=0; INC(click.entries); END; op:=op^.next; END; IF click.entries>0 THEN RETURN click.table[0].opf ELSE RETURN NIL END; END findop; PROCEDURE findsize(VAR pos0, pos1:POSITION; opcall-:MONCALL; typ:CHAR); VAR f :pFRAMEHIST; v :pVARDAT; ig, op :pOPHIST; i, j, gl:CARDINAL; dat :DAT; trk, nofilt :BOOLEAN; PROCEDURE reset; BEGIN pos0.lat :=-10.0; pos0.long:= 10.0; pos1.lat := 10.0; pos1.long:=-10.0; END reset; PROCEDURE max(p:POSITION); BEGIN IF posvalid(p) THEN IF pos0.latp.lat THEN pos1.lat:=p.lat END; IF pos0.long>p.long THEN pos0.long:=p.long END; IF pos1.long1; IF op<>NIL THEN IF typ="S" THEN pos0:=op^.lastpos; pos1:=pos0; ELSIF (typ="T") OR (typ="R") THEN IF typ="R" THEN ig:=ophist; WHILE ig<>NIL DO ig^.drawhints:=ig^.drawhints-sDRAWHINTS{MARKED, MOVES}; ig:=ig^.next END; INCL(op^.drawhints, MARKED); END; f:=op^.frames; WHILE f<>NIL DO v:=f^.vardat; IF (trk OR (f^.next=NIL)) & posvalid(v^.pos) THEN WITH v^ DO IF vistime(f^.time) & (nofilt OR (f^.nodraw<=ERRSET{eDIST, eDUPE})) THEN max(pos); IF (typ="R") & getgate(v, ig) THEN INCL(ig^.drawhints, MARKED); max(ig^.lastpos); END; END; END; END; f:=f^.next; END; (* WrStr(typ); WrFixed(pos0.lat, 4,10);WrFixed(pos0.lat, 4,10);WrFixed(pos0.long, 4,10); WrFixed(pos1.lat, 4,10); WrFixed(pos1.long, 4,10); WrStr(op^.call); WrLn; *) ELSIF typ="H" THEN (* mark all heard this op *) gl:=Length(op^.call); IF gl>0 THEN ig:=ophist; WHILE ig<>NIL DO ig^.drawhints:=ig^.drawhints-sDRAWHINTS{MARKED, MOVES}; IF NOT (ISOBJECT IN ig^.drawhints) & vistime(ig^.lasttime) THEN f:=ig^.frames; LOOP IF f=NIL THEN EXIT END; WITH f^ DO IF (trk OR (f^.next=NIL)) & vistime(time) & posvalid(vardat^.pos) & (nofilt OR (f^.nodraw<=ERRSET{eDIST, eDUPE})) & (vardat^.igatelen=gl) THEN j:=vardat^.igatepos; i:=0; WHILE vardat^.raw[j]=op^.call[i] DO INC(j); INC(i); IF i>=gl THEN INCL(ig^.drawhints, MARKED); max(vardat^.pos); EXIT END; END; END; END; f:=f^.next; END; IF MARKED IN ig^.drawhints THEN max(ig^.lastpos) END; (* show symbol in map size *) END; ig:=ig^.next; END; INCL(op^.drawhints, MARKED); max(op^.lastpos); END; END; END; IF typ="O" THEN (* mark all objects of this op *) ig:=ophist; WHILE ig<>NIL DO ig^.drawhints:=ig^.drawhints-sDRAWHINTS{MARKED, MOVES}; IF (ISOBJECT IN ig^.drawhints) & posvalid(ig^.lastpos) & vistime(ig^.lasttime) THEN f:=ig^.frames; IF f<>NIL THEN WHILE f^.next<>NIL DO f:=f^.next END; (* goto last frame *) IF (Decode(f^.vardat^.raw, dat)>=0) & ((dat.type=OBJ) OR (dat.type=ITEM)) & (dat.objectfrom=opcall) THEN INCL(ig^.drawhints, MARKED); max(ig^.lastpos); END; END; END; ig:=ig^.next; END; END; IF (ABS(pos0.lat )>pi/2.0) OR (ABS(pos1.lat )>pi/2.0) OR (ABS(pos0.long)>pi) OR (ABS(pos1.long)>pi) THEN posinval(pos0); posinval(pos1) END; limpos(pos0); limpos(pos1); (* WrFixed(pos0.long*180.0/pi, 5,10); WrFixed(pos0.lat*180.0/pi, 5,10); WrFixed(pos1.long*180.0/pi, 5,10); WrFixed(pos1.lat*180.0/pi, 5,10); WrLn; *) END findsize; PROCEDURE push(newzoom:REAL; onlyonce:BOOLEAN); VAR i:CARDINAL; BEGIN WITH tabview DO IF (stkpo=0) OR NOT (onlyonce & posstk[stkpo-1].findpush) & ((posstk[stkpo-1].pos.lat<>mappos.lat) OR (posstk[stkpo-1].pos.long<>mappos.long) OR (VAL(INTEGER, posstk[stkpo-1].zoom*10.0)<>VAL(INTEGER, newzoom*10.0))) THEN WITH posstk[stkpo] DO pos:=mappos; zoom:=newzoom; mhop:=click.mhop; onesymbol:=click.onesymbol; onesymbolset:=click.onesymbolset; rf:=lums.rf; lumtrack:=lums.track; lumwaypoint:=lums.waypoint; lummap:=lums.map; lumsym:=lums.sym; lumobj:=lums.obj; mhtxv:=mhtx; wxcol:=lums.wxcol; lumtext:=lums.text; mapname:=lums.mapname; maplumcorr:=lums.maplumcorr; -- altimap:=click.altimap; findpush:=onlyonce; focus:=click.watchmhop; END; IF stkpo=0) & (mapxy(p1, x1, y1)>=0) THEN x0:=x0-x1; y0:=y0-y1; RETURN x0*x0 + y0*y0 >= 200.0 END; RETURN TRUE; END distvisable; PROCEDURE mapzoom(pos0, pos1:POSITION; maxz:CARDINAL; withmargin, zoomtonomap:BOOLEAN); CONST MARGIN=0.1; YMARGIN=0.1; VAR fo, wx, wy, wmax:REAL; mo, mid, pos2, testpos:POSITION; done, nofit, blown:BOOLEAN; testtx, testty:INTEGER; testshx, testshy, steps:REAL; BEGIN IF NOT posvalid(pos0) OR NOT posvalid(pos1) THEN RETURN END; push(realzoom(initzoom, finezoom), FALSE); wx:=pos1.long-pos0.long; wy:=pos0.lat-pos1.lat; pos0.lat:=pos0.lat+wy*FLOAT(lums.fontysize)/FLOAT(ysize); pos1.lat:=pos1.lat-wy*FLOAT(lums.fontysize)*0.25/FLOAT(ysize); wy:=pos0.lat-pos1.lat; wmax:=wx; IF wmax0) & (NOT zoomtonomap OR distvisable(pos0, pos1)) THEN centerpos(mid, testpos); mercator(testpos.long, testpos.lat, initzoom, testtx, testty, testshx, testshy); loadmap(image, testtx, testty, initzoom, finezoom, testshx, testshy, done, blown, configon(fALLOWEXP), TRUE); ELSE done:=TRUE END; (* test if map is complete *) IF mapxy(pos2, wx, wy)<0 THEN nofit:=TRUE ELSIF done THEN EXIT ELSE nofit:=FALSE END; -- IF (mapxy(pos2, wx, wy)>=0) OR (initzoom<=MINZOOM) THEN EXIT END; DEC(initzoom); END; IF initzoom<>VAL(INTEGER,maxz) THEN tooltips("b") END; (* fine zoom *) finezoom:=1.0; --IF initzoom1.95) OR (mapxy(pos2, wx, wy)<0) THEN EXIT END; END; finezoom:=fo; END; mo:=mappos; centerpos(mid, mappos); IF mappos.latclickpos.long THEN h:=mpos.long; mpos.long:=clickpos.long; clickpos.long:=h END; mapzoom(mpos, clickpos, conf2int(fMAXZOOM, 0, 1, MAXZOOM, MAXZOOM), TRUE, TRUE); END; END zoomtomarks; PROCEDURE pantoop(op:pOPHIST); VAR rightdown, p:POSITION; m, cf:REAL; BEGIN IF (op<>NIL) & posvalid(op^.lastpos) THEN xytodeg(VAL(REAL,xsize), 0.0, rightdown); p:=op^.lastpos; cf:=FLOAT(lums.centering)*0.005; (* hold obj in percent of image to center *) m:=(rightdown.long-mappos.long)*cf; IF p.long-mrightdown.long THEN mappos.long:=mappos.long + p.long + m - rightdown.long END; m:=(mappos.lat-rightdown.lat)*cf; IF p.lat+m>mappos.lat THEN mappos.lat:=p.lat+m ELSIF p.lat-m0 THEN DEC(stkpo); IF (stkpo>0) & (posstk[stkpo].pos.lat=mappos.lat) & (posstk[stkpo].pos.long=mappos.long) & (VAL(INTEGER, posstk[stkpo].zoom*10.0)=VAL(INTEGER, realzoom(initzoom, finezoom)*10.0)) THEN DEC(stkpo) END; WITH posstk[stkpo] DO mappos:=pos; finezoom:=zoom; initzoom:=trunc(finezoom); finezoom:=finezoom-FLOAT(initzoom)+1.0; click.mhop:=mhop; click.onesymbol:=onesymbol; click.onesymbolset:=onesymbolset; lums.rf:=rf; mhtx:=mhtxv; lums.wxcol:=wxcol; lums.text:=lumtext; IF lumtext>0 THEN int2cfg(fLTEXT, lumtext DIV BRIMUL) END; lums.track:=lumtrack; IF lumtrack>0 THEN int2cfg(fLTRACK, lumtrack DIV BRIMUL) END; lums.waypoint:=lumwaypoint;IF lumwaypoint>0 THEN int2cfg(fLWAY, lumwaypoint DIV BRIMUL) END; lums.map:=lummap; IF lummap>0 THEN int2cfg(fLMAP, lummap DIV BRIMUL) END; lums.sym:=lumsym; IF lumsym>0 THEN int2cfg(fLSYM, lumsym DIV BRIMUL) END; lums.obj:=lumobj; IF lumobj>0 THEN int2cfg(fLOBJ, lumobj DIV BRIMUL) END; lums.mapname:=mapname; lums.maplumcorr:=maplumcorr; -- click.altimap:=altimap; click.watchmhop:=focus; END; lums.moving:=FALSE; END; mercator(mappos.long, mappos.lat, initzoom, inittilex, inittiley, shiftx, shifty); -- lums.wxcol:=0C; END; END pop; PROCEDURE toggview; (* switch to alternate view stack *) VAR tmp:TABS; BEGIN push(realzoom(initzoom, finezoom), FALSE); tmp:=tabview; IF alttabview.stkpo=0 THEN (* alternate stack empty so clone actual entry *) alttabview.posstk[0]:=tabview.posstk[tabview.stkpo-1]; alttabview.stkpo:=1; alttabview.stktop:=1; END; tabview:=alttabview; alttabview:=tmp; lums.moving:=FALSE; pop; IF click.watchmhop & (click.mhop[0]<>0C) THEN pantoop(findop(click.mhop, FALSE)) END; END toggview; PROCEDURE getant(a:CONFSET):INTEGER; BEGIN RETURN conf2int(a, 0, ALTINVAL, MAXANTALT, ALTINVAL) END getant; PROCEDURE closeradio; BEGIN IF click.withradio THEN closesrtmfile END; click.withradio:=FALSE; click.panorama:=FALSE; END closeradio; PROCEDURE measureline(img:pIMAGE; pos0, pos1:POSITION; pos0alt:INTEGER); VAR x0, y0, x1, y1, dist, a1, a2, mhz, el1, el2:REAL; ant1, ant2, wave, ret:INTEGER; ok, ant1obj, vec, altok:BOOLEAN; s,h,se:ARRAY[0..99] OF CHAR; BEGIN IF posvalid(pos0) & posvalid(pos1) & ((pos0.lat<>pos1.lat) OR (pos0.long<>pos1.long)) & (mapxy(pos0, x0, y0)>=-1) & (mapxy(pos1, x1, y1)>=-1) THEN vec:=TRUE; altok:=FALSE; IF NOT click.withradio OR click.altimap THEN ant1:=getant(fANT1); ant2:=getant(fANT2); mhz:=conf2real(fFRESNELL, 0, 0.0, MAX(REAL), 0.0); IF mhz>=MINMHZ THEN wave:=trunc(300000.0/mhz) ELSE wave:=0 END; se:=""; IF (ant1>ALTINVAL) & (ant2>ALTINVAL) & configon(fGEOPROFIL) THEN ant1obj:=gpsalt(fANT1) & (pos0alt-10000); (* take alt from waypoint NN *) IF ant1obj THEN INC(ant1, pos0alt) END; (* add ant higth NN *) ret:=geoprofile(img, pos0, pos1, FLOAT(wave)*0.001, ant1obj, ant1, ant2, dist, a1, a2, el1, el2); IF ret=0 THEN ok:=TRUE; vec:=FALSE; altok:=TRUE; ELSIF ret=-1 THEN se:="Radiolink: need altitude data on Marker Positions" ELSE altok:=TRUE; se:="Radiolink: distance too long" END; ELSE dist:=distance(pos0, pos1)*1000.0; ok:=TRUE; END; FixToStr(dist*0.001, 4, s); Append(s,"km "); IF altok THEN Append(s, TEXTCOLLGR); IntToStr(VAL(INTEGER,a1), 0, h); Append(s, h); Append(s,"m/"); IntToStr(VAL(INTEGER,a2), 0, h); Append(s, h); Append(s,"m "+TEXTCOLEND); END; Append(s,"az:"); FixToStr(azimuth(pos0, pos1), 2, h); Append(s, h); Append(s, DEGSYM+"/"); FixToStr(azimuth(pos1, pos0), 2, h); Append(s, h); Append(s, DEGSYM+" " ); IF altok THEN Append(s, TEXTCOLLGR+"ele:"); FixToStr(el1, 3, h); Append(s, h); Append(s, DEGSYM+"/"); FixToStr(el2, 3, h); Append(s, h); Append(s, DEGSYM+" "+TEXTCOLEND ); END; IF mhz>=MINMHZ THEN FixToStr(32.2+8.68588963806503655305*ln(dist*0.001*mhz), 2, h); Append(s, h); Append(s,"dB"); END; textautosize(DOCKX, 0, 7, 20, "h", s); IF se[0]<>0C THEN textautosize(DOCKX, 0, 3, 2, "r", se) END; END; IF vec THEN vector(img, x0, y0, x1, y1, 20, 220, 20, lums.symsize*22, 0.0) END; END; END measureline; PROCEDURE geobri():INTEGER; BEGIN RETURN conf2int(fGEOBRIGHTNESS, 0, 0, 100, 30) END geobri; PROCEDURE geocontr():INTEGER; BEGIN RETURN conf2int(fGEOCONTRAST, 0, 0, 10000, 0) END geocontr; (* PROCEDURE panorama(img:pIMAGE; pos:POSITION; col:COLTYP; VAR abo:BOOLEAN); CONST ALTINVAL=-10000; VAR ant:INTEGER; BEGIN IF posvalid(pos) THEN ant:=getant(fANT1); IF ant>ALTINVAL THEN Panorama(img, pos, ant, col, abo); ELSE textautosize(0, 0, 3, 2, "r", "Panorama: need Antenna higth") END END; END panorama; *) PROCEDURE getrefrac():REAL; BEGIN RETURN conf2real(fREFRACT, 0, 0.0, 1.0, 0.0) END getrefrac; PROCEDURE radioimage(img:pIMAGE; pos:POSITION; colnum:CARDINAL; VAR abo:BOOLEAN); CONST ALTINVAL=-10000; VAR ant1, ant2, ant3, qual:INTEGER; BEGIN IF posvalid(pos) THEN ant1:=getant(fANT1); ant2:=getant(fANT2); ant3:=getant(fANT3); IF (colnum<>0) & (ant2>ALTINVAL) THEN ant1:=ant2 END; IF (ant1>ALTINVAL) & (ant3>ALTINVAL) THEN qual:=confflags(fSRTMCACHE, 0); Radiorange(img, pos, ant1, ant3, geocontr(), ORD(colnum<>0), qual, abo, getrefrac()); ELSE textautosize(0, 0, 3, 2, "r", "Radiolink: need Antenna higths") END END; END radioimage; PROCEDURE getgeocol(c:CONFSET; bri:INTEGER; dr,dg,db:CARDINAL; VAR col:COLTYP); BEGIN col.r:=conf2int(c, 0, 0, 100, dr)*bri DIV 100; col.g:=conf2int(c, 1, 0, 100, dg)*bri DIV 100; col.b:=conf2int(c, 2, 0, 100, db)*bri DIV 100; END getgeocol; PROCEDURE reliefcolors(img:pIMAGE; color:BOOLEAN); VAR bri, bri2:CARDINAL; def: INTEGER; x, y:CARDINAL; BEGIN def:=geobri(); getgeocol(fCOLMARK1, def, 100,0,0, radio.c1); (* marker 1 defaults to red *) getgeocol(fCOLMARK2, def, 0,100,0, radio.c2); (* marker 2 defaults to green *) FOR y:=0 TO HIGH(img^[0]) DO FOR x:=0 TO HIGH(img^) DO WITH img^[x][y] DO IF color THEN bri:=r; bri2:=g; r:=(radio.c1.r*bri + radio.c2.r*bri2) DIV 100; g:=(radio.c1.g*bri + radio.c2.g*bri2) DIV 100; b:=(radio.c1.b*bri + radio.c2.b*bri2) DIV 100; -- ELSE r:=r*bri DIV 100; g:=r; b:=r END; ELSE bri:=VAL(INTEGER,r)*def DIV 100; r:=bri; g:=bri; b:=bri; END; END; END; END; END reliefcolors; PROCEDURE copypastepos(pos:POSITION); (* in decimal deg *) VAR s, h:ARRAY[0..100] OF CHAR; BEGIN FixToStr(pos.lat/RAD, 6, s); Append(s, " "); FixToStr(pos.long/RAD, 6, h); Append(s, h); copypaste(s); END copypastepos; (* PROCEDURE testlist(op:pOPHIST); VAR pf:pFRAMEHIST; BEGIN WrStrLn(op^.call); pf:=op^.frames; WHILE pf<>NIL DO WrCard(CAST(CARDINAL, pf^.vardat), 15); WrInt(pf^.vardat^.igatelen, 10); WrFixed(pf^.vardat^.pos.long, 4, 10); WrFixed(pf^.vardat^.pos.lat, 4, 10); WrLn; pf:=pf^.next; END; WrLn; END testlist; *) <* IF WITHHTML THEN *> PROCEDURE wr(fd:File; s:ARRAY OF CHAR); VAR l:CARDINAL; BEGIN l:=Length(s); IF l>0 THEN WrBin(fd, s, l) END; END wr; PROCEDURE coltxt(fd:File; s-:ARRAY OF CHAR; col:BOOLEAN); CONST MARKBLU=''; MARKRED=''; MARKEND=''; VAR h:ARRAY[0..4095] OF CHAR; i:INTEGER; j,n,ii:CARDINAL; c:CHAR; BEGIN j:=0; FOR i:=0 TO VAL(INTEGER, Length(s))-1 DO c:=s[i]; CASE c OF " ",".",",","0".."9","A".."Z","a".."z": h[j]:=c; INC(j); |LF: h[j]:=CR; INC(j); h[j]:=LF; INC(j); h[j]:="<"; INC(j); h[j]:="B"; INC(j); h[j]:="R"; INC(j); h[j]:=">"; INC(j); |CR:; ELSE IF (c=TEXTCOLRED) & col THEN ii:=0; WHILE MARKRED[ii]<>0C DO h[j]:=MARKRED[ii]; INC(j); INC(ii) END; ELSIF (c=TEXTCOLBLU) & col THEN ii:=0; WHILE MARKBLU[ii]<>0C DO h[j]:=MARKBLU[ii]; INC(j); INC(ii) END; ELSIF (c=TEXTCOLEND) & col THEN ii:=0; WHILE MARKEND[ii]<>0C DO h[j]:=MARKEND[ii]; INC(j); INC(ii) END; ELSE h[j]:="&"; INC(j); h[j]:="#"; INC(j); n:=ORD(c); IF n>=100 THEN h[j]:=CHR(ORD("0")+n DIV 100); INC(j) END; h[j]:=CHR(ORD("0")+n DIV 10 MOD 10); INC(j); h[j]:=CHR(ORD("0")+n MOD 10); INC(j); h[j]:=";"; INC(j); END; END; IF j>=HIGH(h)-20 THEN RETURN END; END; WrBin(fd, h, j); END coltxt; PROCEDURE html; VAR h:ARRAY[0..1000] OF CHAR; date, dtime:TIME; pf, pfend:pFRAMEHIST; pv:pVARDAT; entc, anch:CARDINAL; fd:File; decoded:BOOLEAN; PROCEDURE unpos(call:MONCALL); (* show op with no position *) VAR op:pOPHIST; pf:pFRAMEHIST; BEGIN op:=ophist; wr(fd, '

Stations with no or dubious Position Data

'); WHILE op<>NIL DO IF NOT posvalid(op^.lastpos) THEN IF (call[0]=0C) OR (call=op^.call) THEN pf:=op^.frames; WHILE pf<>NIL DO IF call[0]=0C THEN (* all op but show only last frame *) WHILE (pf^.next<>NIL) DO pf:=pf^.next END; END; wr(fd, '

'); decode(h, pf^.vardat, NIL, pf^.time, 0, pf^.nodraw, TRUE); coltxt(fd, h, TRUE); wr(fd, "

"+CR+LF); pf:=pf^.next; END; END; END; op:=op^.next; END; END unpos; PROCEDURE samepath(pf:pFRAMEHIST):BOOLEAN; VAR a,b,l:CARDINAL; BEGIN l:=pf^.vardat^.igatelen; IF (click.table[entc].pff=NIL) OR (l=0) OR (l<>click.table[entc].pff^.vardat^.igatelen) THEN RETURN FALSE END; a:=pf^.vardat^.igatepos; b:=click.table[entc].pff^.vardat^.igatepos; REPEAT IF pf^.vardat^.raw[a]<>click.table[entc].pff^.vardat^.raw[b] THEN RETURN FALSE END; INC(a); INC(b); DEC(l); UNTIL l=0; RETURN TRUE END samepath; BEGIN fd:=OpenWrite("/usr/www/aprs/test/info.html"); IF NOT FdValid(fd) THEN fd:=OpenWrite("/tmp/info.html") END; IF NOT FdValid(fd) THEN RETURN END; wr(fd, ""+CR+LF+""+CR+LF+""+CR+LF); entc:=click.entries; xytodeg(VAL(REAL,click.x), VAL(REAL,click.y), clickpos); mestxt[0]:=0C; IF entc=0 THEN (* found nothing map click *) wr(fd, "(Map) "); postostr(clickpos, "3", h); -- FixToStr(clickpos.long*360.0/PI2, 5, h); wr(fd, h); wr(fd, " "); -- FixToStr(clickpos.lat*360.0/PI2, 5, h); wr(fd, h); wr(fd, " "); limpos(clickpos); postoloc(h, clickpos); Append(h, " "); IF tracenew.call[0]<>0C THEN Append(h, "Tracecall:"); Append(h, tracenew.call); Append(h, " "); END; wr(fd, h); measure(click.markpos, clickpos, mestxt, FALSE); coltxt(fd, mestxt, TRUE); click.dryrun:=FALSE; unpos(""); ELSE WHILE entc>0 DO DEC(entc); IF click.table[entc].opf<>NIL THEN measure(click.markpos, click.table[entc].opf^.lastpos, mestxt, FALSE); wr(fd, "

"); coltxt(fd, click.table[entc].opf^.call, FALSE); -- trackopf:=click.table[entc].opf; CASE click.table[entc].typf OF tTRACK :wr(fd, " (Track)"); findsize(newpos0, newpos1, click.table[entc].opf^.call, "T"); |tSYMBOL:wr(fd, " (Symbol)"); findsize(newpos0, newpos1, click.table[entc].opf^.call, "S"); |tTEXT,"K":wr(fd, " (Text)"); findsize(newpos0, newpos1, click.table[entc].opf^.call, "T"); |tOBJECT:wr(fd, " (Object)"); |"o":wr(fd, " (Objecttext)"); |"R":wr(fd, " (RF-Path)"); findsize(newpos0, newpos1, click.table[entc].opf^.call, "R"); |"W":wr(fd, " (Wx)"); ELSE END; wr(fd, "

"); IF posvalid(click.table[entc].opf^.lastpos) THEN measure(click.markpos, click.table[entc].opf^.lastpos, h, FALSE); ELSE measure(click.markpos, clickpos, h, FALSE) END; IF h[0]<>0C THEN coltxt(fd, h, TRUE); wr(fd, "
") END; date:=click.table[entc].opf^.lasttime; pv:=NIL; pf:=click.table[entc].opf^.frames; IF pf<>NIL THEN WHILE pf^.next<>NIL DO pf:=pf^.next END; (* find last raw frame *) pv:=pf^.vardat; date:=pf^.time; END; IF (pf<>NIL) & (pv<>NIL) THEN decode(h, pv, NIL, date, 0, pf^.nodraw, TRUE); coltxt(fd, h, TRUE); wr(fd, "
"+CR+LF); END; wr(fd, "

"+CR+LF); (* graphs(click.table[entc].opf, click.table[entc].typf, systime); btimehist(click.table[entc].opf); *) END; END; END; FOR decoded:=FALSE TO TRUE DO anch:=1; entc:=click.entries; WHILE entc>0 DO DEC(entc); IF click.table[entc].opf<>NIL THEN pv:=NIL; dtime:=0; IF NOT decoded THEN wr(fd, "

") END; pf:=click.table[entc].pff0; pfend:=click.table[entc].pff; IF pfend<>NIL THEN pfend:=pfend^.next END; IF pf=NIL THEN pf:=click.table[entc].opf^.frames; pfend:=NIL END; WHILE pf<>pfend DO IF (click.table[entc].typf<>"R") OR samepath(pf) THEN IF decoded THEN wr(fd, '

'); decode(h, pf^.vardat, pv, pf^.time, dtime, pf^.nodraw, TRUE); coltxt(fd, h, TRUE); wr(fd, "

"+CR+LF); IF posvalid(pf^.vardat^.pos) THEN pv:=pf^.vardat END; dtime:=pf^.time; ELSE wr(fd, ''); TimeToStr(pf^.time MOD 86400, h); Append(h, ""); wr(fd, h); decode(h, pf^.vardat, pv, pf^.time, dtime, pf^.nodraw, FALSE); coltxt(fd, h, TRUE); wr(fd, "
"+CR+LF); END; INC(anch); END; pf:=pf^.next; END; IF NOT decoded THEN wr(fd, "

"+CR+LF) END; END; END; END; wr(fd, ""+CR+LF+""+CR+LF); Close(fd); END html; <* END *> PROCEDURE drawsquer(img:pIMAGE; p0-,p1-:POSITION; r,g,b:INTEGER); VAR x0, y0, x1, y1:REAL; col:COLTYP; BEGIN IF posvalid(p0) & posvalid(p1) & (mapxy(p0, x0, y1)>=-1) & (mapxy(p1, x1, y0)>=-1) THEN col.r:=r; col.g:=g; col.b:=b; area(img, VAL(INTEGER,x0), VAL(INTEGER,y0), VAL(INTEGER,x1), VAL(INTEGER,y1), col, TRUE); END; END drawsquer; PROCEDURE drawzoomsquer(img:pIMAGE); CONST R=300; G=300; B=200; W=350; VAR x,y,x1,y1:REAL; BEGIN IF click.zoomtox>=0 THEN x:= VAL(REAL, click.x); y:= VAL(REAL, click.y); x1:=VAL(REAL, click.zoomtox); y1:=VAL(REAL, click.zoomtoy); vector(img, x, y, x1, y, R, G, B, W, 0.0); vector(img, x1, y, x1, y1, R, G, B, W, 0.0); vector(img, x1, y1, x, y1, R, G, B, W, 0.0); vector(img, x, y1, x, y, R, G, B, W, 0.0); -- col.r:=60; col.g:=60; col.b:=100; -- area(image, click.x, click.y, click.zoomtox, click.zoomtoy, col, TRUE); END; END drawzoomsquer; PROCEDURE qth(loc:ARRAY OF CHAR):BOOLEAN; CONST FIELD=1.0/24.0*pi/180.0; SFIELD=1.0/240.0*pi/180.0; VAR pos, pos1:POSITION; BEGIN loctopos(pos, loc); IF NOT posvalid(pos) THEN RETURN FALSE END; setmark1(pos, TRUE, MAX(INTEGER), 0); pos1:=pos; pos.long:=(FLOAT(trunc((pos.long*(180.0/pi) + 180.0)*12.0))/12.0 - (180.0 - 1.0/24.0))*(pi/180.0); pos.lat :=(FLOAT(trunc((pos.lat *(180.0/pi) + 90.0)*24.0))/24.0 - ( 90.0 - 1.0/48.0))*(pi/180.0); limpos(pos); click.squerpos0.lat:=pos.lat+FIELD/2.0; click.squerpos1.lat:=pos.lat-FIELD/2.0; click.squerpos0.long:=pos.long-FIELD; click.squerpos1.long:=pos.long+FIELD; limpos(click.squerpos0); limpos(click.squerpos1); pos.long:=(FLOAT(trunc((pos1.long*(180.0/pi) + 180.0)*120.0))/120.0 - (180.0 - 1.0/240.0))*(pi/180.0); pos.lat :=(FLOAT(trunc((pos1.lat *(180.0/pi) + 90.0)*240.0))/240.0 - ( 90.0 - 1.0/480.0))*(pi/180.0); limpos(pos); click.squerspos0.lat:=pos.lat+SFIELD/2.0; click.squerspos1.lat:=pos.lat-SFIELD/2.0; click.squerspos0.long:=pos.long-SFIELD; click.squerspos1.long:=pos.long+SFIELD; limpos(click.squerspos0); limpos(click.squerspos1); (* pos1.lat:=pos.lat-FIELD; pos.lat:=pos.lat+FIELD; pos1.long:=pos.long+FIELD*2.0; pos.long:=pos.long-FIELD*2.0; limpos(pos); limpos(pos1); mapzoom(pos, pos1, conf2int(fDEFZOOM, 0, 1, MAXZOOM, MAXZOOMOBJ), TRUE); *) centerpos(click.markpos, mappos); RETURN TRUE END qth; PROCEDURE midscreenpos(VAR pos:POSITION); BEGIN xytodeg(VAL(REAL,xsize)*0.5, VAL(REAL,ysize)*0.5, pos) END midscreenpos; PROCEDURE zoominoutpush(in, fine, allowrev, mouseismiddle:BOOLEAN); VAR z:REAL; BEGIN z:=realzoom(initzoom, finezoom); IF z=FLOAT(trunc(z)) THEN push(z, FALSE) END; zoominout(in, fine, allowrev, mouseismiddle); END zoominoutpush; PROCEDURE find(allpoi:BOOLEAN); VAR h:ARRAY[0..200] OF CHAR; hm:MONCALL; err, poiok:BOOLEAN; op:pOPHIST; pos, pos1:POSITION; BEGIN IF allpoi THEN confstr(fFIND, h) ELSE confstr(fPOIFILTER, h) END; IF NOT qth(h) THEN (* not a locator *) deganytopos(h, pos); poiok:=FALSE; IF NOT posvalid(pos) THEN (* get position of POI name *) POIfind(pos, allpoi, h); poiok:=posvalid(pos); END; IF posvalid(pos) THEN (* poi or lat / long *) IF allpoi THEN click.mhop[0]:=0C; click.onesymbol.tab:=0C; END; push(realzoom(initzoom, finezoom), TRUE); setmark1(pos, TRUE, MAX(INTEGER), 0); -- click.markpos:=pos; click.marktime:=0; click.markalti:=MAX(INTEGER); centerpos(pos, mappos); pandone:=FALSE; textautosize(DOCKX, 0, 3, 4, "b", "marker set"); END; IF allpoi & (poiok OR NOT posvalid(pos)) THEN (* search in aprs names *) op:=findop(h, TRUE); mainpop; findopl(1); IF op<>NIL THEN click.mhop[0]:=0C; click.onesymbol.tab:=0C; mhtx:=OPSENT; IF NOT poiok THEN (* else let focus on poi *) push(realzoom(initzoom, finezoom),TRUE); IF (click.entries>0) & (click.table[0].opf<>NIL) THEN op:=oppo(click.table[0].opf^.call); IF op<>NIL THEN click.mhop:=op^.call END; END; pandone:=FALSE; lums.rf:=0; IF op<>NIL THEN err:=FALSE; Assign(h, op^.call); IF NOT posvalid(op^.lastpos) THEN err:=TRUE; Append(h, " No valid Position!") END; IF op^.sym.tab<" " THEN err:=TRUE; Append(h, " No valid Symbol!"); IF posvalid(op^.lastpos) THEN (* set marker instead of missing symbol *) setmark1(op^.lastpos, FALSE, MAX(INTEGER), realtime); END; END; IF err THEN textautosize(0, 0, 3, 0, "b", h) END; END; END; ELSIF NOT poiok THEN Assign(hm, h); findsize(pos, pos1, hm, "O"); IF posvalid(pos) THEN push(realzoom(initzoom, finezoom), FALSE); click.mhop:=hm; mhtx:=OPOBJ; pandone:=FALSE; ELSE textautosize(0, 0, 3, 10, "e", LF+"not found!"+LF) END; END; END; END; END find; PROCEDURE internstat; VAR op:pOPHIST; fr:pFRAMEHIST; opc, frc, varc, bytec:CARDINAL; oldest, newest:TIME; s:ARRAY[0..10000] OF CHAR; h:ARRAY[0..30] OF CHAR; ut:TIME; i:CARDINAL; BEGIN newest:=0; oldest:=MAX(TIME); opc:=0; frc:=0; varc:=0; bytec:=0; op:=ophist; WHILE op<>NIL DO INC(opc); fr:=op^.frames; WHILE fr<>NIL DO INC(frc); IF fr^.timenewest THEN newest:=fr^.time END; IF fr^.vardat^.lastref=fr THEN INC(varc); INC(bytec, Length(fr^.vardat^.raw)); END; fr:=fr^.next; END; op:=op^.next; END; Assign(s, "System Stat"); ut:=time(); IF ut>uptime THEN Append(s, LF+"Uptime:"); TimeToStr(ut-uptime, h); Append(s, h); END; Append(s, LF+"Objects:"); IntToStr(opc, 1, h); Append(s, h); Append(s, LF+"Frames:"); IntToStr(frc, 1, h); Append(s, h); Append(s, LF+"Different Frames:"); IntToStr(varc, 1, h); Append(s, h); Append(s, LF+"Rawdata Bytes:"); IntToStr(bytec, 1, h); Append(s, h); IF frc>0 THEN Append(s, LF+"Compressed to:"); IntToStr(100*varc DIV frc, 1, h); Append(s, h); Append(s, "%"); END; IF newest>0 THEN Append(s, LF+"Oldest:"); DateLocToStr(oldest, h); Append(s, h); Append(s, LF+"Newest:"); DateLocToStr(newest, h); Append(s, h); END; Append(s, LF+"Heap Rawdata:"); IntToStr(debugmem.mon, 1, h); Append(s, h); Append(s, LF+"Heap Screen: "); IntToStr(debugmem.screens, 1, h); Append(s, h); Append(s, LF+"Heap Menus: "); IntToStr(debugmem.menus, 1, h); Append(s, h); Append(s, LF+"Srtm Cache: "); IntToStr(srtmmem, 1, h); Append(s, h); Append(s, LF+"POI Cache: "); IntToStr(debugmem.poi, 1, h); Append(s, h); tcpconnstat(s); FOR i:=0 TO HIGH(udpsocks) DO udpconnstat(i, s) END; say(s, 0, "b"); END internstat; PROCEDURE setshowall; BEGIN click.mhop[0]:=0C; click.onesymbol.tab:=0C; click.watchmhop:=FALSE; lums.wxcol:=0C; configbool(fGEOPROFIL, FALSE); say("Show All", 2, "g"); END setshowall; PROCEDURE View(n:CARDINAL); VAR z:REAL; pos, mid:POSITION; s, h:ARRAY[0..100] OF CHAR; BEGIN IF Shift THEN z:=realzoom(initzoom, finezoom); FixToStr(z+0.05, 2, s); midscreenpos(mid); Append(s, " "); postostr(mid, "4", h); Append(s, h); setcfg(fVIEW, n, s, 1); killallmenus; say("View stored!", 4, "r"); ELSE z:=0.0; posinval(pos); getview(fVIEW, n, z, pos); push(realzoom(initzoom, finezoom), FALSE); IF z<>0.0 THEN midscreenpos(mid); mid.lat:=mid.lat+FLOATERRCORR; initzoom:=trunc(z); finezoom:=1.0+z-FLOAT(initzoom); shiftmap(xsize DIV 2, ysize DIV 2, ysize, realzoom(initzoom, finezoom), mid); mappos:=mid; END; IF posvalid(pos) THEN centerpos(pos, mappos) END; pandone:=FALSE; IF click.mhop[0]<>0C THEN setshowall END; rdonesymb(FALSE, TRUE); (* show all symbols *) END; END View; PROCEDURE follow; VAR op:pOPHIST; BEGIN tracenew.winevent:=0; op:=findop(tracenew.call, FALSE); IF op<>NIL THEN (* WrInt(ORD(tracenew.follow), 2); WrInt(ORD(click.mhop[0]=0C), 2); WrInt(ORD(click.mhop=op^.call), 2); WrInt(ORD(tracenew.beep), 2); WrStrLn(" follow"); *) IF tracenew.follow & ((click.mhop[0]=0C) OR (click.mhop=op^.call)) THEN pantoop(op) END; IF tracenew.beep & configon(fBEEPWATCH) THEN beeplim(100, conf2int(fBEEPWATCH, 0, 20, 8000, 800), conf2int(fBEEPWATCH, 1, 0, 5000, 100)); END; clickwatchpos:=op^.lastpos; popwatchcall(tracenew.call); IF tracenew.follow THEN -- IF lums.centering<100 THEN -- click.markpos:=op^.lastpos -- ELSE click.clickpos:=op^.lastpos -- END; END; maptrys:=30; END; tracenew.call[0]:=0C; END follow; PROCEDURE MapPackage; VAR lu, rd:POSITION; s, s1:ARRAY[0..999] OF CHAR; BEGIN xytodeg(0.0, VAL(REAL,ysize), lu); xytodeg(VAL(REAL,xsize), 0.0, rd); textautosize(0, 0, 16, 0, "b", "Calculating Sizes"); redraw(image); StartMapPackage(lu, rd, conf2int(fDOWNLOADZOOM, 0, 1, MAXZOOM, 6), TRUE); s:= "Left up : "; postostr(mappack.leftup, "2", s1); Append(s, s1); Append(s, LF+"Right down: "); postostr(mappack.rightdown, "2", s1); Append(s, s1); Append(s, LF+"From Zoom 1 to "); IntToStr(mappack.tozoom, 1, s1); Append(s, s1); IF NOT click.chkmaps THEN Append(s, LF+"Map Check aborted!"); ELSE Append(s, LF+"Total Tiles : "); IntToStr(mappack.mapscnt, 1, s1); Append(s, s1); Append(s, LF+"Download Tiles: "); IntToStr(mappack.needcnt, 1, s1); Append(s, s1); Append(s, LF+"Estimated "); FixToStr(FLOAT(mappack.needcnt)*0.018, 3, s1); Append(s, s1); Append(s, "MByte"); END; killmenuid(16); IF mappack.needcnt>0 THEN textautomenu(DOCKX, 0, 16, 0, "r", s, " Start Download", CMDSTARTDOWNLOAD); ELSE textautosize(DOCKX, 0, 16, 0, "b", s) END; END MapPackage; PROCEDURE zoomtosquare; CONST TOSMALL=5; VAR p1, p2:POSITION; BEGIN IF (click.zoomtox>=0) & ((ABS(click.x-click.zoomtox)>TOSMALL) OR (ABS(click.y-click.zoomtoy)>TOSMALL)) THEN xytodeg(VAL(REAL,click.x), VAL(REAL,click.y), p1); xytodeg(VAL(REAL,click.zoomtox), VAL(REAL,click.zoomtoy), p2); zoomtomarks(p1, p2); END; click.zoomtox:=-1; (* zoom done *) END zoomtosquare; PROCEDURE screenshot; VAR s, h, hh:ARRAY[0..999] OF CHAR; c:CHAR; i, j, n:CARDINAL; ok:INTEGER; BEGIN confstr(fFOTOFN, s); s[HIGH(s)]:=0C; h:=s; i:=0; WHILE (s[i]<>0C) & (s[i]<>"%") DO INC(i) END; IF s[i]="%" THEN IF s[i+1]="t" THEN (* insert date in filename *) s[i]:=0C; DateToStr(time()+localtime(), hh); n:=0; WHILE hh[n]<>0C DO IF (hh[n]<"0") OR (hh[n]>"9") THEN hh[n]:="-" END; INC(n); END; Append(s, hh); INC(i, 2); WHILE h[i]<>0C DO Append(s, h[i]); INC(i) END; ELSIF s[i+1]="n" THEN (* insert serial number until new file *) n:=0; REPEAT s[i]:=CHR(n DIV 100 MOD 10 + ORD("0")); s[i+1]:=CHR(n DIV 10 MOD 10 + ORD("0")); s[i+2]:=CHR(n MOD 10 + ORD("0")); s[i+3]:=0C; j:=i+2; WHILE h[j]<>0C DO Append(s, h[j]); INC(j) END; INC(n); UNTIL (n>999) OR NOT Exists(s); END; END; IF s<>0C THEN killallmenus; (* dump panorama image pointer *) IF panoimage<>NIL THEN ok:=saveppm(s, panoimage, HIGH(panoimage^)+1, HIGH(panoimage^[0])+1, FALSE); ELSE ok:=saveppm(s, image, xsize, ysize, autoshots<>0) END; IF ok<0 THEN Append(s, " write error"); c:="e"; ELSE Append(s, " saved"); c:="b"; END; textautosize(0, 0, 6, 0, c, s); ELSE IF WITHX11 THEN textautosize(0, 0, 6, 0, "e", LF+"no filename"+LF); ELSE WrStrLn("no image filename"); END END; END screenshot; PROCEDURE drawtime(img:pIMAGE; t:TIME; fast:INTEGER); TYPE sCHGEN=SET OF [0..34]; CONST CHGEN=ARRAY OF sCHGEN {{1,2,3, 5,9,10,14,15,19,20,24,25,29,31,32,33}, {2, 6,7,10,12,17,22,27,31,32,33}, {1,2,3, 5,9, 14, 18, 22, 26, 30..34}, {1,2,3, 9, 14, 16,17,18, 24, 29, 31,32,33}, {0,5, 8,10,13, 15,18, 20..24, 28, 33}, {0..4, 5,10..13, 19, 24, 25,29, 31,32,33}, {2, 6, 10, 15..18, 20,24, 25,29, 31,32,33}, {0..4, 9, 13, 17, 21, 26, 31}, {1,2,3, 5,9, 10,14, 16,17,18, 20,24, 25,29, 31,32,33}, {1,2,3, 5,9, 10,14, 16..19, 24, 29, 31,32,33}, {30}, {10, 25}, {}}; POSX=4; POSY=18; dimmlev=200.0*256.0; VAR s:ARRAY[0..31] OF CHAR; ch:CARDINAL; col:COLTYP; i, x, y, px, l:CARDINAL; lum:REAL; BEGIN DateToStr(t+localtime(), s); s[16]:=0C; (* strip off seconds *) IF fast<0 THEN fast:=0 ELSIF fast>200 THEN fast:=200 END; fast:=fast*4; col.r:=1000; col.g:=1000-fast; col.b:=200+fast; l:=0; i:=0; px:=POSX; WHILE s[i]>0C DO ch:=ORD(s[i]); IF (ch>=ORD("0")) & (ch<=ORD("9")) THEN DEC(ch, ORD("0")) ELSIF ch=ORD(".") THEN ch:=10 ELSIF ch=ORD(":") THEN ch:=11 ELSE ch:=12 END; IF ch<=HIGH(CHGEN) THEN s[l]:=CHR(ch); INC(l) END; IF ch<=9 THEN INC(px, 12) ELSE INC(px, 5) END; INC(i); END; FOR y:=POSY+1 TO POSY-15 BY -1 DO FOR x:=POSX TO px DO WITH img^[x][y] DO lum:=FLOAT(VAL(CARDINAL,r)*87 + VAL(CARDINAL,g)*140 + VAL(CARDINAL,b)*28); IF lum>dimmlev THEN lum:=dimmlev/lum; r:=trunc(FLOAT(r)*lum); g:=trunc(FLOAT(g)*lum); b:=trunc(FLOAT(b)*lum); END; END; END; END; px:=POSX; i:=0; WHILE i0 THEN pf:=click.table[click.selected].pff0; IF (pf<>NIL) & posvalid(pf^.vardat^.pos) THEN oldpos:=pf^.vardat^.pos; xytodeg(VAL(REAL,click.x), VAL(REAL,click.y), clickpos); d0:=distance(clickpos, pf^.vardat^.pos); --WrInt(trunc(d0*1000.0), 10); WrLn; LOOP pf:=pf^.next; IF pf=NIL THEN EXIT END; IF posvalid(pf^.vardat^.pos) & ((pf^.vardat^.pos.lat<>oldpos.lat) OR (pf^.vardat^.pos.long<>oldpos.long)) THEN d1:=distance(clickpos, pf^.vardat^.pos); --WrInt(trunc(d1*1000.0), 15);WrInt(trunc(d0*1000.0), 15);WrLn; IF d1d0 THEN EXIT END; END; END; END; END; END nearwaypoint; PROCEDURE clickdelwaypoint; VAR s:ARRAY[0..100] OF CHAR; BEGIN nearwaypoint; WITH click.table[0] DO delwaypoint(opf, pff0); Assign(s, opf^.call); Append(s, " waypoint Deleted"); say(s, 4, "r"); END; END clickdelwaypoint; PROCEDURE savevideo420(img:pIMAGE; fn:ARRAY OF CHAR; format:CHAR; VAR bytecnt:REAL); CONST LF=12C; VAR x,y:INTEGER; ww, rr, gg, bb:INTEGER; pw, pr, pb:CARDINAL; h,s:ARRAY[0..255] OF CHAR; PROCEDURE flo(c:INT16):INTEGER; BEGIN IF c<=HIGH(gammatab) THEN RETURN ORD(gammatab[c]) ELSE RETURN 255 END; END flo; BEGIN IF NOT FdValid(videofd) THEN (* videofd:=Create(fn); *) IF Exists(fn) THEN videofd:=OpenWrite(fn) ELSE videofd:=OpenWrite(fn) END; IF NOT FdValid(videofd) THEN RETURN END; IF format="M" THEN h:="YUV4MPEG2 C420jpeg W"; IntToStr(xsize, 1, s); Append(h, s); Append(h, " H"); IntToStr(ysize, 1, s); Append(h, s); Append(h, " F25000000:1000000 Ip"+LF); WrBin(videofd, h, Length(h)); END; END; IF vidbuf=NIL THEN ALLOCATE(vidbuf, xsize*ysize*3 DIV 2); debugmem.req:=xsize*ysize*3 DIV 2; INC(debugmem.screens, debugmem.req); IF vidbuf=NIL THEN Error("video buffer alloc") END; END; IF format="M" THEN h:="FRAME"+LF; WrBin(videofd, h, 6); END; pw:=0; pb:=xsize*ysize; pr:=pb+pb DIV 4; FOR y:=ysize-1 TO 0 BY -1 DO FOR x:=0 TO xsize-1 DO WITH img^[x][y] DO IF format="M" THEN vidbuf^[pw]:=CHR(flo((VAL(CARDINAL,r)*76 + VAL(CARDINAL,g)*150 + VAL(CARDINAL,b)*29) DIV 256)); ELSE vidbuf^[pw]:=CHR(flo((VAL(CARDINAL,r)*76 + VAL(CARDINAL,g)*150 + VAL(CARDINAL,b)*29) DIV 256)*219 DIV 256 + 16); END; INC(pw); END; IF ODD(y) & ODD(x) THEN WITH img^[x-1][y] DO rr:=r; gg:=g; bb:=b; END; WITH img^[x][y] DO INC(rr,r); INC(gg,g); INC(bb,b); END; WITH img^[x-1][y-1] DO INC(rr,r); INC(gg,g); INC(bb,b); END; WITH img^[x][y-1] DO INC(rr,r); INC(gg,g); INC(bb,b); END; rr:=flo(rr DIV 4); gg:=flo(gg DIV 4); bb:=flo(bb DIV 4); ww:=(rr*76 + gg*150 + bb*29) DIV 256; rr:=(rr-ww)*145 DIV 256 + 128; IF rr<0 THEN rr:=0 ELSIF rr>255 THEN rr:=255 END; bb:=(bb-ww)*182 DIV 256 + 128; IF bb<0 THEN bb:=0 ELSIF bb>255 THEN bb:=255 END; IF format<>"M" THEN vidbuf^[pr]:=CHR(bb); vidbuf^[pb]:=CHR(rr); ELSE vidbuf^[pr]:=CHR(rr); vidbuf^[pb]:=CHR(bb); END; INC(pr); INC(pb); END; END; END; WrBin(videofd, vidbuf^, xsize*ysize*3 DIV 2); bytecnt:=bytecnt+FLOAT(xsize*ysize*3 DIV 2); END savevideo420; (* PROCEDURE savevideo444(img:pIMAGE; n:CARDINAL); VAR x,y,p:INTEGER; buf:ARRAY[0..65535] OF CHAR; c, yy, rr, gg, bb:REAL; PROCEDURE flo(c:CARD16):REAL; BEGIN IF c<=HIGH(gammatab) THEN RETURN FLOAT(ORD(gammatab[c])) ELSE RETURN 255.0 END; END flo; BEGIN IF NOT FdValid(videofd) THEN RETURN END; p:=0; FOR y:=ysize-1 TO 0 BY -1 DO FOR x:=0 TO xsize-1 DO WITH img^[x+y*xsize] DO rr:=flo(r); gg:=flo(g); bb:=flo(b) END; yy:=rr*0.299 + gg*0.587 +bb*0.114; buf[p]:=CHR(TRUNC(yy*(219.0/255.0))+16); INC(p); IF p>HIGH(buf) THEN WrBin(videofd, buf, p); p:=0 END; c:=(bb-yy)*0.565+128.0; IF c<0.0 THEN c:=0.0 ELSIF c>255.9 THEN c:=255.0 END; buf[p]:=CHR(TRUNC(c)); INC(p); IF p>HIGH(buf) THEN WrBin(videofd, buf, p); p:=0 END; c:=(rr-yy)*0.713+128.0; IF c<0.0 THEN c:=0.0 ELSIF c>255.9 THEN c:=255.0 END; buf[p]:=CHR(TRUNC(c)); INC(p); IF p>HIGH(buf) THEN WrBin(videofd, buf, p); p:=0 END; END; END; IF p>0 THEN WrBin(videofd, buf, p) END; END savevideo444; *) PROCEDURE wrvidsize(b:REAL); VAR s:ARRAY[0..100] OF CHAR; BEGIN FixToStr(b/1000000.0, 2, s); Append(s, " MBytes written"); say(s, 0, "b"); END wrvidsize; PROCEDURE copy(VAR dest, src:IMAGE); VAR x:CARDINAL; BEGIN FOR x:=0 TO HIGH(dest) DO MOVE(ADR(src[x]), ADR(dest[x]), SIZE(dest[0])); END; END copy; PROCEDURE cmpcol(c1, c2:COLTYP):BOOLEAN; BEGIN RETURN (c1.r<>c2.r) OR (c1.g<>c2.g) OR (c1.b<>c2.b) END cmpcol; PROCEDURE addradio; (* radiation visability map *) VAR abort:BOOLEAN; c1, c2:COLTYP; BEGIN IF posvalid(click.markpos) OR posvalid(click.measurepos) THEN lums.rf:=0; getgeocol(fCOLMARK1, geobri(), 100,0,0, c1); getgeocol(fCOLMARK2, geobri(), 0,100,0, c2); IF NOT radio.wasradio OR radio.wasaltimap OR (radio.markpos.lat<>click.markpos.lat) OR (radio.markpos.long<>click.markpos.long) OR (radio.measurepos.lat<>click.measurepos.lat) OR (radio.measurepos.long<>click.measurepos.long) OR (radio.mappos.lat<>mappos.lat) OR (radio.mappos.long<>mappos.long) OR (radio.initzoom<>initzoom) OR (radio.finezoom<>finezoom) OR (radio.ant1<>getant(fANT1)) OR (radio.ant2<>getant(fANT2)) OR (radio.ant3<>getant(fANT3)) OR (radio.bri<>geobri()) OR (radio.contr<>geocontr()) OR cmpcol(radio.c1, c1) OR cmpcol(radio.c2, c2) OR (radio.qual<>confflags(fSRTMCACHE, 0)) OR (radio.refrac<>getrefrac()) THEN abort:=FALSE; clr(rfimg); IF posvalid(click.markpos) THEN radioimage(rfimg, click.markpos, 0, abort); END; IF NOT abort & posvalid(click.measurepos) THEN radioimage(rfimg, click.measurepos, ORD(posvalid(click.markpos)), abort); END; -- IF (lums.map>0) & posvalid(click.measurepos) & posvalid(click.markpos) THEN makebw(image) END; radio.wasradio:=TRUE; radio.wasaltimap:=FALSE; radio.markpos:=click.markpos; radio.measurepos:=click.measurepos; radio.mappos:=mappos; radio.initzoom:=initzoom; radio.finezoom:=finezoom; radio.ant1:=getant(fANT1); radio.ant2:=getant(fANT2); radio.ant3:=getant(fANT3); radio.bri:=geobri(); radio.contr:=geocontr(); radio.c1:=c1; radio.c2:=c2; radio.qual:=confflags(fSRTMCACHE, 0); radio.refrac:=getrefrac(); reliefcolors(rfimg, posvalid(click.measurepos) & posvalid(click.markpos)); IF abort THEN textautosize(0, 0, 5, 2, "r", "radiorange aborted"); closeradio; radio.wasradio:=FALSE; sayonoff("Radiorange Map", click.withradio); END; END; IF radio.wasradio THEN addmap(image, rfimg) END; END; END addradio; PROCEDURE altitudemap; (* simple relieaf map layer *) VAR abort:BOOLEAN; c1, c2:COLTYP; BEGIN lums.rf:=0; IF NOT radio.wasradio OR NOT radio.wasaltimap OR (radio.mappos.lat<>mappos.lat) OR (radio.mappos.long<>mappos.long) OR (radio.initzoom<>initzoom) OR (radio.finezoom<>finezoom) OR (radio.bri<>geobri()) THEN clr(rfimg); IF SimpleRelief(rfimg) THEN radio.wasaltimap:=TRUE; radio.wasradio:=TRUE; radio.mappos:=mappos; radio.initzoom:=initzoom; radio.finezoom:=finezoom; radio.bri:=geobri(); ELSE textautosize(0, 0, 3, 2, "r", "no altitude data found") END; END; IF radio.wasradio THEN addmap(image, rfimg) END; END altitudemap; PROCEDURE xytomark; VAR pos:POSITION; BEGIN -- xytodeg(VAL(REAL,click.x), VAL(REAL,click.y), pos); xytodeg(VAL(REAL, xmouse.x), VAL(REAL, VAL(INTEGER, mainys())-xmouse.y), pos); setmark1(pos, TRUE, MAX(INTEGER), 0); postoconfig(pos); click.waysum:=0.0; END xytomark; PROCEDURE xytomark2; VAR pos:POSITION; BEGIN xytodeg(VAL(REAL, xmouse.x), VAL(REAL, VAL(INTEGER, mainys())-xmouse.y), pos); IF posvalid(pos) THEN click.measurepos:=pos; copypastepos(pos); END; END xytomark2; PROCEDURE centermouse(shortcut:BOOLEAN); VAR pos :POSITION; x0,x1,y0,y1 :REAL; BEGIN posinval(pos); IF shortcut THEN xytodeg(VAL(REAL, xmouse.x), VAL(REAL, VAL(INTEGER, mainys())-xmouse.y), pos); IF posvalid(click.bubblpos) & (mapxy(click.bubblpos, x0, y0)>=-1) & posvalid(pos) & (mapxy(pos, x1, y1)>=-1) & (sqr(x0-x1) + sqr(y0-y1)<25.0) THEN pos:=click.bubblpos END; (* POI is near mouse so use POI position to center *) ELSIF (click.entries>0) & (click.table[click.selected].opf<>NIL) & posvalid(click.table[click.selected].opf^.lastpos) THEN pos:=click.table[click.selected].opf^.lastpos; ELSIF posvalid(click.clickpos) THEN pos:=click.clickpos END; IF posvalid(pos) THEN push(realzoom(initzoom, finezoom), TRUE); centerpos(pos, mappos); END; END centermouse; PROCEDURE clicktomark; BEGIN IF (click.entries>0) & (click.table[click.selected].opf<>NIL) & posvalid(click.table[click.selected].opf^.lastpos) THEN setmarkalti(click.table[click.selected].pff0, click.table[click.selected].opf, TRUE); ELSE setmark1(click.clickpos, TRUE, MAX(INTEGER), 0) END; END clicktomark; PROCEDURE setmarklockpoi(marker2:BOOLEAN); VAR pos:POSITION; name,info:ARRAY[0..40] OF CHAR; BEGIN xytodeg(VAL(REAL, xmouse.x), VAL(REAL, VAL(INTEGER, mainys())-xmouse.y), pos); POIname(pos, name,info); IF name<>"" THEN IF marker2 THEN click.measurepos:=pos; copypastepos(pos); ELSE setmark1(pos, TRUE, MAX(INTEGER), 0); postoconfig(click.bubblpos); END; info:="Locked to "; Append(info, name); say(info, 4, "b"); ELSE say("Not Locked", 4, "r") END; END setmarklockpoi; PROCEDURE slowupdate():TIME; (* add image update time on cpu intensiv options *) VAR t:TIME; BEGIN t:=makeimagetime; IF t>20 THEN t:=20 END; RETURN t*2+updateintervall END slowupdate; PROCEDURE addrftracks(dryrun, tx:BOOLEAN); VAR clr:BOOLEAN; BEGIN clr:=NOT dryrun; (* clr old image before draw *) IF tx THEN mhtracks(click.mhop, clr) ELSE rftracks(click.mhop, clr) END; IF NOT (dryrun OR clr) THEN (* not dryrun and something drawn *) radio.wasradio:=FALSE; (* no radiolink data in rfimg now *) shine(rfimg, lums.rfbri); addmap(image, rfimg); END; END addrftracks; PROCEDURE animate(singlecall-:MONCALL; step:TIME; tofile:ARRAY OF CHAR); CONST QUICKMOV=10; (* faster if nothing visable moves *) FASTDELAY=70; (* delay switching to fast *) SLOWER=3; (* steps befor next move switch to slow *) TRAILER=10; (* steps at end of move till video end *) VAR op, singleop:pOPHIST; pf, pf1:pFRAMEHIST; efil:ERRSET; nextmov, vtime, endtime, stime, showt, fractime:TIME; fast, fastdelay:INTEGER; skip, ii:CARDINAL; x,y,nomove:REAL; col:COLTYP; textpos:INT8; dir, mapok, blown,stop:BOOLEAN; ipos:POSITION; itime, iitime:REAL; bytew:REAL; s,s1:ARRAY[0..40] OF CHAR; minalt:INTEGER; dat, dat1:DAT; hoverobj:CLICKOBJECT; BEGIN closeradio; singleop:=oppo(singlecall); IF NOT pandone THEN findsize(newpos0, newpos1, click.mhop, "T"); mapzoom(newpos0, newpos1, conf2int(fDEFZOOM, 0, 1, MAXZOOM, MAXZOOMOBJ), TRUE, FALSE); pandone:=TRUE; mercator(mappos.long, mappos.lat, initzoom, inittilex, inittiley, shiftx, shifty); END; showt:=0; bytew:=0.0; click.dryrun:=FALSE; vtime:=systime; (* last whole data time *) endtime:=vtime-VAL(TIME,lums.firstdim+lums.maxdim); (* start time minimum *) stime:=endtime; nomove:=movest(500)*5.0; (* min km/s for a moving object *) IF step=0 THEN step:=trunc(sqrt(nomove)*FLOAT(VIDEORATE*conf2int(fANIMSPEED, 0, 0, 10000, 400)))+1 END; fastdelay:=-conf2int(fVIDEOFAST, 0, 0, 10000, 0); markvisable(0C); op:=ophist; xytodeg(VAL(REAL,xsize), 0.0, ipos); IF configon(fTRACKFILT) THEN efil:=ERRSET{eDIST} ELSE efil:=ERRSET{eDIST,eNODRAW,eSYMB} END; minalt:=conf2int(fALTMIN, 0, -10000, 65535, -10000); stop:=FALSE; WHILE op<>NIL DO WITH op^ DO EXCL(drawhints, MOVES); IF MARKED IN drawhints THEN IF (distance(margin0, margin1)>nomove*400.0) & ((singleop=NIL) OR (op=singleop)) & (op^.sym.tab<>DELETSYM) THEN (* they will move *) pf1:=NIL; pf:=op^.frames; WHILE pf<>NIL DO IF (pf^.nodraw-efil=ERRSET{}) & posvalid(pf^.vardat^.pos) THEN IF pf1<>NIL THEN WITH pf1^.vardat^ DO IF (pf1^.time>=stime) & posvalid(pos) & (pos.long<=ipos.long) & (pos.lat>=ipos.lat) & (pos.long>=mappos.long) & (pos.lat<=mappos.lat) -- & (pf^.next<>NIL) & posvalid(pf^.next^.vardat^.pos) & (distance(pos, pf^.vardat^.pos)>nomove*10.0) THEN (* moving *) IF pf^.time>endtime THEN endtime:=pf^.time END; (* show till latest mover *) IF pf1^.timeendtime THEN endtime:=lasttime END; (* show till latest mover *) -- IF (frames<>NIL) & (frames^.time0 THEN loadmap(image, inittilex, inittiley, initzoom, finezoom, shiftx, shifty, mapok, blown, configon(fALLOWEXP), FALSE); ELSE clr(image) END; IF lums.sym>0 THEN IF lums.obj>0 THEN symbols(ophist, TRUE, hoverobj) END; symbols(ophist, FALSE, hoverobj); END; IF lums.text>0 THEN text(ophist, FALSE, FALSE, TRUE); (* first draw dimmed *) text(ophist, TRUE, FALSE, TRUE); (* overdraw dimmed *) END; cc(image, vtime, endtime); op:=ophist; WHILE op<>NIL DO EXCL(op^.drawhints, MARKED); op:=op^.next; END; (* now use only mover(s) *) lums.moving:=FALSE; videofd:=InvalidFd; IF vtime>stime THEN stime:=vtime END; -- icnt:=0; fast:=fastdelay; skip:=0; fractime:=0; REPEAT IF skip=0 THEN (* MOVE(image, rfimg, SIZE(PIX)*xsize*ysize); *) copy(rfimg^, image^); IF lums.track>1 THEN tracks(rfimg, ophist, vtime) END; END; op:=ophist; nextmov:=endtime; WHILE op<>NIL DO IF MOVES IN op^.drawhints THEN pf:=NIL; pf1:=op^.frames; WHILE (pf1<>NIL) & (vtime>pf1^.time) DO IF pf1^.nodraw-efil=ERRSET{} THEN pf:=pf1 END; pf1:=pf1^.next; END; WHILE (pf1<>NIL) & (pf1^.nodraw-efil<>ERRSET{}) DO pf1:=pf1^.next END; IF pf<>NIL THEN IF (pf1<>NIL) & (pf1^.time>pf^.time) & (vtime>pf^.time) THEN (* interpolate waypoints *) itime:=(FLOAT(vtime-pf^.time)+FLOAT(fractime)*(1.0/VIDEORATE))/FLOAT(pf1^.time-pf^.time); -- IF itime>1.0 THEN itime:=1.0 ELSIF itime<0.0 THEN itime:=0.0 END; iitime:=1.0-itime; ipos.long:=pf^.vardat^.pos.long*iitime + pf1^.vardat^.pos.long*itime; ipos.lat :=pf^.vardat^.pos.lat *iitime + pf1^.vardat^.pos.lat *itime; dir:=pf^.vardat^.pos.long>pf1^.vardat^.pos.long; (* mirror symbol on long deg *) ELSE (* end of track *) ipos:=pf^.vardat^.pos; dir:=MIRRORSYM IN op^.drawhints; itime:=-1.0 END; IF (mapxy(ipos, x, y)>=0) & vistime(pf^.time) THEN IF skip=0 THEN IF op^.poligon & (Decode(pf^.vardat^.raw, dat)>=0) THEN IF (itime>0.0) & (Decode(pf1^.vardat^.raw, dat1)>=0) & (dat.multiline.size=dat1.multiline.size) THEN (* interpolate poligon form *) ii:=0; WHILE ii0C) & (Decode(pf^.vardat^.raw, dat)>=0) THEN (* decode each frame if form changed *) IF (itime>0.0) & (Decode(pf1^.vardat^.raw, dat1)>=0) THEN (* interpolate areasymbol form *) WITH dat.areasymb.dpos DO lat :=lat *iitime + dat1.areasymb.dpos.lat *itime; long:=long*iitime + dat1.areasymb.dpos.long*itime; END; END; drawareasym(rfimg, ipos, dat.areasymb, lums.obj DIV 4); ELSE drawsym(rfimg, op^.sym.tab, op^.sym.pic, dir, x, y, lums.sym DIV 4); IF (op^.sym.pic="@") & (Decode(pf^.vardat^.raw, dat)>=0) THEN IF (itime>0.0) & (Decode(pf1^.vardat^.raw, dat1)>=0) THEN (* interpolate storm areas *) WITH dat.areasymb.dpos DO lat :=lat *iitime + dat1.areasymb.dpos.lat *itime; long:=long*iitime + dat1.areasymb.dpos.long*itime; END; stormcicle(rfimg, ipos, dat.wx.radiushurr*iitime + dat1.wx.radiushurr*itime, dat.wx.radiusstorm*iitime + dat1.wx.radiusstorm*itime, dat.wx.wholegale*iitime + dat1.wx.wholegale*itime, lums.sym DIV 4); END; END; END; IF configon(fKMH) & (Decode(pf^.vardat^.raw, dat)>=0) THEN s:=""; IF (dat.speed>0) & (dat.speed0C THEN IntToStr(trunc(FLOAT(dat.speed)*KNOTS), 1, s); Append(s, s1); END; END; IF (dat.altitude=minalt) THEN IF s[0]<>0C THEN Append(s, " ") END; IntToStr(dat.altitude, 1, s1); Append(s, s1); Append(s, "m"); END; IF s[0]<>0C THEN Colset(col, "Y"); textpos:=-8; drawstr(rfimg, s, x+FLOAT(lums.symsize DIV 2-1), y-FLOAT(lums.fontysize+3), lums.text, 0, col, textpos, 0, TRUE, click.dryrun); END; END; Colset(col, "W"); textpos:=0; drawstr(rfimg, op^.call, x+FLOAT(lums.symsize DIV 2-1), y-FLOAT(lums.fontysize DIV 2), lums.text, 0, col, textpos, 0, TRUE, click.dryrun); END; IF (pf1<>NIL) & (distance(pf^.vardat^.pos, pf1^.vardat^.pos)/FLOAT(pf1^.time-pf^.time)>nomove) & (pf1^.timeFASTDELAY*) ); IF endtime>stime THEN col.r:=100; col.g:=800; col.b:=1000; area(rfimg, 0,1, trunc(FLOAT(xsize)*FLOAT(vtime-stime)/FLOAT(endtime-stime)), 3, col, FALSE); END; IF tofile[0]<>0C THEN savevideo420(rfimg, tofile, "M", bytew); -- INC(icnt); IF showt<>time() THEN showt:=time(); wrvidsize(bytew); redraw(rfimg); END; Eventloop(1); ELSE refresh:=TRUE; LOOP (* while stop pressed *) IF refresh THEN redraw(rfimg) END; lums.actfps:=step; (* for faster/slower button *) Eventloop(1000); step:=lums.actfps; IF click.cmd=" " THEN IF stop THEN stop:=FALSE; click.cmd:="A"; ELSE stop:=TRUE; click.cmd:=CMDANIMATEMENU END; ELSIF click.cmd<>CMDANIMATEMENU THEN stop:=FALSE END; IF NOT stop & (click.cmd<>CMDANIMATEMENU) THEN EXIT END; realtime:=time(); END; END; IF fast>250 THEN fast:=250 END; IF fast>0 THEN skip:=fast DIV 25 ELSE skip:=0 END; ELSE DEC(skip) END; INC(fractime, step); INC(vtime, fractime DIV VIDEORATE); fractime:=fractime MOD VIDEORATE; (* IF fast>FASTDELAY THEN INC(vtime, step*STEPMUL) ELSE INC(vtime, step) END; *) realtime:=time(); UNTIL (vtime>endtime+step*TRAILER DIV VIDEORATE) OR (click.cmd<>"A") & (click.cmd<>CMDANIMATE1) & (click.cmd<>CMDVIDEO) OR (newxsize>0); IF FdValid(videofd) THEN Close(videofd); say(VIDEOFN+" Saved", 0, "b"); END; IF vidbuf<>NIL THEN DEC(debugmem.screens, xsize*ysize*3 DIV 2); DEALLOCATE(vidbuf, xsize*ysize*3 DIV 2); vidbuf:=NIL; END; END animate; PROCEDURE makeimage(dryrun:BOOLEAN); VAR mapok:BOOLEAN; mpos:POSITION; hoverobj:CLICKOBJECT; testtime:TIME; BEGIN testtime:=time(); hoverobj.opf:=NIL; markvisable(click.mhop); IF (click.mhop[0]<>0C) & (mhtx=OPHEARD) THEN findsize(newpos0, newpos1, click.mhop, "H"); ELSIF (click.mhop[0]<>0C) & (mhtx=OPOBJ) THEN findsize(newpos0, newpos1, click.mhop, "O"); ELSIF lums.rf>1 THEN findsize(newpos0, newpos1, click.mhop, "R"); ELSE findsize(newpos0, newpos1, click.mhop, "T") END; IF NOT pandone THEN mapzoom(newpos0, newpos1, conf2int(fDEFZOOM, 0, 1, MAXZOOM, MAXZOOMOBJ), TRUE, TRUE); pandone:=TRUE; lums.moving:=FALSE; END; mercator(mappos.long, mappos.lat, initzoom, inittilex, inittiley, shiftx, shifty); click.dryrun:=dryrun; IF dryrun THEN click.min:=lums.symsize DIV 2; click.entries:=0; click.pf0:=NIL; ELSE IF lums.map>0 THEN loadmap(image, inittilex, inittiley, initzoom, finezoom, shiftx, shifty, mapok, isblown, configon(fALLOWEXP), FALSE); -- IF maploadpid.runs & NOT mapok THEN IF NOT mapok & configon(fGETMAPS) THEN tooltips("B"); maptrys:=30; ELSE maptrys:=0 END; ELSE clr(image) END; END; IF (lums.wxcol="R") OR (lums.wxcol="W") THEN (* "w" is show wx stations only *) IF NOT dryrun THEN closeradio; IF lums.map>0 THEN makebw(image) END; clr(rfimg); IF lums.wxcol="R" THEN metercolor("R"); addmap(image, rfimg); clr(rfimg); metercolor("1"); ELSE metercolor("T") END; addmap(image, rfimg); END; ELSIF (lums.rf>1) & (click.mhop[0]<>0C) & (mhtx=OPSENT) THEN addrftracks(dryrun, FALSE); ELSIF (click.mhop[0]<>0C) & (mhtx=OPHEARD) THEN addrftracks(dryrun, TRUE); END; IF lums.moving THEN text(ophist, FALSE, FALSE, TRUE); IF lums.track>1 THEN tracks(image, ophist, MAX(TIME)) END; symbols(ophist, TRUE, hoverobj); IF lums.sym>0 THEN symbols(ophist, FALSE, hoverobj) END; text(ophist, TRUE, FALSE, TRUE); ELSE IF lums.track>1 THEN tracks(image, ophist, MAX(TIME)) END; IF lums.obj>0 THEN symbols(ophist, TRUE, hoverobj); text(ophist, TRUE, TRUE, TRUE); END; IF lums.sym>0 THEN symbols(ophist, FALSE, hoverobj) END; IF NOT dryrun THEN drawpois(image) END; IF (lums.text>0) OR (lums.wxcol<>0C) THEN text(ophist, FALSE, TRUE, TRUE) END; END; IF NOT dryrun THEN IF (click.marktime=0) OR (click.marktime+MARKERTIME>realtime) THEN setmark(image, click.markpos, click.marktime=0) END; drawsquer(image, click.squerpos0, click.squerpos1,0,60,0); drawsquer(image, click.squerspos0, click.squerspos1,0,0,140); IF NOT click.withradio OR click.altimap THEN mpos:=click.measurepos; IF NOT posvalid(mpos) & (hoverobj.opf<>NIL) & configon(fGEOPROFIL) THEN mpos:=hoverobj.opf^.lastpos END; measureline(image, click.markpos, mpos, click.markalti); END; cc(image, time(), 0); IF configon(fRULER) THEN ruler(image) END; Stopticker; drawzoomsquer(image); IF click.withradio THEN IF click.altimap THEN altitudemap ELSE addradio END; ELSE radio.wasradio:=FALSE END; ELSE nearwaypoint; click.dryrun:=FALSE; END; IF lums.wxcol="w" THEN say("Wx Stations (exit with ESC)", 10, "g"); ELSIF lums.wxcol="W" THEN say("Temperatue Map (exit with ESC)", 5, "g") ELSIF lums.wxcol="R" THEN say("Rain Map (exit with ESC)", 5, "g") END; IF hoverobj.opf<>NIL THEN hoverinfo(hoverobj); hoverobj.opf:=NIL END; IF beaconediting & beaconed THEN drawpoliobj(image) END; refresh:=TRUE; realtime:=time(); lastxupdate:=realtime; makeimagetime:=realtime-testtime; END makeimage; PROCEDURE MainEvent; VAR ch:CHAR; cfgs:ARRAY[0..20] OF CHAR; raw, menu, void:BOOLEAN; BEGIN menu:=FALSE; raw:=FALSE; realtime:=time(); IF NOT lums.logmode THEN systime:=realtime END; IF realtime1) & (click.entries html; <* END *> IF click.entries>=1 THEN lums.errorstep:=FALSE END; click.cmd:=0C; IF Shift THEN click.cmd:="X" ELSE IF click.entries=1 THEN IF (click.table[0].typf=tSYMBOL) OR (click.table[0].typf=tOBJECT) THEN IF click.table[0].opf^.lastinftyp>=100 THEN (* wx symbol *) confstr(fCLICKWXSYM, cfgs); IF InStr(cfgs, CMD1USER)>=0 THEN click.cmd:=CMD1USER; ELSIF InStr(cfgs, CMD1USERRF)>=0 THEN click.cmd:=CMD1USERRF; ELSIF InStr(cfgs, CFGHEARD)>=0 THEN click.cmd:=CMDMH; ELSIF InStr(cfgs, "C")>=0 THEN click.cmd:=CMDCENTERMOUSE; END; ELSE (* not wx symbol *) confstr(fCLICKSYM, cfgs); IF InStr(cfgs, CMD1USER)>=0 THEN click.cmd:=CMD1USER; ELSIF InStr(cfgs, CMD1USERRF)>=0 THEN click.cmd:=CMD1USERRF; ELSIF InStr(cfgs, CFGHEARD)>=0 THEN click.cmd:=CMDMH; ELSIF InStr(cfgs, "C")>=0 THEN click.cmd:=CMDCENTERMOUSE; ELSIF InStr(cfgs, "A")>=0 THEN click.cmd:=CMDANIMATE1; ELSIF InStr(cfgs, "X")>=0 THEN click.cmd:="x"; ELSIF InStr(cfgs, "Y")>=0 THEN click.cmd:="y"; END; END; ELSIF click.table[0].typf=tTEXT THEN confstr(fCLICKTEXT, cfgs); IF InStr(cfgs, CMD1USER)>=0 THEN click.cmd:=CMD1USER; ELSIF InStr(cfgs, CMD1USERRF)>=0 THEN click.cmd:=CMD1USERRF; ELSIF InStr(cfgs, CFGHEARD)>=0 THEN click.cmd:=CMDMH; ELSIF InStr(cfgs, "C")>=0 THEN click.cmd:=CMDCENTERMOUSE; ELSIF InStr(cfgs, "A")>=0 THEN click.cmd:=CMDANIMATE1; ELSIF InStr(cfgs, "X")>=0 THEN click.cmd:="x"; ELSIF InStr(cfgs, "Y")>=0 THEN click.cmd:="y"; END; ELSIF click.table[0].typf=tTRACK THEN confstr(fCLICKTRACK, cfgs); IF (click.mhop[0]<>0C) & (click.mhop=click.table[0].opf^.call) THEN (* in single user mode and click same track *) IF InStr(cfgs, CMDDELWAYPOINT)>=0 THEN click.cmd:=CMDDELWAYPOINT; ELSIF InStr(cfgs, "A")>=0 THEN click.cmd:=CMDANIMATE1; END; ELSE IF InStr(cfgs, CMD1USER)>=0 THEN click.cmd:=CMD1USER; ELSIF InStr(cfgs, CMD1USERRF)>=0 THEN click.cmd:=CMD1USERRF; ELSIF InStr(cfgs, "A")>=0 THEN click.cmd:=CMDANIMATE1; ELSIF InStr(cfgs, CMDDELWAYPOINT)>=0 THEN click.cmd:=CMDDELWAYPOINT; END; END; nearwaypoint; (* set marker on click to track *) setmarkalti(click.table[click.selected].pff0, click.table[0].opf, TRUE); click.marktime:=realtime; END; IF InStr(cfgs, CFGRAWDECODED)>=0 THEN raw:=TRUE; menu:=TRUE END; IF click.cmd=0C THEN menu:=TRUE END; (* redraw image *) IF click.marktime=0 THEN (* hard marker *) measure(click.markpos, click.clickpos, mestxt, FALSE); ELSE measure(click.markpos, click.measurepos, mestxt, FALSE) END; -- importbeacon(click.table[click.selected].opf); (* copy to beacon editor *) ELSE (* clicked empty map *) IF (click.marktime=0) OR (click.marktime+MARKERTIME>=realtime) THEN measure(click.markpos, click.clickpos, mestxt, TRUE) END; menu:=TRUE; END; END; confstr(fCLICKMAP, ch); IF NOT Shift & (ch="2") THEN IF posvalid(click.markpos) THEN ch:="Y" ELSE ch:="X" END; END; IF ch=CMDCENTERMOUSE THEN click.cmd:=CMDCENTERMOUSE; ELSIF NOT Shift & (ch="X") OR Shift & (ch="Y") THEN click.cmd:="X"; ELSIF NOT Shift & (ch="Y") OR Shift & (ch="X") THEN click.cmd:="Y"; measure(click.markpos, click.clickpos, mestxt, FALSE); END; IF (click.entries>0) & (click.table[click.selected].typf=tTEXT) & (click.table[click.selected].opf<>NIL) THEN copypaste(click.table[click.selected].opf^.call) END; IF NOT Shift THEN (* not close menus on shift click to map *) IF beaconediting & beaconed THEN IF findmultiline(click.clickpos, click.markpos) THEN click.marktime:=0; click.cmd:=" " END; END; IF NOT lums.headmenuy & ((click.entries=0) OR menu OR (click.mhop[0]<>0C)) OR lums.headmenuy & (click.entries>0) & (menu OR (click.mhop[0]<>0C)) THEN ch:=click.cmd; mainpop; click.cmd:=ch; ELSE killallmenus END; -- THEN mainpop; click.cmd:=" "; ELSE killallmenus END; END; IF mestxt[0]<>0C THEN textautosize(DOCKX, 0, 6, 10, "b", mestxt) END; END; IF raw OR (click.cmd<>0C) THEN --WrInt(ORD(click.cmd), 1); WrStrLn(click.cmd); startmapdelay; IF click.cmd=CURSDOWN THEN mappos.lat:=mappos.lat-movest(ysize)*shiftfine(); limpos(mappos); ELSIF click.cmd=CURSUP THEN mappos.lat:=mappos.lat+movest(ysize)*shiftfine(); limpos(mappos); ELSIF click.cmd=CURSLEFT THEN mappos.long:=mappos.long-movest(xsize)*shiftfine(); limpos(mappos); ELSIF click.cmd=CURSRIGHT THEN mappos.long:=mappos.long+movest(xsize)*shiftfine(); limpos(mappos); ELSIF click.cmd="T" THEN IF posvalid(newpos0) & posvalid(newpos1) THEN mapzoom(newpos0, newpos1, conf2int(fDEFZOOM, 0, 1, MAXZOOM, MAXZOOMOBJ), TRUE, FALSE) END; ELSIF click.cmd="o" THEN click.dryrun:=FALSE; push(realzoom(initzoom, finezoom), FALSE); objsender(click.table[click.selected].opf, click.mhop); mhtx:=OPOBJ; lums.obj:=10*conf2int(fLOBJ, 0, 0, 100, 100); (* switch on objects *) pandone:=FALSE; ELSIF click.cmd=CMDMH THEN click.dryrun:=FALSE; IF click.entries>0 THEN push(realzoom(initzoom, finezoom), FALSE); IF click.table[click.selected].opf<>NIL THEN click.mhop:=click.table[click.selected].opf^.call END; mhtx:=OPHEARD; pandone:=FALSE; (* tracenew.call:=click.mhop; (* watch call for incoming data *) *) END; ELSIF (click.cmd=CMD1USER) OR (click.cmd=CMD1USERRF) THEN click.dryrun:=FALSE; IF click.entries>0 THEN push(realzoom(initzoom, finezoom), FALSE); IF click.table[click.selected].opf<>NIL THEN click.mhop:=click.table[click.selected].opf^.call; -- IF beaconediting() THEN importbeacon(click.table[click.selected].opf) END; (* copy to beacon editor *) END; mhtx:=OPSENT; pandone:=FALSE; lums.errorstep:=FALSE; IF click.cmd=CMD1USERRF THEN lums.rf:=conf2int(fLRF, 0, 0, 100, 30)*10 ELSE lums.rf:=0 END; END; ELSIF click.cmd=CMDANIMATE1 THEN IF click.entries>0 THEN push(realzoom(initzoom, finezoom), FALSE); IF click.table[click.selected].opf<>NIL THEN click.mhop:=click.table[click.selected].opf^.call END; pandone:=FALSE; END; animate(click.mhop, lums.fps, ""); ELSIF click.cmd="0" THEN setshowall; ELSIF (click.cmd="1") OR (click.cmd=CURSHOME) THEN View(0); ELSIF click.cmd="2" THEN View(1); ELSIF click.cmd="3" THEN View(2); ELSIF click.cmd="4" THEN View(3); ELSIF (click.cmd="b") OR (click.cmd=CURSBS) THEN pop; -- mercator(mappos.long, mappos.lat, initzoom, inittilex, inittiley, shiftx, shifty); ELSIF click.cmd=CMDRESETIMGPARMS THEN push(realzoom(initzoom, finezoom), FALSE); resetimgparms; ELSIF click.cmd="+" THEN zoominoutpush(TRUE, Shift OR Ctrl, FALSE, FALSE); ELSIF click.cmd="-" THEN zoominoutpush(FALSE, Shift OR Ctrl, FALSE, FALSE); ELSIF click.cmd=CMDFZOOMIN THEN zoominoutpush(TRUE, TRUE, TRUE, TRUE); ELSIF click.cmd=CMDFZOOMOUT THEN zoominoutpush(FALSE, TRUE, TRUE, TRUE); ELSIF click.cmd=CMDDOWNLOAD THEN MapPackage; ELSIF click.cmd=SCREENSHOT THEN IF NOT WITHX11 THEN makeimage(FALSE) END; screenshot; ELSIF click.cmd="s" THEN rdonesymb(click.onesymbol.tab=0C, TRUE); (* toggle onesymbol *) ELSIF click.cmd="E" THEN lums.errorstep:=NOT lums.errorstep; sayonoff("Show errors", lums.errorstep); ELSIF click.cmd="f" THEN configbool(fTRACKFILT, NOT configon(fTRACKFILT)); sayonoff("Trackfilter", configon(fTRACKFILT)); ELSIF click.cmd="m" THEN lums.moving:=NOT lums.moving; sayonoff("Dimm not Moving", lums.moving); ELSIF click.cmd="R" THEN IF lums.rf=0 THEN lums.rf:=300 ELSE lums.rf:=0 END; ELSIF click.cmd=CMDRADIORANGE THEN IF click.withradio & NOT click.altimap THEN closeradio ELSE click.withradio:=TRUE; click.altimap:=FALSE END; lums.wxcol:=0C; IF click.withradio & NOT (posvalid(click.markpos) OR posvalid(click.measurepos)) THEN say("Radiorange Map On, Set 1 oder 2 Markers", 4, "b"); ELSE sayonoff("Radiorange Map", click.withradio) END; ELSIF click.cmd="H" THEN IF click.withradio & click.altimap THEN closeradio ELSE click.withradio:=TRUE; click.altimap:=TRUE END; lums.wxcol:=0C; sayonoff("Altitude Map", click.withradio); (* ELSIF click.cmd="P" THEN IF click.withradio THEN closeradio ELSE click.withradio:=TRUE; click.panorama:=TRUE END; lums.wxcol:=0C; sayonoff("Panorama", click.withradio); *) ELSIF click.cmd="O" THEN IF lums.obj=0 THEN lums.obj:=10*conf2int(fLOBJ, 0, 0, 100, 100); IF lums.obj<30 THEN (* switch on objects but are too dark *) AddConfLine(fLOBJ, 0, DEFAULTLUMOBJ); (* set to default brightness *) lums.obj:=10*conf2int(fLOBJ, 0, 0, 100, 100); END; ELSE lums.obj:=0 END; sayonoff("Show Items/Objects", lums.obj<>0); ELSIF click.cmd="l" THEN IF lums.text=0 THEN lums.text:=10*conf2int(fLTEXT, 0, 0, 100, 100) ELSE lums.text:=0 END; sayonoff("Labels", lums.text<>0); ELSIF click.cmd=CMDFOLLOW THEN lums.followwhat:=CAST(BITSET, CAST(CARDINAL, lums.followwhat)+1); lums.followwhat:=lums.followwhat*{0,1}; IF NOT anywatchfollow() THEN lums.followwhat:=lums.followwhat*{0} END; int2cfg(fFOLLOW, VAL(CARDINAL,lums.followwhat)); IF lums.followwhat={} THEN say("Map Follow off", 4, "b"); ELSIF lums.followwhat={FOLLOWWATCH} THEN say("Map Follows Watchcall(s)", 4, "b"); ELSIF lums.followwhat={FOLLOWX} THEN say("Map Follows Clicked Symbol", 4, "b"); ELSE say("Map Follows Watchcall and Clicked Symbol", 4, "b") END; ELSIF CAP(click.cmd)="W" THEN IF Shift & (click.cmd="W") THEN click.cmd:="w" END; (* IF click.cmd="W" THEN IF lums.wxcol<>"W" THEN lums.wxcol:="W" ELSE lums.wxcol:=0C END; ELSIF lums.wxcol<>"R" THEN lums.wxcol:="R" ELSE lums.wxcol:=0C END; sayonoff("Wx Colormap", lums.wxcol<>0C); *) IF click.cmd="W" THEN IF lums.wxcol="W" THEN lums.wxcol:=0C ELSIF lums.wxcol="w" THEN lums.wxcol:="W" ELSE lums.wxcol:="w" END; ELSIF lums.wxcol<>"R" THEN lums.wxcol:="R" ELSE lums.wxcol:=0C END; click.mhop[0]:=0C; click.onesymbol.tab:=0C; closeradio; ELSIF click.cmd=CMDCENTER THEN centermouse(FALSE); (* center last leftclicked *) ELSIF click.cmd=CMDCENTERMOUSE THEN centermouse(TRUE); (* center position *) ELSIF (click.cmd=CMDLISTWINLINE) & posvalid(click.markpos) THEN (* click to listwin line *) push(realzoom(initzoom, finezoom), TRUE); centerpos(click.markpos, mappos); click.marktime:=realtime; IF click.mhop[0]<>0C THEN setshowall END; ELSIF (click.cmd=CMDCLICKWATCH) & posvalid(clickwatchpos) THEN (* click to watchcall popup *) click.markpos:=clickwatchpos; push(realzoom(initzoom, finezoom), FALSE); centerpos(click.markpos, mappos); click.marktime:=realtime; IF click.mhop[0]<>0C THEN setshowall END; ELSIF click.cmd="X" THEN xytomark; (* set marker 1 to map pos *) ELSIF click.cmd="x" THEN (* set marker 1 to object lastpos *) clicktomark; mainpop; ELSIF click.cmd=CMDSETMARK1LOCK THEN setmarklockpoi(FALSE); (* set marker 1 to poi pos *) ELSIF click.cmd="y" THEN (* set marker 2 to object lastpos *) IF (click.entries>0) & (click.table[click.selected].opf<>NIL) & posvalid(click.table[click.selected].opf^.lastpos) THEN click.measurepos:=click.table[click.selected].opf^.lastpos; ELSE click.measurepos:=click.clickpos END; ELSIF click.cmd="Y" THEN xytomark2; ELSIF click.cmd=CMDSETMARK2LOCK THEN setmarklockpoi(TRUE); (* set marker 2 to poi pos *) ELSIF click.cmd=CMDDELWAYPOINT THEN clickdelwaypoint; ELSIF click.cmd=CMDZOOMTOMARKS THEN zoomtomarks(click.markpos, click.measurepos); ELSIF click.cmd=CMDZOOMSQUARE THEN zoomtosquare; ELSIF click.cmd=":" THEN posinval(click.markpos); posinval(click.measurepos); click.waysum:=0.0; posinval(click.squerpos0); posinval(click.squerspos0); killallmenus; sayonoff("Markers", FALSE); ELSIF click.cmd="@" THEN AddConfLine(fCLICKMAP, 0, ""); AddConfLine(fCLICKSYM, 0, ""); AddConfLine(fCLICKTRACK, 0, ""); AddConfLine(fCLICKTEXT, 0, ""); AddConfLine(fCLICKWXSYM, 0, ""); killallmenus; say("'ON Next Click' Reset to Defaults", 10, "b"); ELSIF click.cmd="~" THEN changecolor(click.table[click.selected].opf); ELSIF click.cmd="A" THEN animate(click.mhop, lums.fps, ""); ELSIF click.cmd=CMDVIDEO THEN say("Saving "+VIDEOFN, 0, "b"); animate(click.mhop, lums.actfps, VIDEOFN); ELSIF click.cmd=CMDINTERNSTAT THEN internstat; ELSIF click.cmd=CMDFIND THEN click.dryrun:=FALSE; find(TRUE); ELSIF click.cmd=CONFPOISYMFIND THEN click.dryrun:=FALSE; find(FALSE); ELSIF click.cmd="\" THEN helptext(0, 0, 0, 0, "en-shortcuts"); ELSIF click.cmd="7" THEN Setmap(0); ELSIF click.cmd="8" THEN Setmap(1); ELSIF click.cmd="9" THEN Setmap(2); ELSIF click.cmd="6" THEN Setmap(MAX(INTEGER)); ELSIF click.cmd="Q" THEN quit:=TRUE; ELSIF click.cmd="e" THEN click.dryrun:=FALSE; ELSIF (click.cmd=CMDRDLOG) & (click.cmdatt<>0C) THEN importlog(click.cmdatt); click.cmdatt:=0C; ELSIF click.cmd=11C THEN toggview; ELSIF click.cmd="(" THEN mapbri(-5); ELSIF click.cmd=")" THEN mapbri(5); ELSIF click.cmd="[" THEN fullbritime(TRUE); ELSIF click.cmd="]" THEN fullbritime(FALSE); END; IF WITHX11 THEN makeimage(FALSE) END; click.cmd:=0C; IF beaconediting & beaconed & ismultiline(TRUE) THEN poligonmenu END; ELSIF (tracenew.call[0]<>0C) & (lastxupdate+slowupdate()<=realtime) & NOT (click.withradio & (posvalid(click.markpos) OR posvalid(click.measurepos))) THEN follow; IF WITHX11 & (maptrys>0) THEN IF click.watchlast THEN refrinfo END; makeimage(FALSE); END; ELSIF (tracenew.winevent>1000) OR ((tracenew.winevent>0) OR poisactiv()) & (lastxupdate+2+slowupdate()<=realtime) THEN tracenew.winevent:=0; IF click.watchlast THEN refrinfo END; IF NOT (click.withradio OR posvalid(click.markpos) & posvalid(click.measurepos)) THEN closesrtmfile END; IF WITHX11 THEN makeimage(FALSE) END; ELSIF newxsize>0 THEN (* window resize request *) IF ODD(newxsize) THEN DEC(newxsize) END; IF ODD(newysize) THEN DEC(newysize) END; allocxbuf(newxsize, newysize); allocimage(image, newxsize, newysize, FALSE); allocimage(rfimg, newxsize, newysize, FALSE); xsize:=newxsize; ysize:=newysize; IF NOT maximized THEN saveXYtocfg(fXYSIZE, xsize, ysize) END; newxsize:=0; newysize:=0; radio.wasradio:=FALSE; posinval(radio.mappos); makeimage(FALSE); ELSIF ((lasttcprx+60>realtime) OR (lastanyudprx+60>realtime)) & (laststatref+50) & (maptime<>realtime) THEN maptime:=realtime; DEC(maptrys); IF WITHX11 & IsMapLoaded() THEN makeimage(FALSE) ELSIF maptrys=20 THEN tooltips("m") END; END; IF (click.bubblstr[0]<>0C) & NOT pulling THEN textbubble(click.bubblpos, click.bubblstr, click.lastpoi); IF click.bubblinfo<>"" THEN textautosize(DOCKX, 0, POIINFOWINID, MINPOIINFOTIME+Length(click.bubblinfo) DIV POIINFOREADSPEED, "w", click.bubblinfo); ELSE killmenuid(POIINFOWINID) END; click.bubblstr[0]:=0C; click.bubblinfo[0]:=0C; END; IF refresh THEN redraw(image) END; IF NOT logdone THEN bootreadlog; INC(tracenew.winevent) END; IF NOT WITHX11 & shottrigg THEN shottrigg:=FALSE; makeimage(FALSE); screenshot; END; IF realday<>realtime DIV (3600*24) THEN realday:=realtime DIV (3600*24); void:=deletelogfile(FALSE); END; END MainEvent; PROCEDURE getinitview; VAR z:REAL; BEGIN initzoom:=8; finezoom:=1.0; z:=0.0; getview(fVIEW, 0, z, mappos); IF z<>0.0 THEN initzoom:=trunc(z); finezoom:=1.0+z-FLOAT(initzoom); END; limpos(mappos); IF parmzoom>0 THEN initzoom:=parmzoom; finezoom:=parmfinezoom; END; IF initzoom<1 THEN initzoom:=1 ELSIF initzoom>MAXZOOM THEN initzoom:=MAXZOOM END; END getinitview; PROCEDURE batch; (* get key comands from file *) VAR c:CHAR; j,ctl:BOOLEAN; BEGIN ctl:=FALSE; j:=FALSE; REPEAT LOOP IF batchp>=batchlen THEN RETURN END; c:=batchbuf[batchp]; INC(batchp); IF c="#" THEN j:=TRUE; ELSIF (c<" ") THEN j:=FALSE; ELSIF NOT j THEN EXIT END; END; IF NOT ctl & (c="^") THEN ctl:=TRUE; ELSE IF ctl THEN IF c>=CHR(96) THEN c:=CHR(ORD(c)-96); (* ^x for ctrl char *) ELSIF c>=CHR(64) THEN c:=CHR(ORD(c)-64) END; ctl:=FALSE; END; keychar(c, FALSE, FALSE); END; UNTIL NOT ctl; END batch; <* IF TARGET_FAMILY="UNIX" THEN *> PROCEDURE dobatch; VAR f:File; ret:INTEGER; BEGIN f:=OpenRead("batch.txt"); IF FdValid(f) THEN ret:=RdBin(f, batchbuf, SIZE(batchbuf)); IF ret>0 THEN batchlen:=ret; batchp:=0; END; Close(f); ELSE shottrigg:=TRUE END; END dobatch; PROCEDURE ["C"] killsave(signum:INTEGER); BEGIN IF NOT quit & configon(fAUTOSAVE) THEN saveconfig END; WrStr("exit "); WrInt(signum,0); WrStrLn("!"); HALT(signum) END killsave; PROCEDURE ["C"] makeshot(signum:INTEGER); BEGIN dobatch; END makeshot; <* END *> BEGIN FILL(ADR(debugmem), 0C, SIZE(debugmem)); clrconfig; initparms; posinval(click.markpos); mountains:=NIL; loadconfig(FALSE); loadfont; maximized:=FALSE; getstartxysize(xsize, ysize); IF initxsize>0 THEN xsize:=initxsize END; IF initysize>0 THEN ysize:=initysize END; mappos.long:=12.0*PI2/360.0; mappos.lat:=49.0*PI2/360.0; getinitview; mercator(mappos.long, mappos.lat, initzoom, inittilex, inittiley, shiftx, shifty); centerpos(mappos, mappos); makegammatab; vidbuf:=NIL; image:=NIL; rfimg:=NIL; allocimage(image, xsize, ysize, FALSE); allocimage(rfimg, xsize, ysize, FALSE); posinval(clickwatchpos); tabview.stkpo:=0; tabview.stktop:=0; alttabview.stkpo:=0; alttabview.stktop:=0; maptrys:=0; makeimagetime:=0; FILL(ADR(serialpid), 0C, SIZE(serialpid)); FILL(ADR(serialpid2), 0C, SIZE(serialpid2)); click.mhop[0]:=0C; click.onesymbol.tab:=0C; click.zoomtox:=-1; posinval(click.squerpos0); posinval(click.squerspos0); posinval(click.measurepos); FILL(ADR(tracenew), 0C, SIZE(tracenew)); pandone:=TRUE; newxsize:=0; newysize:=0; cycleorder:=0; realday:=0; onetipp:=FALSE; logdone:=FALSE; uptime:=time(); autoshottime:=0; withx:=InitX("Aprsmap", "Aprsmap", xsize, ysize)>=0; IF NOT withx THEN WrStrLn("cannot open xwindow, image generation only") END; Gammatab(lums.gamma); realtime:=time(); initmenus; quit:=FALSE; tracenew.winevent:=1; posinval(newpos0); posinval(newpos1); <* IF TARGET_FAMILY="UNIX" THEN *> signal(SIGTERM, killsave); signal(SIGINT, killsave); IF WITHX11 THEN signal(SIGPIPE, killsave); ELSE signal(SIGPIPE, makeshot); END; <* END *> IF withx THEN realtime:=time(); rxidle:=0; refresh:=TRUE; lastlooped:=realtime; WHILE NOT quit DO MainEvent; <* IF TARGET_FAMILY="UNIX" THEN *> IF (autoshots>0) & Watchclock(autoshottime, autoshots) THEN dobatch END; <* END *> IF batchp op1.next > op2.next > NIL op.frames > frame1.next > frame2.next > NIL frame1 > vardat1.lastref > frame5 frame2 > vardat2.lastref > frame4 frame3 > vardat1.lastref > frame5 frame4 > vardat2.lastref > frame4 frame5 > vardat1.lastref > frame5 *) END aprsmap.