' gets a screendump from a Garmin GPS-Receiver ' e.g. the Garmin Etrex (c) Markus Hoffmann 2005 ' ' devicename$="/dev/ttyS1" outputfilename$="screen.xpm" clr interactive,showit @loadsettings(env$("HOME")+"/.garminrc") WHILE LEN(param$(i)) IF LEFT$(param$(i))="-" IF param$(i)="--help" OR param$(i)="-h" @intro @using ELSE IF param$(i)="--version" @intro QUIT ELSE IF param$(i)="--interactive" interactive=TRUE ELSE IF param$(i)="--show" OR param$(i)="-s" showit=TRUE ELSE IF param$(i)="-o" INC i IF LEN(param$(i)) outputfilename$=param$(i) ENDIF else collect$=collect$+param$(i)+" " ENDIF ELSE ' devicename$=param$(i) ' IF NOT EXIST(devicename$) ' PRINT "gps-screen: "+devicename$+": file or path not found" ' quit ' ENDIF ENDIF INC i WEND print "Open device ",devicename$ OPEN "UX:9600,N,8,1",#1,devicename$,0 @init_device fertig=0 @getscreen totzeit=timer do pause 0.001 IF TIMER-totzeit>5 @sendmessage(10,mki$(5)) totzeit=TIMER fertig=1 ENDIF IF inp?(#1) @status(2,"READ") WHILE inp?(#1) AND LEN(INKEY$)=0 @procmessage(@getmessage$()) WEND @status(2,"OK") totzeit=TIMER ENDIF exit if fertig=1 loop @ende procedure getscreen clr anzscanlines @sendmessage(10,MKI$(32)) return procedure init_device ' Garmin identifizieren @sendmessage(254," ") @procmessage(@getmessage$()) return PROCEDURE ende ' Quit the program, close all open files remove all installations CLOSE quit RETURN FUNCTION getmessage$() local s$,flag,flag2,chk,chk2 t=TIMER clr s$,flag,flag2 DO IF inp?(#1) t$=chr$(inp(#1)) ' PRINT "Got:";ASC(t$) IF t$=CHR$(16) IF flag2=0 flag2=1 ELSE IF flag=0 flag=1 ELSE s$=s$+t$ flag=0 ENDIF ENDIF ELSE IF flag2=0 PRINT "protokollfehler: muell ";ASC(t$) ELSE IF flag=1 AND t$=CHR$(3) GOTO t ELSE IF flag=1 PRINT "Protokoll-ERROR 16" flag=0 ENDIF s$=s$+t$ ENDIF ENDIF else pause 0.01 endif IF TIMER-t>2 @status(1,"TIMEOUT") s$="TIMEOUT 0 ?" beep fertig=1 GOTO t ENDIF LOOP t: pid=ASC(MID$(s$,1,1)) chk=ASC(MID$(s$,LEN(s$),1)) and 255 chk2=0 FOR i=1 TO LEN(s$)-1 chk2=chk2-ASC(MID$(s$,i,1)) NEXT i chk2=chk2 AND 255 IF chk=chk2 AND pid<>6 AND pid<>21 @sendACK(pid) ELSE IF chk<>chk2 @status(1,"Uebertragungsfehler CHK") ENDIF return s$ ENDFUNCTION PROCEDURE procmessage(t$) local pid,plen pid=ASC(LEFT$(t$,1)) plen=ASC(MID$(t$,2,1)) IF pid=6 ' ACK, alles OK, ignorieren @status(1,"OK") ELSE IF pid=69 @procscanline(t$) ELSE IF pid=21 @status(1,"NAK !") ELSE IF pid=-2 OR pid=10 PRINT "Paket nicht erlaubt ! Pid="; pid ELSE IF pid=-1 @procproductdata(t$) ELSE @status(2,"? Paket pid="+STR$(pid)+" !") print "? Paket pid="+STR$(pid)+" ! LEN=";plen t$=mid$(t$,3,plen) for i=0 to len(t$)-1 print hex$(asc(mid$(t$,i+1,1)) and 255,2,2,1)' next i print ENDIF RETURN PROCEDURE procproductdata(ut$) garminPID=CVI(MID$(ut$,3,2)) garminVER=CVI(MID$(ut$,5,2)) garminMES$=MID$(t$,7,LEN(ut$)-7-1) garminmes$=replace$(garminmes$,chr$(0)," ") print "Connected: " print "PID=",garminPID print "VER=",garminVER print "MES=",garminMES$ RETURN PROCEDURE procscanline(t$) local plen,bmflag,offset plen=ASC(MID$(t$,2,1)) t$=MID$(t$,3,plen) bmflag=lpeek(varptr(t$)+0) ' print "BMFLAG=";bmflag ' print "PLEN=";plen if bmflag=0 screenplanes=lpeek(varptr(t$)+12) sht=lpeek(varptr(t$)+20) screenwidth=lpeek(varptr(t$)+16) screenbytes=screenplanes*screenwidth/8*sht ' print hex$(cvl(mid$(t$,5,4)))'cvl(mid$(t$,9,4))' ' print cvl(mid$(t$,13,4)),cvl(mid$(t$,17,4)),cvl(mid$(t$,21,4))' ' print hex$(cvl(mid$(t$,25,4))),cvl(mid$(t$,29,4)),cvl(mid$(t$,33,4))' ' print cvl(mid$(t$,37,4)) print "Planes: ";screenplanes print "Dimension: "+str$(screenwidth)+"x"+str$(sht) print "Bytes: ";screenplanes*screenwidth/8*sht escreenbuf$=space$(screenplanes*screenwidth/8*sht) else offset=cvl(mid$(t$,5,4)) @progress(sht,anzscanline) ' print "OFFSET=";offset bmove varptr(t$)+8,varptr(escreenbuf$)+offset,screenwidth/8*screenplanes inc anzscanline ' print anzscanline if anzscanline=sht ' bsave "escreen",varptr(escreenbuf$),len(escreenbuf$) print if showit @show_screenshot endif if interactive @saveescreen else @savexpm(outputfilename$) endif fertig=1 endif endif RETURN procedure show_screenshot local x,y,b,a sx=0 sy=0 sw=640 sh=400 clearw grau=get_color(65530/2,65530/2,65530/2) hellgrau=get_color(65530/1.5,65530/1.5,65530/1.5) hell=get_color(65530/1.1,65530/1.1,65530/1.1) weiss=get_color(65530,65530,65530) schwarz=get_color(0,0,0) rot=get_color(65530,0,0) if sht>0 and screenplanes>0 and screenwidth>0 defmouse 2 for x=screenwidth-1 downto 0 for y=0 to sht-1 a=asc(mid$(escreenbuf$,1+x/8*screenplanes+y*screenwidth*screenplanes/8,1)) and 255 b=x mod 4 if btst(a,b*2) and btst(a,b*2+1) color schwarz else if btst(a,b*2)=0 and btst(a,b*2+1) color grau else if btst(a,b*2) and btst(a,b*2+1)=0 color hellgrau else color weiss endif plot sx+sw-sht+y,sy+sh-x next y vsync next x get sx+sw-sht,sy+sh-screenwidth,sht,screenwidth,escreen$ vsync defmouse 0 endif return procedure saveescreen fileselect "save screendump ...","./*.xpm","screen.xpm",f$ if len(f$) if exist(f$) if form_alert(2,"[1][Datei existiert schon !|Ersetzen ?][Ja|ABBRUCH]")=1 defmouse 2 vsync @savexpm(f$) defmouse 0 endif else defmouse 2 vsync @savexpm(f$) defmouse 0 endif endif vsync return procedure savexwd(f$) bsave f$,varptr(escreen$),len(escreen$) return procedure savexpm(f$) print "Save screen as: "+f$ open "O",#4,f$ print #4,"/* XPM */" print #4,"static char *magick[] = {" print #4,"/* columns rows colors chars-per-pixel */" print #4,chr$(34)+str$(sht)+" "+str$(screenwidth)+" 4 1"+chr$(34)+"," print #4,chr$(34)+" c #ffffff"+chr$(34)+"," print #4,chr$(34)+"- c #aaaaaa"+chr$(34)+"," print #4,chr$(34)+"* c #555555"+chr$(34)+"," print #4,chr$(34)+"# c #000000"+chr$(34)+"," print #4,"/* pixels erzeugt von GPS-Earth "+version$+" (garmin.bas) */" for x=screenwidth-1 downto 0 print #4,chr$(34); for y=0 to sht-1 a=asc(mid$(escreenbuf$,1+x/8*screenplanes+y*screenwidth*screenplanes/8,1)) and 255 b=x mod 4 if btst(a,b*2) and btst(a,b*2+1) print #4,"#"; else if btst(a,b*2)=0 and btst(a,b*2+1) print #4,"*"; else if btst(a,b*2) and btst(a,b*2+1)=0 print #4,"-"; else print #4," "; endif next x print #4,chr$(34)+"," next y print #4,"};" close #4 return procedure sendACK(pid) @sendmessage(6,CHR$(pid)) return procedure sendmessage(id,m$) local i,a,chk,s$ chk=0-id-LEN(m$) s$=CHR$(16)+CHR$(id)+CHR$(LEN(m$)) IF LEN(m$)=16 s$=s$+CHR$(16) ENDIF IF LEN(m$) FOR i=1 TO LEN(m$) a=ASC(MID$(m$,i,1)) and 255 s$=s$+CHR$(a) IF a=16 s$=s$+CHR$(16) ENDIF chk=chk-a NEXT i ENDIF chk=chk AND 255 s$=s$+CHR$(chk) IF chk=16 s$=s$+CHR$(16) ENDIF s$=s$+chr$(16)+chr$(3) BPUT #1,varptr(s$),len(s$) flush #1 return procedure sendnack @sendmessage(21,"") return procedure status(n,ssst$) print "STATUS=";n;" ";ssst$ return PROCEDURE intro PRINT "gps-screen.bas V.1.11 (c) Markus Hoffmann 2004-2005" print "grabs a screenshot from a GARMIN GPS device and saves it" print "as portable pixmap (*xpm)" print VERSION RETURN PROCEDURE using PRINT "Usage: gps-screen [options] [device]" PRINT "Options:" PRINT " -h, --help Display this information" PRINT " --interactive interactively save screen" PRINT " -s show screen" PRINT " --show show screen" PRINT " -o Place the output into (Default: screen.xpm)" RETURN ' Get the devicename from GPS-Earth-conf file procedure loadsettings(f$) local t$,a$,b$ if exist(f$) open "I",#9,f$ while not eof(#9) lineinput #9,t$ t$=trim$(t$) if left$(t$)<>"#" wort_sep t$,"=",1,a$,b$ if upper$(a$)="DEVICE" devicename$=b$ endif endif wend close #9 endif return procedure progress(a,b) local t$ print chr$(13);"[";string$(b/a*32,"-");">";string$((1.03-b/a)*32,"-");"| ";str$(int(b/a*100),3,3);"% ]"; flush return