⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lowr.c

📁 这是经典的卫星编程应用程序
💻 C
📖 第 1 页 / 共 4 页
字号:
#include "g7to.h"
#define PROCX

long	BaseLatitude;
long	BaseLongitude;
long	TailAdrPointer;
long	HeadAdrPointer;
INT		timeoutp;
INT		validwp;

INT LwrRangeLo=1;			// If retrieving a range of waypoints from a LEI unit this
							//  is the start waypoint #
INT LwrRangeHi=-1;			// If retrieving a range of waypoints from a LEI unit this
							//  is the finish waypoint #
extern	unsigned char bmh[118]; // = {
//     66,  77, 182,  31,   0,   0,   0,   0,   0,   0, 118,   0,   0,
//      0,  40,   0,   0,   0, 160,   0,   0,   0, 100,   0,   0,   0,
//      1,   0,   4,   0,   0,   0,   0,   0,  64,  31,   0,   0,   0,
//      0,   0,   0,   0,   0,   0,   0,  16,   0,   0,   0,  16,   0,
//      0,   0,   0,   0,   0,   0,  99,  99,  99,   0, 181, 181, 181,
//      0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0,
//    255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255,
//    255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255,
//    255,   0, 255, 255, 255,   0, 255, 255, 255,   0, 255, 255, 255,   0
//}; // bmh[118]

void 	readstarttofinish(long Start, long Finish, char * what, void (*fcn)(INT));
void	debugOUTstd(BYTE *message, INT len,INT width);
INT		totalread=0;
INT		Total;
long	rstfOffset=0;
INT		AbortNow=0;
INT		TotalDeltas=0;
INT		NumberOfIcons=0;
INT		NumOfGraphSymbols=0;
typedef unsigned char BYTE;
#if __BORLANDC__
extern	INT WinNT;
#endif
BYTE	LowrLogin;
INT	LastCommand=0;
INT	LowrValidWpts=0;
INT LowrMemBytesRead=0;
long LowrLastLat, LowrLastLong;

struct LowrID  {
	BYTE Reserved;
	INT ProductID;
	INT ProtocolVersion;
	INT ScreenType;
	INT ScreenWidth;
	INT ScreenHeight;
	INT NumOfWaypoints;
	INT NumOfIcons;
	INT NumOfRoutes;
	INT NumOfWaypointsPerRoute;
	BYTE NumOfPlotTrails;
	BYTE NumOfIconSym;
	BYTE ScreenRotateAngle;
	long RunTime;
} LowrID;

struct LowrWPTr {
	BYTE Reserved;
	short WaypointNumber;
	BYTE Status;
	BYTE IconSymbol;
	long Latitude;  // LONG (Mercator Meter)
	long Longitude; // LONG (Mercator Meter)
	BYTE Name[13];
	long Date;		// seconds since 00:00 January 1, 1992
} LowrWPTr;

union Hdr {
	BYTE Header[8];
	struct hdrs {
		INT preamble;
		INT command;
		INT length;
		BYTE  reserved;
		BYTE  checksum;
	} hdrs;
} Hdr;

struct LowrTrailOrigin {
	BYTE Reserved;
	BYTE PlotTrailNumber;
	long OriginY;
	long OriginX;
	short NumberOfDeltas;
} LowrTrailOrigin;

struct ND {
	BYTE pt;
	short no;
} ND;

struct LowrTrailOriginMem {
	BYTE Reserved;
	BYTE PlotTrailNumber;
	long StructurePointer;
	short StructureSize;
} LowrTrailOriginMem;

struct LowrMemGet {
	long Address;
	short Count;
	BYTE CtgSelect;
} LowrMemGet;

struct LowrMemRead {
	BYTE reserved;
	union data {
		struct ptp {				// for reading Plot trail structure
			long BaseLatitude;
			long BaseLongitude;
			long TailAdrPointer;
			long HeadAdrPointer;
		} ptp;
		short data[80];				// for reading 80 shorts
		BYTE  bytes[160];			// for reading 360 bytes
		unsigned long lbytes[40];   // for reading longs
	} data;
} LowrMemRead;
	
#define MAX_Lowr_LENGTH 256

