Esempio n. 1
0
int AMXEXPORT AMXAPI amx_ProcessCleanup(AMX *amx)
{
  #if defined HAVE_DYNCALL_H || defined WIN32_FFI
    freelib(&ModRoot, amx, NULL);
  #endif
  closepipe();
  return AMX_ERR_NONE;
}
Esempio n. 2
0
/*------------------------------------------------------------------*/
void	putsUTM(lib *ll)
		{
		char	r[64];
		lib *l=makelib();
		copylib(ll,l);
		Lla2Utm(l,l,NULL);
		sprintf(r,"%.0lf %.0lf %.0lf",l->xc->x,l->xc->y,l->xc->z);
		if(ll->xc->y < 0)
			puts_pc("S");
		puts_pc(r);
		freelib(l);
		}
Esempio n. 3
0
/* libcall(const libname[], const funcname[], const typestring[], ...)
 *
 * Loads the DLL or shared library if not yet loaded (the name comparison is
 * case sensitive).
 *
 * typestring format:
 *    Whitespace is permitted between the types, but not inside the type
 *    specification. The string "ii[4]&u16s" is equivalent to "i i[4] &u16 s",
 *    but the latter is easier on the eye.
 *
 * types:
 *    i = signed integer, 16-bit in Windows 3.x, else 32-bit in Win32 and Linux
 *    u = unsigned integer, 16-bit in Windows 3.x, else 32-bit in Win32 and Linux
 *    f = IEEE floating point, 32-bit
 *    p = packed string
 *    s = unpacked string
 *    The difference between packed and unpacked strings is only relevant when
 *    the parameter is passed by reference (see below).
 *
 * pass-by-value and pass-by-reference:
 *    By default, parameters are passed by value. To pass a parameter by
 *    reference, prefix the type letter with an "&":
 *    &i = signed integer passed by reference
 *    i = signed integer passed by value
 *    Same for '&u' versus 'u' and '&f' versus 'f'.
 *
 *    Arrays are passed by "copy & copy-back". That is, libcall() allocates a
 *    block of dynamic memory to copy the array into. On return from the foreign
 *    function, libcall() copies the array back to the abstract machine. The
 *    net effect is similar to pass by reference, but the foreign function does
 *    not work in the AMX stack directly. During the copy and the copy-back
 *    operations, libcall() may also transform the array elements, for example
 *    between 16-bit and 32-bit elements. This is done because Pawn only
 *    supports a single cell size, which may not fit the required integer size
 *    of the foreign function.
 *
 *    See "element ranges" for the syntax of passing an array.
 *
 *    Strings may either be passed by copy, or by "copy & copy-back". When the
 *    string is an output parameter (for the foreign function), the size of the
 *    array that will hold the return string must be indicated between square
 *    brackets behind the type letter (see "element ranges"). When the string
 *    is "input only", this is not needed --libcall() will determine the length
 *    of the input string itself.
 *
 *    The tokens 'p' and 's' are equivalent, but 'p[10]' and 's[10]' are not
 *    equivalent: the latter syntaxes determine whether the output from the
 *    foreign function will be stored as a packed or an unpacked string.
 *
 * element sizes:
 *    Add an integer behind the type letter; for example, 'i16' refers to a
 *    16-bit signed integer. Note that the value behind the type letter must
 *    be either 8, 16 or 32.
 *
 *    You should only use element size specifiers on the 'i' and 'u' types. That
 *    is, do not use these specifiers on 'f', 's' and 'p'.
 *
 * element ranges:
 *    For passing arrays, the size of the array may be given behind the type
 *    letter and optional element size. The token 'u[4]' indicates an array of
 *    four unsigned integers, which are typically 32-bit. The token 'i16[8]'
 *    is an array of 8 signed 16-bit integers. Arrays are always passed by
 *    "copy & copy-back"
 *
 * When compiled as Unicode, this library converts all strings to Unicode
 * strings.
 *
 * The calling convention for the foreign functions is assumed:
 * -  "__stdcall" for Win32,
 * -  "far pascal" for Win16
 * -  and the GCC default for Unix/Linux (_cdecl)
 *
 * C++ name mangling of the called function is not handled (there is no standard
 * convention for name mangling, so there is no portable way to convert C++
 * function names to mangled names). Win32 name mangling (used by default by
 * Microsoft compilers on functions declared as __stdcall) is also not handled.
 *
 * Returns the value of the called function.
 */