//
// Lowrance Serial Port Commands
//
enum {
	ReadMem				=0x0008,  // Read from a memory location
	WriteMem			=0x0009,  // Write to a memory location
	Login				=0x000D,  // Wake up external serial port
	BaudChange			=0x010A,  // Change NMEA Baud Rate
	GetScreenPointer	=0x0301,  // Request Screen Pointer to download the current Screen
	UnfreezeScreen		=0x0302,  // unfreeze the current screen (happens after downloading screen)
	GetWaypoint			=0x0303,  // Get a Waypoint
	SendWaypoint		=0x0304,  // Send a Waypoint
	GetRoute			=0x0305,  // Get a Route
	SendRoute			=0x0306,  // Send a Route
	GetPlotTrail		=0x0307,  // Get plot trail Pointer
	GetNumIcons			=0x0308,  // Get number of icons
	GetIconSymbol		=0x0309,  // Get icon symbol
	SetNumIcons			=0x030A,  // Set number of icons
	SendIcon			=0x030B,  // Send icon
	GetNumGraphSymbols	=0x030C,  // Get number of Graphical symbols
	GetIconGraphSymbol	=0x030D,  // Get Icon Graphical symbol
	GetProductInfo		=0x030E,  // Get product information
	GetPlotTrailOrigin	=0x0312,  // Get Plot Trail Origin (Protocol version 2.0)
	GetPlotTrailDeltas	=0x0313,  // Get Plot Trail Deltas (Protocol version 2.0)
	SetPlotTrailOrigin	=0x0314,  // Set Plot Trail Origin (Protocol version 2.0)
	SetPlotTrailDeltas	=0x0315,  // Set Plot Trail Deltas (Protocol version 2.0)
};


// Constants needed 

#define RADtoDEG  57.295779513082322
#define EarthRad  6356752.3142 
#define DEGtoRAD  0.017453292519943296

#define PI        3.14159265358979323846
#define PIdiv2    1.57079632679489661923
#define EarthRadxRADtoDEG 364215079.013679028

/* -------------------------------------------------------------------------- */
PROCX BYTE sethigh(BYTE b, BYTE val)
{
	val&=0xf;
	b&=0x0f;
	b|=(val<<4);
	return b;
} // sethigh
/* -------------------------------------------------------------------------- */
PROCX BYTE setlo(BYTE b, BYTE val)
{
	val&=0xf;
	b&=0xf0;
	b|=val;
	return b;
} // setlo

/* -------------------------------------------------------------------------- */
PROCX long swaplongendian(long in)
{
	union a {
		long b;
		BYTE c[4];
	} a;
	BYTE temp;

	a.b = in;
	temp=a.c[0];
	a.c[0]=a.c[3];
	a.c[3]=temp;

	temp=a.c[2];
	a.c[2]=a.c[1];
	a.c[1]=temp;

	return a.b;
} // long swaplongendian(long a)

/* -------------------------------------------------------------------------- */
//
// Search the currend pushed waypoints for a name, latitude and longitud
//  match.  Returns the number of the waypoint in the list.  This number is
//  a number 1-waypoints
//
PROCX INT MatchRoute(char * namein, double la, double lo)
{
	int i;
	double lat,lon;
	char name[20];
	char *p;
	char *b;
	for(i=1;i<=waypoints;i++) {
		b=strdup(waypoint_push[i]);
		p=strtok3(b,";");				// Skip waypoint type
		p=strtok3(NULL,";");			// Skip datatype
		p=strtok3(NULL,";");			// Get name
		strcpy(name,p);
		p=strtok3(NULL,"!");
//
// skipping lat/long compare because at this point duplicate waypoint names
//   are removed.
//		lat=atof(strtok3(NULL,";"));	// Get Latitude
//		lon=atof(strtok3(NULL,";"));	// Get Longitude
		lat=la;
		lon=lo;
		free(b);
		if((strncmp(name,namein,15) == 0) && la==lat && lo==lon) {
			return i;
		}
	} // for
	return -1;
} // MatchRoute

struct DispParms {
	BYTE Reserved;
	short PixelX;
	short PixelY;
	long BlackAddress;
	short BlackCount;
	long GreyAddress;
	short GreyCount;
} DispParms;

BYTE *black,*grey;
/* -------------------------------------------------------------------------- */
//
// concatonates bytes to the black array
//
PROCX void DoScreenBlack(INT cnt)
{
	static INT ptr=0;

	memcpy(&black[ptr],&SerialMessage[1],cnt); // skip login id byte
	ptr+=cnt;
} // DoScreenBlack

/* -------------------------------------------------------------------------- */
//
// concatonates bytes to the grey array
//
PROCX void DoScreenGrey(INT cnt)
{
	static INT ptr=0;

	memcpy(&grey[ptr],&SerialMessage[1],cnt); // skip login id byte
	ptr+=cnt;
} // DoScreenGrey

BYTE *nib;
BYTE *nib2;
INT	vertical,horizontalblack;
INT	nibsize,siz,rowlen,linebytes;