static cell AMX_NATIVE_CALL n_libcall(AMX *amx, const cell *params)
{
  const TCHAR *libname, *funcname, *typestring;
  MODLIST *item;
  int paramidx, typeidx, idx;
  PARAM ps[MAXPARAMS];
  cell *cptr,result;
  LIBFUNC LibFunc;

  amx_StrParam(amx, params[1], libname);
  item = findlib(&ModRoot, amx, libname);
  if (item == NULL)
    item = addlib(&ModRoot, amx, libname);
  if (item == NULL) {
    amx_RaiseError(amx, AMX_ERR_NATIVE);
    return 0;
  } /* if */

  /* library is loaded, get the function */
  amx_StrParam(amx, params[2], funcname);
  LibFunc=(LIBFUNC)SearchProcAddress(item->inst, funcname);
  if (LibFunc==NULL) {
    amx_RaiseError(amx, AMX_ERR_NATIVE);
    return 0;
  } /* if */

  #if defined HAVE_DYNCALL_H
    /* (re-)initialize the dyncall library */
    if (dcVM==NULL) {
      dcVM=dcNewCallVM(4096);
      dcMode(dcVM,DC_CALL_C_X86_WIN32_STD);
    } /* if */
    dcReset(dcVM);
  #endif

  /* decode the parameters */
  paramidx=typeidx=0;
  amx_StrParam(amx, params[3], typestring);
  while (paramidx < MAXPARAMS && typestring[typeidx]!=__T('\0')) {
    /* skip white space */
    while (typestring[typeidx]!=__T('\0') && typestring[typeidx]<=__T(' '))
      typeidx++;
    if (typestring[typeidx]==__T('\0'))
      break;
    /* save "pass-by-reference" token */
    ps[paramidx].type=0;
    if (typestring[typeidx]==__T('&')) {
      ps[paramidx].type=BYREF;
      typeidx++;
    } /* if */
    /* store type character */
    ps[paramidx].type |= (unsigned char)typestring[typeidx];
    typeidx++;
    /* set default size, then check for an explicit size */
    #if defined __WIN32__ || defined _WIN32 || defined WIN32
      ps[paramidx].size=32;
    #elif defined _Windows
      ps[paramidx].size=16;
    #endif
    if (_istdigit(typestring[typeidx])) {
      ps[paramidx].size=(unsigned char)_tcstol(&typestring[typeidx],NULL,10);
      while (_istdigit(typestring[typeidx]))
        typeidx++;
    } /* if */
    /* set default range, then check for an explicit range */
    ps[paramidx].range=1;
    if (typestring[typeidx]=='[') {
      ps[paramidx].range=_tcstol(&typestring[typeidx+1],NULL,10);
      while (typestring[typeidx]!=']' && typestring[typeidx]!='\0')
        typeidx++;
      ps[paramidx].type |= BYREF; /* arrays are always passed by reference */
      typeidx++;                  /* skip closing ']' too */
    } /* if */
    /* get pointer to parameter */
    cptr=amx_Address(amx,params[paramidx+4]);
    switch (ps[paramidx].type) {
    case 'i': /* signed integer */
    case 'u': /* unsigned integer */
    case 'f': /* floating point */
      assert(ps[paramidx].range==1);
      ps[paramidx].v.val=(int)*cptr;
      break;
    case 'i' | BYREF:
    case 'u' | BYREF:
    case 'f' | BYREF:
      ps[paramidx].v.ptr=cptr;
      if (ps[paramidx].range>1) {
        /* convert array and pass by address */
        ps[paramidx].v.ptr = fillarray(amx, &ps[paramidx], cptr);
      } /* if */
      break;
    case 'p':
    case 's':
    case 'p' | BYREF:
    case 's' | BYREF:
      if (ps[paramidx].type=='s' || ps[paramidx].type=='p') {
        int len;
        /* get length of input string */
        amx_StrLen(cptr,&len);
        len++;            /* include '\0' */
        /* check max. size */
        if (len<ps[paramidx].range)
          len=ps[paramidx].range;
        ps[paramidx].range=len;
      } /* if */
      ps[paramidx].v.ptr=malloc(ps[paramidx].range*sizeof(TCHAR));
      if (ps[paramidx].v.ptr==NULL)
        return amx_RaiseError(amx, AMX_ERR_NATIVE);
      amx_GetString((char *)ps[paramidx].v.ptr,cptr,sizeof(TCHAR)>1,UNLIMITED);
      break;
    default:
      /* invalid parameter type */
      return amx_RaiseError(amx, AMX_ERR_NATIVE);
    } /* switch */
    paramidx++;
  } /* while */
  if ((params[0]/sizeof(cell)) - 3 != (size_t)paramidx)
    return amx_RaiseError(amx, AMX_ERR_NATIVE); /* format string does not match number of parameters */

  #if defined HAVE_DYNCALL_H
    for (idx = 0; idx < paramidx; idx++) {
      if ((ps[idx].type=='i' || ps[idx].type=='u' || ps[idx].type=='f') && ps[idx].range==1) {
        switch (ps[idx].size) {
        case 8:
          dcArgChar(dcVM,(unsigned char)(ps[idx].v.val & 0xff));
          break;
        case 16:
          dcArgShort(dcVM,(unsigned short)(ps[idx].v.val & 0xffff));
          break;
        default:
          dcArgLong(dcVM,ps[idx].v.val);
        } /* switch */
      } else {
        dcArgPointer(dcVM,ps[idx].v.ptr);
      } /* if */
    } /* for */
    result=(cell)dcCallPointer(dcVM,(void*)LibFunc);
  #else /* HAVE_DYNCALL_H */
    /* push the parameters to the stack (left-to-right in 16-bit; right-to-left
     * in 32-bit)
     */
#if defined __WIN32__ || defined _WIN32 || defined WIN32
    for (idx=paramidx-1; idx>=0; idx--) {
#else
    for (idx=0; idx<paramidx; idx++) {
#endif
      if ((ps[idx].type=='i' || ps[idx].type=='u' || ps[idx].type=='f') && ps[idx].range==1) {
        switch (ps[idx].size) {
        case 8:
          push((unsigned char)(ps[idx].v.val & 0xff));
          break;
        case 16:
          push((unsigned short)(ps[idx].v.val & 0xffff));
          break;
        default:
          push(ps[idx].v.val);
        } /* switch */
      } else {
        push(ps[idx].v.ptr);
      } /* if */
    } /* for */

    /* call the function; all parameters are already pushed to the stack (the
     * function should remove the parameters from the stack)
     */
    result=LibFunc();
  #endif /* HAVE_DYNCALL_H */

  /* store return values and free allocated memory */
  for (idx=0; idx<paramidx; idx++) {
    switch (ps[idx].type) {
    case 'p':
    case 's':
      free(ps[idx].v.ptr);
      break;
    case 'p' | BYREF:
    case 's' | BYREF:
      cptr=amx_Address(amx,params[idx+4]);
      amx_SetString(cptr,(char *)ps[idx].v.ptr,ps[idx].type==('p'|BYREF),sizeof(TCHAR)>1,UNLIMITED);
      free(ps[idx].v.ptr);
      break;
    case 'i':
    case 'u':
    case 'f':
      assert(ps[idx].range==1);
      break;
    case 'i' | BYREF:
    case 'u' | BYREF:
    case 'f' | BYREF:
      cptr=amx_Address(amx,params[idx+4]);
      if (ps[idx].range==1) {
        /* modify directly in the AMX (no memory block was allocated */
        switch (ps[idx].size) {
        case 8:
          *cptr= (ps[idx].type==('i' | BYREF)) ? (long)((signed char)*cptr) : (*cptr & 0xff);
          break;
        case 16:
          *cptr= (ps[idx].type==('i' | BYREF)) ? (long)((short)*cptr) : (*cptr & 0xffff);
          break;
        } /* switch */
      } else {
        int i;
        for (i=0; i<ps[idx].range; i++) {
          switch (ps[idx].size) {
          case 8:
            *cptr= (ps[idx].type==('i' | BYREF)) ? ((signed char*)ps[idx].v.ptr)[i] : ((unsigned char*)ps[idx].v.ptr)[i];
            break;
          case 16:
            *cptr= (ps[idx].type==('i' | BYREF)) ? ((short*)ps[idx].v.ptr)[i] : ((unsigned short*)ps[idx].v.ptr)[i];
            break;
          default:
            *cptr= (ps[idx].type==('i' | BYREF)) ? ((long*)ps[idx].v.ptr)[i] : ((unsigned long*)ps[idx].v.ptr)[i];
          } /* switch */
        } /* for */
        free((char *)ps[idx].v.ptr);
      } /* if */
      break;
    default:
      assert(0);
    } /* switch */
  } /* for */

  return result;
}

/* bool: libfree(const libname[]="")
 * When the name is an empty string, this function frees all libraries (for this
 * abstract machine). The name comparison is case sensitive.
 * Returns true if one or more libraries were freed.
 */
static cell AMX_NATIVE_CALL n_libfree(AMX *amx, const cell *params)
{
  const TCHAR *libname;
  amx_StrParam(amx,params[1],libname);
  return freelib(&ModRoot,amx,libname) > 0;
}

#else /* HAVE_DYNCALL_H || WIN32_FFI */

static cell AMX_NATIVE_CALL n_libcall(AMX *amx, const cell *params)
{
  (void)amx;
  (void)params;
  return 0;
}
Esempio n. 4
0
int AMXEXPORT AMXAPI amx_ProcessCleanup(AMX *amx)
{
  freelib(&ModRoot, amx, NULL);
  closepipe();
  return AMX_ERR_NONE;
}
Esempio n. 5
0
/*--------------------------------------------------------*/
void	CheckLib(void)
		{
static	lib		*ll=NULL,*nav=NULL;
		lib		*l;
		char 	r[16],rr[16];

		if(!LPP)
			LPP=OBP;

		CheckItem(LPP);
        LPP = LPP->next;


		if(ll)
		{
			if(!LL)
			{
				puts_pc("-d\r\n>");
				ll=NULL;
			}
			else
			{
				if(!LL->x || edit_flag!=eof)
				{
					puts_pc("-d\r\n>");
					ll=NULL;
				}
			}
		}
		if(LL)
			if(LL->x && edit_flag==eof)
				ll=CheckItem(LL);


		if(nav)
		{
			if(!NAV)
			{
				puts_pc("-n\r\n>");
				nav=NULL;
			}
			else
			{
				if(!NAV->x)
				{
					puts_pc("-n\r\n>");
					nav=NULL;
				}
			}
		}
		if(NAV)
			if(NAV->x)
				nav=CheckItem(NAV);

		while(LD) {
			sprintf(r,"-l %s\r\n>",LinkAddrText(LinkAddr(LD),rr));
			puts_pc(r);
			l=LD;
			LD=LD->next;
			if(LPP==l)
				LPP=OBP;
			freelib(l);
			}

		if(!CPM)
			CPM=CP;
		ListMenu(CPM,Cedit,null);
		if(CPM)
			CPM=CPM->next;

		ListMenu(GUN,edit_gun,null);
		ListMenu(METEO,set_meteo,null);
		ListMenu(SYS,set_system,null);
		ListMenu(LINK,SetupMenu,null);
		}
Esempio n. 6
0
/*------------------------------------------------------------------*/
void	ListLib(lib *lb)
		{
		gun		*g;
		lib		*ll;
		char	*p,c[256],cc[8];
		int		i,j;

		copylib(lb,ll=makelib());
		if(lb == LL)
			sprintf(c,"=d");
        else{
			if(lb == NAV)
				sprintf(c,"=n");
			else
				sprintf(c,"=l");
            }
		sprintf(strchr(c,0)," %s,%d\r\n",LinkAddrText(LinkAddr(ll),cc),targets_xn(ll));
		puts_pc(c);
		for(ll->xc=ll->x; ll->xc; ll->xc=ll->xc->next) {
			puts_pc("=c ");
			putsLLA(ll);
			if(checktype(ll,TYPE_BT))
				sprintf(c," %d %d\r\n",ll->xc->muzzle,ll->xc->refp);
			else
				sprintf(c,"\r\n");
			puts_pc(c);
			}
		if(ll->txt) {
			for(p=ll->txt->t; (*p==' ') && *p; ++p);
			sprintf(c,"=t %s\r\n",p);
			}
		else
			sprintf(c,"=t ...\r\n");
		puts_pc(c);
		if(Guns && checktype(ll,TYPE_BT)) {
			g=&Guns[ll->gun];
			sprintf(c,"=g %s %d %d %d %d %d\r\n",g->name,ll->refd,ll->powder,g->left,g->right,g->mils);
			puts_pc(c);
			for(i=0; g->ammo[i]; ++i) {
				j=ll->ammpcs[i];
				sprintf(c,"=a %s %d ",g->ammo[i],j & 0xfff);
				j /= 0x1000;
				if(!j)
					sprintf(strchr(c,0),"N");
				if(j < 0)
					do  sprintf(strchr(c,0),"-"); while(++j);
				if(j > 0)
					do  sprintf(strchr(c,0),"+"); while(--j);
				sprintf(strchr(c,0),"\r\n");
				puts_pc(c);
				}
			}
		if(lb == LL)
			sprintf(c,"=d");
        else{
			if(lb == NAV)
				sprintf(c,"=n");
			else
				sprintf(c,"=l");
            }
		sprintf(strchr(c,0),"\r\n>");
		puts_pc(c);
		freelib(ll);
		}
Esempio n. 7
0
/*------------------------------------------------------*/
void		LoadFromPc(char *p)
			{
			void	InProg(void);
			int		ReadPar(char *);

			char	q[LINK_LEN],*r,*s,*ss[16];
			int		i,j,k;
			long	y,z;
			lib		*l;
			command	*c,**cp;

			switch(*p)
			{
			case 'd':
				Lr=scanLLA(Lr,++p,null);
				if(!Lr)
				{
					j=0;
					switch(strscan(p,ss,',',16))
					{
					case 2:
						j=atoi(ss[1]);
					case 1:
						if(l=FindLib(LinkAddrStr(ss[0])))
						{
							copylib(l,Lr=makelib());
							if(j)
								for(Lr->xc=Lr->x; --j && Lr->xc->next;)
									Lr->xc=Lr->xc->next;
							else
								Lr->x=Lr->xc=freecoord(Lr->x);
							Ungetch(REFRESH,0);
						}
						else
							puts_pc("!NOT_FOUND\r\n");
						break;
					default:
						puts_pc("!SYNTAX\r\n");
						break;
					}
				}
				break;

				case 'l':	if(i=LinkAddrStr(++p)) 
							{
								freelib(Lc);
								Lc=makelib();
								Lc->ltype=LinkAddrType(i);
								Lc->n=LinkAddrN(i);
								}
							else
								InsertLib(&Lc);
							break;

				case 'M':	if(sscanf(++p," %d,%04X,%04X,%s",&k,&i,&j,q)==4) {
                                if(Mscan)
/* znak, da je editor odprt ! */   	if(Mscan->c->maxopt) {
/* vrstica in obseg aktivna ? */		if(k)
											if(--k <= Mscan->c->maxopt) {
												Mscan->active = k;
        	       		                    	Refresh();
            	           		            	}
                                   		break;
                                    	}
                                r=strchr(q,',');
                                *r++=0;
                                cp=NULL;
                                if(!strcmp(q,"message"))
                                	cp=&CP;
                               	if(!strcmp(q,"gun"))
                               		cp=&GUN;
								if(!strcmp(q,"meteo"))
                                	cp=&METEO;
                                if(!cp)
                                	break;
/*......................................................................................*/
	                            if(!*cp)
                                	new_command(cp);
                                else{
	                               	c=*cp;
									do
										if(c->chk == j)
											*cp=c;
										else
											c=c->next;
									while(c != *cp);
									if((*cp)->chk != j)
										new_command(cp);
            						}
								(*cp)->chk=j;
                                c=*cp;
                                s=(char *)c;
								i = sizeof(command) - sizeof(command *) - sizeof(int);
								while(i--) {
					 				sscanf(r,"%02X",&j);
                                    *s++ = j;
									++r;++r;
									}
                                c->chk *= -1;
								if(cp == &CP)
									Ungetch(GXM_MESSAGE_ID,0);
								if(cp == &GUN)
									Ungetch(GXM_GUN_ID,0);
								}
							break;
				case 'r':   if(crest && (sscanf(++p," %ld %ld",&y,&z) == 2)) {
								add_coord(crest,0,y,z);
								crest->xc->refp=null;
								}
							else
								DeleteTask(DMRtimeout,RTC_task);
							break;

				case 'c':   i=j=0;
							if(Lc)
								Lc=scanLLA(Lc,++p,eof);
							break;
				case 'g':	if(Lc && (sscanf(++p," %s %d %d",q,&j,&k) == 3)) {
							for(i=0; Guns[i].name; ++i)
								if(!strcmp(Guns[i].name,q)) {
									Lc->gun=i;
									Lc->refd=j;
									Lc->powder=k;
									}
								}
							break;
				case 'a':	if(Lc && (sscanf(++p,"%s %d",q,&j) == 2)) {
								for(i=0; Guns[Lc->gun].ammo[i]; ++i)
									if(!strcmp(Guns[Lc->gun].ammo[i],q)) {
										Lc->ammpcs[i]=j;
										r=strchr(p,'+');
										s=strrchr(p,'+');
										if(r)
											do	Lc->ammpcs[i] += 0x1000;
													while(r++ != s);
										r=strchr(p,'-');
										s=strrchr(p,'-');
										if(r)
											do	Lc->ammpcs[i] -= 0x1000;
													while(r++ != s);
										}
								}
							break;
				case 'p':	if(sscanf(++p,"%d,%d",&i,&j) == 2)
								if(i<12 && j<4) {
									xyLCD(i,j);
									Ungetch(GXM_CURSOR_POS,0);
									}
							break;

				case 'm':	LoadHexRec(p,'m',_MenuCode);
							break;
				case 'h':	LoadHexRec(p,'h',_MenuHead);
							break;
				case 't':	if(Lc)
							{
								++p;
								++p;
								Lc->txt=addtxt(Lc,p);
							}
							else
								LoadHexRec(p,'t',_TextCode);
							break;

				case 'T':	if(sscanf(++p," %x %x",&i,&j)==2)
							{
							sprintf(q,"%04X\r\n",readTEMP(i,j));
							puts_pc(q);
							}
							break;

				case 'f':   if(ReadPar(++p))
								break;
							i=strscan(p,ss,' ',16);
							if(i>=2)
							{
								sscanf(ss[0],"%lx",&eebott);
								sscanf(ss[1],"%lx",&eetop);
								if(eebott < (long)FLASHTOP)
								{
									puts_pc("!ILL_ADDRESS\r\n");
									break;
								}
								if(eetop > (long)FLASHTOP+0x80000L)
								{
									puts_pc("!ILL_ADDRESS\r\n");
									break;
								}
								if(i==3)
								{
									ss[2][8]=0;
									sprintf(pass,"%-8s",ss[2]);
								}
								if(CheckPass(&syspass))
								{
									puts_pc("!NOT_ALLOWED\r\n");
									break;
								}
								puts_pc("\7\r\nFLASH programming !!!\r\n");
								wait(50);
								InProg();
								puts_pc("Done\r\n");
							}
							else
								puts_pc("!SYNTAX\r\n");
							break;
				case 'b':	k=sscanf(++p," %d %d",&i,&j);
							if(k)
								if(Baud(CHPC,i)) {
									if(k==2)
										Xonoff(j);
									break;
									}
							puts_pc("!SYNTAX\r\n");
							break;

				case 'z':	EnterZone(++p);
							break;

				case 'G':	DeleteTask(ReadPc,RTC_task);
							Guns=ReadGunData(0,0,0,0,NULL);
							SetTask(ReadPc,0,RTC_task);
							break;
				default:	puts_pc("!SYNTAX\r\n");
							break;
				}
			}
Esempio n. 8
0
/*------------------------------------------------------------------*/
lib		*scanLLA(lib *l,char *s, int n)
{
	int		i,j=0;
	char	*ss[8];
	char	p[128];
	lib		*ll;

	strncpy(p,s,127);
	p[127]=0;
	i=strscan(p,ss,',',8);
	if(i<3)
	{
		strncpy(p,s,127);
		p[127]=0;
		i=strscan(p,ss,' ',8);
	}
	if(i<3)
		return(NULL);
 	if(!l)
	{
		l=makelib();
		copylib(LL,l);
	}
	if(!l->ltype)
	{
		l->ltype=addtype(TYPE_TG);
		l->txt=l->ltype->typtxt;
		auto_ntyp(&l);
	}
	if(i>3)
		j=*ss[3];
	if(n || !l->x || j=='+')
		AddCoord(l,0,0,0);

	l->xc->x=atof(ss[0]);
	l->xc->y=atof(ss[1]);
	l->xc->z=atof(ss[2]);
	if(coordtx)
		Utm2Lla(l,l);	
	else
	{
		l->xc->x *= M_PI/180.0;
		l->xc->y *= M_PI/180.0;
	}

	l->xc->t=Time;
	if(i==6)
	{
		l->xc->muzzle=atoi(ss[4]);
		l->xc->refp=atoi(ss[5]);
	}
	else
	{
		l->xc->muzzle=0;
		ll=copylib(l,ll=makelib());
		LlaToCorr(l,ll,OBP,NULL,EL_AZ_R);
		l->xc->refp = ScaleAngle(ll->xc->y + maxmils/2,maxmils,MR10,eof)+0.5;
		freelib(ll);
	}
	return(l);
	}