/* -------------------------------------------------------------------------- */
PROCX void rotatedisp(void)
{
	BYTE *raw;
	INT i,j,k,rl,lb;

// printf("nibsize: %d, siz: %d, rowlen: %d, vertical: %d, horizontal: %d, linebytes: %d\n",
// 			nibsize, siz, rowlen,vertical,horizontalblack,linebytes);
//
// nib2 contains the data in slices of vertical size, but the length of each
//   slice is rowlen bytes;
//
//	rowlen:			The actual number of bytes involved in the bitmap row (vertical)
//	vertical:		The actual number of pixels in the vertical row
//	horizontalblack:The actual number of pixels in a horizontal row
//  linebytes:		The actual number of bytes that contain data in the vertical row
//
//  For the EEII:
//
//	rowlen: 52, vertical: 100, horizontal: 65, linebytes: 50
//
// for the GM100:
//
//  siz: 8320, rowlen: 80, vertical: 160, horizontal: 104, linebytes: 80
//
// First we must move the 2 pixels per byte into a 1 pixel per byte array
//
	if((raw=(BYTE*)calloc(nibsize*2+1000,1)) == NULL) {
		oomem("rotatedisp1");
		byebye(0);
	}
	j=k=0;
	for(i=0;i<(nibsize);i++) {  // was rowlen*horizontalblack
		if(++j<=linebytes) {
			raw[k++] = (nib[i]>>4)&0x0f;
			if((j==linebytes) && (vertical&1)) continue;
			raw[k++] = nib[i]&0x0f;
			if(j==rowlen) j=0;  // just in case rowlen=linebytes, i.e. no padding to skip
		}
		else {
			if(j>=rowlen) j=0; // skip padding
		}
	}
//
// code checked good to here
//
	lb=(horizontalblack/2)+(horizontalblack&1);
	rl=(lb+3)&~3;
	siz=vertical*rl;
//
// for the EEII
//
// rowlen: 36, vertical: 100, horizontal: 65, linebytes: 33
//
// for the GM100:
//
// siz: 8320, rowlen: 52, vertical: 160, horizontal: 104, linebytes: 52
//
// stuff the raw array into lines of horizontal black with 2 bits per pixel
//
	k=0;
	for(i=0;i<vertical;i++) {
		for(j=0;j<horizontalblack;j+=2) {
			nib2[k]=0;
			nib2[k]=sethigh(nib2[k],raw[vertical*j+i]);		
			if((horizontalblack&1) && (j==(horizontalblack-1))) {
				k++;
				continue;
			}
			nib2[k]=setlo(nib2[k],raw[vertical*(j+1)+i]);
			k++;
		}
		for(j=0;j<(rl-lb);j++) {
			nib2[k]=0xff;
			k++;
		}
	}
  	bmh[18]=horizontalblack;
  	bmh[22]=vertical;
} // rotatedisp

/* -------------------------------------------------------------------------- */
PROCX void DoScreenPointer(void)
{
//	INT horizontal;
	long tlong,greyadr,blackadr;
	INT i,j,k;

	if(open_output("wb")==0) return;
	memcpy(&DispParms,SerialMessage,sizeof(struct DispParms));
	blackadr=(DispParms.BlackAddress);
	greyadr=(DispParms.GreyAddress);
	vertical=LowrID.ScreenHeight;
	if(LowrID.ScreenType<2) vertical++;
	horizontalblack=(DispParms.BlackCount*8)/(DispParms.PixelX);
//	horizontal     =(DispParms.GreyCount/vertical)*8;
// printf("PixelX       : %d\n",DispParms.PixelX);
// printf("PixelY       : %d\n",DispParms.PixelY);
// printf("BlackAddress : 0x%08lx\n",blackadr);
// printf("BlackCount   : %d\n",DispParms.BlackCount);
// printf("GreyAddress  : 0x%08lx\n",greyadr);
// printf("GreyCount    : %d\n",DispParms.GreyCount);
// printf("vertical: %d, Horizontal: %d\n",vertical,horizontalblack);
// fflush(stdout);
//
// Get Planes
//
	rstfOffset=0;
	if((black=(BYTE*)calloc(DispParms.BlackCount+100,1)) == NULL) {
		oomem("DoScreenPointer1");
		byebye(0);
	}
	totalread=0;
	readstarttofinish(blackadr, blackadr+DispParms.BlackCount-1, "black plane", DoScreenBlack);

	if(LowrID.ScreenType>0 && DispParms.GreyCount>0) {
		if((grey=(BYTE*)calloc(DispParms.GreyCount+100,1)) == NULL) {
			oomem("DoScreenPointer2");
			byebye(0);
		}
		totalread=0;
		readstarttofinish(greyadr, greyadr+DispParms.GreyCount-1, "grey plane",DoScreenGrey);
	}

	rowlen= (((vertical/2) + (vertical&1) + 3)&~3);  // must end on a long boundary
	linebytes=(vertical/2)+(vertical&1);			 // if vertical is odd must add 1

	if(LowrID.ScreenType<2) siz=horizontalblack*vertical;
	else siz=horizontalblack*vertical/2;
	if((nib=(BYTE*)calloc(siz+1000,1))==NULL)
		oomem("Allocating nibble buffer1");
	if((nib2=(BYTE*)calloc(siz+1000,1))==NULL)
		oomem("Allocating nibble buffer2");
	k=0;
//
// Combine planes into 'nibble' buffer
//
//  The code here takes the screen memory and converts it from 8 pixels
//   per byte to 2 pixels per byte.  By using the BlackCount we include
//   the screen padding bytes.
//
	for(i=0;i<DispParms.BlackCount;i++) {
		for(j=6;j>=0;j-=2) {

			if(DispParms.GreyCount>0)
				if((grey[i]>>j)&1) nib[k]=setlo(nib[k],(BYTE)0x2);
			if((black[i]>>j)&1) nib[k]=setlo(nib[k],(BYTE)3);

			if((nib[k]&0x3) == 3) nib[k]=0;						// invert the black
			else if((nib[k]&0xf) == 0) nib[k]=3;

			if(DispParms.GreyCount>0)
				if((grey[i]>>(j+1))&1) nib[k]=sethigh(nib[k],(BYTE)2);
			if((black[i]>>(j+1))&1) nib[k]=sethigh(nib[k],(BYTE)3);

			if((nib[k]&0x30) == 0x30) nib[k]=sethigh(nib[k],0);// invert the black
			else if((nib[k]&0xf0) == 0) nib[k]=sethigh(nib[k],3);

			k++;
		}
	}
	nibsize=k; 										// bytes in nib

	free(black);
	if(DispParms.GreyCount>0) free(grey);

	k=j=0;
//
// process expanding nibble buffer into proper format
//
//  In the following the scan 'row' is actually one vertical line in the
//   display.
//
//  In a .bmp of 16 colors the pixels each take up a nibble, i.e.
//   two pixels per byte.  Each row must end on a 4 byte boundary
//   if not, 0 nibbles are added until a 4 byte boundary is reached
//
//   The 4 byte boundary of x bytes can be calculated by (x+3)&~3
//
//  In the input buffer, the GPS screen memory scan row is '0 padded'
//   until it's length is equal to DispParms.PixelX.  For example,
//   in the EEII the DispParms.PixelX value is 112, but the screen scan row is
//   only 100 pixels 'wide'.  That means that 12 pixels of padding is added.  This
//   equates to 3 nibbles (8 pixels per byte in screen memory) of padding.
//
//  In the code below the 'if(j<=rowlen)' takes care of
//   adding the padding for the .bmp file.  linebytes-rowlen gives the bytes of
//   padding to add.
//
//   If the last byte is only one nibble, the lower nibble  is already
//   set to 0 by the conversion from the screen format and doesn't need to be
//   counted and the remainder is sufficient.
//
//  The 'if(j>=DispParms.PixelX/2)' line takes care of the GPS screen 
//   padding bytes by skipping them if they exist.  Not all units send padding bytes.
//

// printf("DispParms.BlackCount*4: %d\n",DispParms.BlackCount*4);
// printf("horizontal: %d, vertical: %d, vertical/2: %d\n",horizontalblack,vertical,vertical/2);
// printf("siz: %d\n",siz);
// 
	for(i=0;i<DispParms.BlackCount*4;i++) { // blackcount * 8 / 2 is the size of the source bfr
		if(++j<=linebytes)					// actual data
			nib2[k++]=nib[i];
		else {
			if(j<=rowlen)  nib2[k++]=0;
		}
		if(j>=DispParms.PixelX/2) j=0;
	}
	memcpy(nib,nib2,siz);
//
// mirror display horizontally on output
//
// work a row at a time starting with the last row in the array
//  and working toward the front
//
	j=0;
	k=siz/horizontalblack;
	for(i=siz-k;i>=0;i-=k) {
		memcpy(&nib2[j],&nib[i],k);
		j+=k;
	}
  	bmh[18]=vertical;
  	bmh[22]=horizontalblack;
	if(LowrID.ScreenRotateAngle==90) rotatedisp();
//
// set size of data
//
	tlong=siz;
	memcpy(&bmh[34],&tlong,4);
//
// set size of file
//
	tlong+=118;
	memcpy(&bmh[2],&tlong,4);
//
// write a standard 118 byte header for AxBx16 windows bitmaps
//
   	fwrite(bmh,118,1,out);
	fwrite(nib2,siz,1,out);
//
// close out and free memory
//
    fclose(out);
	free(nib2);
	free(nib);
} // DoScreenPointer

//struct LowrMemGet {
//	long Address;
//	short Count;
//	BYTE CtgSelect;
//} LowrMemGet;

/* -------------------------------------------------------------------------- */
PROCX void GetLowrDisplay(void)
{
	BYTE *temp;

	temp=NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -