1 // Copyright (c) <2012> <Leif Asbrink>
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without restriction,
6 // including without limitation the rights to use, copy, modify,
7 // merge, publish, distribute, sublicense, and/or sell copies of
8 // the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 
24 #include <ctype.h>
25 #include "globdef.h"
26 #include "uidef.h"
27 #include "screendef.h"
28 #include "keyboard_def.h"
29 #include "rusage.h"
30 #include "thrdef.h"
31 
32 extern void users_eme(void);
33 
34 #define MAX_EMEPARM 4
35 extern char *eme_own_info_filename;
36 extern char *eme_allcalls_filename;
37 extern char *eme_emedta_filename;
38 extern char *eme_dirskd_filename;
39 extern char *eme_dxdata_filename;
40 extern char *eme_call3_filename;
41 extern char *eme_error_report_file;
42 
43 #define EGH 18
44 #define DX_SEARCH_LINES 2
45 
46 int eg_old_y1;
47 int eg_old_y2;
48 int eg_old_x1;
49 int eg_old_x2;
50 
51 
52 void make_eme_graph(int clear_old);
53 int eme_graph_scro;
54 int emeparm_int[MAX_EMEPARM];
55 float *emeparm_float;
56 char *emeparm_text[MAX_EMEPARM+1]={"Auto init",        //0
57                       "UTC correction",                //1
58                       "Latitude (+ for N)",            //2
59                       "Longitude (+ for E)",           //3
60                       "Locator"};
61 char tmp_locator[7];
62 char dx_locator[7];
63 int dx_no;
64 FILE *locerr_file;
65 float cos_laref;
66 float sin_laref;
67 float cos_dxlat;
68 float sin_dxlat;
69 void locator_to_latlong(void);
70 void dist_az(float *dist, float *azimuth, float lat, float lon,
71                                         float dxlat, float dxlon);
72 void latlong_to_locator(float lon, float lat);
73 
74 
75 float dx_lat;
76 float tmp_lat;
77 float dx_lon;
78 float tmp_lon;
79 float dx_dist;
80 float dx_az;
81 int dxflag;
82 #define MAX_SUGGESTED 6
83 int eg_move_flag;
84 
85 int suggested_calls[MAX_SUGGESTED];
86 int suggested_calls_counter;
87 char dx_callsign[EG_DX_CHARS+1];
88 
89 
90 #define MAX_DXCALLS 10000
91 #define RAD (PI_L/180)
92 
check_eg_borders(void)93 void check_eg_borders(void)
94 {
95 current_graph_minh=eg_vsiz;
96 current_graph_minw=eg_hsiz;
97 check_graph_placement((void*)(&eg));
98 set_graph_minwidth((void*)(&eg));
99 }
100 
101 
clear_search_result_box(void)102 void clear_search_result_box(void)
103 {
104 lir_fillbox(eg.xleft+1,egbutt[EG_DX].y1+3+text_height,
105 eg.xright-eg.xleft-1,eg.ybottom-egbutt[EG_DX].y1-3-text_height,0);
106 settextcolor(10);
107 lir_pixwrite(egbutt[EG_DX].x1+text_width/2,egbutt[EG_DX].y1+2,dx_callsign);
108 settextcolor(7);
109 }
110 
show_dx_location(void)111 void show_dx_location(void)
112 {
113 char s[80];
114 settextcolor(10);
115 lir_pixwrite(egbutt[EG_LOC].x1+text_width/2,egbutt[EG_LOC].y1+2,dx_locator);
116 sprintf(s,"%d   ",(int)(dx_az/RAD));
117 s[3]=0;
118 lir_pixwrite(eg.xleft+text_width/2,egbutt[EG_LOC].y1+2,s);
119 sprintf(s,"%d     ",(int)(dx_dist));
120 s[6]=0;
121 lir_pixwrite(egbutt[EG_LOC].x2+text_width/2,egbutt[EG_LOC].y1+2,s);
122 settextcolor(7);
123 clear_search_result_box();
124 }
125 
126 
127 
new_eme_loc(void)128 void new_eme_loc(void)
129 {
130 int i;
131 for(i=0; i<6; i++)tmp_locator[i]=numinput_txt[i];
132 locator_to_latlong();
133 for(i=0; i<6; i++)dx_locator[i]=tmp_locator[i];
134 dx_locator[6]=0;
135 dx_lat=tmp_lat;
136 dx_lon=tmp_lon;
137 dxflag=1;
138 eme_time=0;
139 cos_dxlat=cos(RAD*dx_lat);
140 sin_dxlat=sin(RAD*dx_lat);
141 dist_az(&dx_dist, &dx_az, emeparm_float[2],emeparm_float[3], dx_lat, dx_lon);
142 suggested_calls_counter=1;
143 show_dx_location();
144 numinput_flag=-1;
145 }
146 
147 
148 
149 
150 
clear_dx(void)151 void clear_dx(void)
152 {
153 char s[80];
154 int i;
155 for(i=0; i<EG_DX_CHARS; i++)s[i]=' ';
156 s[EG_DX_CHARS]=0;
157 lir_pixwrite(egbutt[EG_DX].x1+text_width/2,egbutt[EG_DX].y1+2,s);
158 dxflag=0;
159 }
160 
new_dx_result(void)161 void new_dx_result(void)
162 {
163 char s[256];
164 int i, j, k, m;
165 int line, pos;
166 if(suggested_calls_counter == 0)
167   {
168   clear_dx();
169   return;
170   }
171 if(suggested_calls_counter == 1)
172   {
173   for(i=0; i<EG_DX_CHARS; i++)dx_callsign[i]=dx[suggested_calls[0]].call[i];
174   tmp_lon=-dx[suggested_calls[0]].lon;
175   tmp_lat=dx[suggested_calls[0]].lat;
176   latlong_to_locator(tmp_lon,tmp_lat);
177   for(i=0; i<6; i++)numinput_txt[i]=tmp_locator[i];
178   new_eme_loc();
179   }
180 else
181   {
182   for(i=0; i<EG_DX_CHARS; i++)
183     {
184     dx_callsign[i]=' ';
185     }
186   }
187 dx_callsign[EG_DX_CHARS]=0;
188 k=0;
189 for(j=0; j<DX_SEARCH_LINES; j++)
190   {
191   for(i=0; i<EGH-1; i++)
192     {
193     s[k]=' ';
194     k++;
195     }
196   s[k]=0;
197   k++;
198   }
199 if(suggested_calls_counter > 1)
200   {
201   line=0;
202   pos=0;
203   for(i=0; i<suggested_calls_counter; i++)
204     {
205     k=suggested_calls[i];
206     j=0;
207     while(dx[k].call[j] != ' ')j++;
208     if(dx[k].call[j] == ' ')j--;
209     if(pos+j >= EGH-1)
210       {
211       pos=0;
212       line++;
213       if(line >= DX_SEARCH_LINES)
214         {
215         j=0;
216         goto nomore;
217         }
218       }
219     m=0;
220     while(m <= j)
221       {
222       s[EGH*line+pos]=dx[k].call[m];
223       m++;
224       pos++;
225       }
226     pos++;
227     }
228 nomore:;
229   if(j==0)settextcolor(13);
230   }
231 clear_search_result_box();
232 for(i=0; i<DX_SEARCH_LINES; i++)
233   {
234   lir_pixwrite(eg.xleft+text_width/2,egbutt[EG_DX].y1+3+(i+1)*text_height,
235                                                          &s[i*EGH]);
236   }
237 if(j==0)settextcolor(7);
238 }
239 
240 
star_match_dx_a(void)241 void star_match_dx_a(void)
242 {
243 int i, j, k, ia, ib, ib0;
244 // The first character is a star.
245 // Find the length of the fragment.
246 ib0=1;
247 while(  ib0 < numinput_curpos && numinput_txt[ib0] != '*')ib0++;
248 // Search for calls containing the string.
249 for(i=0; i<dx_no; i++)
250   {
251   ia=1;
252   j=0;
253   ib=ib0;
254 get_string:;
255   while(dx[i].call[j] != numinput_txt[ia] && j <  CALLSIGN_CHARS )j++;
256   if(j < CALLSIGN_CHARS)
257     {
258 // We have found the first character.
259     for(k=ia+1; k<ib; k++)
260       {
261       j++;
262       if(dx[i].call[j] != numinput_txt[k] && numinput_txt[k] != '?')goto fail;
263       }
264     if(j >= CALLSIGN_CHARS)goto fail;
265 // The string matches.
266 // If there no more '*' in the search string, decide if sucess or fail.
267     if(ib==numinput_curpos)
268       {
269       j++;
270       if(j == CALLSIGN_CHARS)goto sucess;
271       if(dx[i].call[j] == ' ')goto sucess;
272       goto fail;
273       }
274     ib++;
275     if(ib==numinput_curpos)goto sucess;
276     ia=ib;
277     while(  ib < numinput_curpos && numinput_txt[ib] != '*')ib++;
278     goto get_string;
279 sucess:;
280     suggested_calls[suggested_calls_counter]=i;
281     suggested_calls_counter++;
282     if(suggested_calls_counter >= MAX_SUGGESTED)goto maxsug;
283     }
284 fail:;
285   }
286 maxsug:;
287 new_dx_result();
288 }
289 
star_match_dx_b(void)290 void star_match_dx_b(void)
291 {
292 int i, j, k, ia, ib, ib0;
293 // The first character is not a star.
294 // Find the length of the fragment.
295 ib0=1;
296 while(  ib0 < numinput_curpos && numinput_txt[ib0] != '*')ib0++;
297 // Search for calls beginning with the fragment string.
298 for(i=0; i<dx_no; i++)
299   {
300   for(k=0; k<ib0; k++)
301     {
302     if(dx[i].call[k] != numinput_txt[k] && numinput_txt[k] != '?')goto fail;
303     }
304   ib=ib0+1;
305   if(ib==numinput_curpos)goto sucess;
306   j=0;
307 get_string:;
308   ia=ib;
309   while(  ib < numinput_curpos && numinput_txt[ib] != '*')ib++;
310   while(dx[i].call[j] != numinput_txt[ia] && j <  CALLSIGN_CHARS )j++;
311   if(j < CALLSIGN_CHARS)
312     {
313 // We have found the first character.
314     for(k=ia+1; k<ib; k++)
315       {
316       j++;
317       if(dx[i].call[j] != numinput_txt[k] && numinput_txt[k] != '?')goto fail;
318       }
319     if(j >= CALLSIGN_CHARS)goto fail;
320 // The string matches.
321 // If there no more '*' in the search string, decide if sucess or fail.
322     if(ib==numinput_curpos)
323       {
324       j++;
325       if(j == CALLSIGN_CHARS)goto sucess;
326       if(dx[i].call[j] == ' ')goto sucess;
327       goto fail;
328       }
329     ib++;
330     if(ib==numinput_curpos)goto sucess;
331     goto get_string;
332 sucess:;
333     suggested_calls[suggested_calls_counter]=i;
334     suggested_calls_counter++;
335     if(suggested_calls_counter >= MAX_SUGGESTED)goto maxsug;
336     }
337 fail:;
338   }
339 maxsug:;
340 new_dx_result();
341 }
342 
343 
new_eme_dx(void)344 void new_eme_dx(void)
345 {
346 int i,j,k;
347 pause_thread(THREAD_SCREEN);
348 hide_mouse(eg.xleft,eg.xright,eg.ytop,eg.ybottom);
349 // Search the data base for the call sign in numinput_txt.
350 // Just return if we have 2 or less characters
351 numinput_flag=-1;
352 suggested_calls_counter=0;
353 // There may be '*' and '?' in the call.
354 // Clean up the search string in case '?' are next to '*'
355 // or there are multiple '*'.
356 i=0;
357 while(i<numinput_curpos)
358   {
359   if(numinput_txt[i]=='*')
360     {
361     while(i>0 && numinput_txt[i-1] == '*')i--;
362     while(i>0 && numinput_txt[i-1] == '?')
363       {
364       i--;
365       k=i;
366       while(k<numinput_curpos)
367         {
368         numinput_txt[k]=numinput_txt[k+1];
369         k++;
370         }
371       numinput_curpos--;
372       if(i>0)i--;
373       }
374     }
375   if(numinput_txt[i]=='*')
376     {
377     while(i<numinput_curpos-1 &&
378                   (numinput_txt[i+1] == '?' || numinput_txt[i+1] == '*'))
379       {
380       k=i+1;
381       while(k<numinput_curpos)
382         {
383         numinput_txt[k]=numinput_txt[k+1];
384         k++;
385         }
386       numinput_curpos--;
387       }
388     }
389   i++;
390   }
391 if(numinput_curpos<=2)
392   {
393   clear_dx();
394   goto new_eme_dx_x;
395   }
396 // If the first character is '*' call a special routine.
397 if(numinput_txt[0] == '*')
398   {
399   star_match_dx_a();
400   goto new_eme_dx_x;
401   }
402 // If there is any '*' at all, call another special routine
403 for(i=0; i<numinput_curpos; i++)
404   {
405   if(numinput_txt[i] == '*')
406     {
407     star_match_dx_b();
408     goto new_eme_dx_x;
409     }
410   }
411 // Search for matching calls with fixed positions for the
412 // characters.
413 for(i=0; i<dx_no; i++)
414   {
415   j=0;
416   while(j<numinput_curpos &&
417          (numinput_txt[j] == '?' || numinput_txt[j]==dx[i].call[j])  )j++;
418   if(j == numinput_curpos &&
419         (dx[i].call[j] == ' ' || numinput_curpos >= CALLSIGN_CHARS)  )
420     {
421     suggested_calls[suggested_calls_counter]=i;
422     suggested_calls_counter++;
423     if(suggested_calls_counter >= MAX_SUGGESTED)goto maxsug;
424     }
425   }
426 maxsug:;
427 new_dx_result();
428 new_eme_dx_x:;
429 resume_thread(THREAD_SCREEN);
430 }
431 
432 
help_on_eme_graph(void)433 void help_on_eme_graph(void)
434 {
435 int msg_no;
436 int event_no;
437 // Set msg invalid in case we are not in any select area.
438 msg_no=-1;
439 for(event_no=0; event_no<MAX_EGBUTT; event_no++)
440   {
441   if( egbutt[event_no].x1 <= mouse_x &&
442       egbutt[event_no].x2 >= mouse_x &&
443       egbutt[event_no].y1 <= mouse_y &&
444       egbutt[event_no].y2 >= mouse_y)
445     {
446     switch (event_no)
447       {
448       case EG_TOP:
449       case EG_BOTTOM:
450       case EG_LEFT:
451       case EG_RIGHT:
452       msg_no=101;
453       break;
454 
455       case EG_MINIMISE:
456       msg_no=70;
457       break;
458 
459       case EG_LOC:
460       msg_no=71;
461       break;
462 
463       case EG_DX:
464       msg_no=72;
465       break;
466       }
467     }
468   }
469 help_message(msg_no);
470 }
471 
mouse_continue_eme_graph(void)472 void mouse_continue_eme_graph(void)
473 {
474 int i, j;
475 switch (mouse_active_flag-1)
476   {
477   case EG_TOP:
478   if(eg.ytop!=mouse_y)goto egm;
479   break;
480 
481   case EG_BOTTOM:
482   if(eg.ybottom!=mouse_y)goto egm;
483   break;
484 
485   case EG_LEFT:
486   if(eg.xleft!=mouse_x)goto egm;
487   break;
488 
489   case EG_RIGHT:
490   if(eg.xright==mouse_x)break;
491 egm:;
492   pause_screen_and_hide_mouse();
493   graph_borders((void*)&eg,0);
494   eg_move_flag=1;
495   if(eg_oldx==-10000)
496     {
497     eg_oldx=mouse_x;
498     eg_oldy=mouse_y;
499     }
500   else
501     {
502     i=mouse_x-eg_oldx;
503     j=mouse_y-eg_oldy;
504     eg_oldx=mouse_x;
505     eg_oldy=mouse_y;
506     eg.ytop+=j;
507     eg.ybottom+=j;
508     eg.xleft+=i;
509     eg.xright+=i;
510     check_eg_borders();
511     }
512   graph_borders((void*)&eg,15);
513   resume_thread(THREAD_SCREEN);
514   break;
515 
516   default:
517   goto await_release;
518   }
519 if(leftpressed == BUTTON_RELEASED)goto finish;
520 return;
521 await_release:;
522 if(leftpressed != BUTTON_RELEASED) return;
523 switch (mouse_active_flag-1)
524   {
525   case EG_MINIMISE:
526   eg.minimise^=1;
527   break;
528 
529   case EG_LOC:
530   for(i=0; i<EG_DX_CHARS; i++) dx_callsign[i]=' ';
531   mouse_active_flag=1;
532   numinput_chars=EG_LOC_CHARS;
533   numinput_xpix=egbutt[EG_LOC].x1+text_width/2;
534   numinput_ypix=egbutt[EG_LOC].y1+2;
535   erase_numinput_txt();
536   numinput_flag=TEXT_PARM;
537   par_from_keyboard_routine=new_eme_loc;
538   return;
539 
540   case EG_DX:
541   mouse_active_flag=1;
542   numinput_chars=EG_DX_CHARS;
543   numinput_xpix=egbutt[EG_DX].x1+text_width/2;
544   numinput_ypix=egbutt[EG_DX].y1+2;
545   erase_numinput_txt();
546   numinput_flag=TEXT_PARM;
547   par_from_keyboard_routine=new_eme_dx;
548   return;
549 
550   default:
551   lirerr(872);
552   break;
553   }
554 finish:;
555 leftpressed=BUTTON_IDLE;
556 mouse_active_flag=0;
557 make_eme_graph(TRUE);
558 if(eg.minimise==0)calculate_moon_data();
559 eg_oldx=-10000;
560 }
561 
mouse_on_eme_graph(void)562 void mouse_on_eme_graph(void)
563 {
564 int event_no;
565 // First find out is we are on a button or border line.
566 for(event_no=0; event_no<MAX_EGBUTT; event_no++)
567   {
568   if( egbutt[event_no].x1 <= mouse_x &&
569       egbutt[event_no].x2 >= mouse_x &&
570       egbutt[event_no].y1 <= mouse_y &&
571       egbutt[event_no].y2 >= mouse_y)
572     {
573     eg_old_y1=eg.ytop;
574     eg_old_y2=eg.ybottom;
575     eg_old_x1=eg.xleft;
576     eg_old_x2=eg.xright;
577     mouse_active_flag=1+event_no;
578     current_mouse_activity=mouse_continue_eme_graph;
579     return;
580     }
581   }
582 // Not button or border.
583 // Do nothing.
584 current_mouse_activity=mouse_nothing;
585 mouse_active_flag=1;
586 }
587 
588 
make_eme_graph(int clear_old)589 void make_eme_graph(int clear_old)
590 {
591 int xj,xi,yj,yi;
592 pause_thread(THREAD_SCREEN);
593 if(clear_old)
594   {
595   hide_mouse(eg_old_x1,eg_old_x2,eg_old_y1,eg_old_y2);
596   lir_fillbox(eg_old_x1,eg_old_y1,eg_old_x2-eg_old_x1+1,
597                                                     eg_old_y2-eg_old_y1+1,0);
598   }
599 eg_move_flag=0;
600 if(eg.minimise == 0 && eme_flag == 2)
601   {
602   eg_hsiz=EGH*text_width;
603   eg_vsiz=(4+DX_SEARCH_LINES)*text_height+3;
604   eme_active_flag=1;
605   cos_laref=cos(RAD*emeparm_float[2]);
606   sin_laref=sin(RAD*emeparm_float[2]);
607   }
608 else
609   {
610   eg_hsiz=2*text_width-1;
611   eg_vsiz=1.5*text_height-1;
612   eme_active_flag=0;
613   }
614 eg_flag=1;
615 check_eg_borders();
616 clear_button(egbutt, MAX_EGBUTT);
617 hide_mouse(eg.xleft,eg.xright,eg.ytop,eg.ybottom);
618 scro[eme_graph_scro].no=EME_GRAPH;
619 scro[eme_graph_scro].x1=eg.xleft;
620 scro[eme_graph_scro].x2=eg.xright;
621 scro[eme_graph_scro].y1=eg.ytop;
622 scro[eme_graph_scro].y2=eg.ybottom;
623 egbutt[EG_LEFT].x1=eg.xleft;
624 egbutt[EG_LEFT].x2=eg.xleft+2;
625 egbutt[EG_LEFT].y1=eg.ytop;
626 egbutt[EG_LEFT].y2=eg.ybottom;
627 egbutt[EG_RIGHT].x1=eg.xright-2;
628 egbutt[EG_RIGHT].x2=eg.xright;
629 egbutt[EG_RIGHT].y1=eg.ytop;
630 egbutt[EG_RIGHT].y2=eg.ybottom;
631 egbutt[EG_TOP].x1=eg.xleft;
632 egbutt[EG_TOP].x2=eg.xright;
633 egbutt[EG_TOP].y1=eg.ytop;
634 egbutt[EG_TOP].y2=eg.ytop+2;
635 egbutt[EG_BOTTOM].x1=eg.xleft;
636 egbutt[EG_BOTTOM].x2=eg.xright;
637 egbutt[EG_BOTTOM].y1=eg.ybottom-2;
638 egbutt[EG_BOTTOM].y2=eg.ybottom;
639 // Draw the border lines
640 graph_borders((void*)&eg,7);
641 eg_oldx=-10000;
642 settextcolor(7);
643 xj=eg.xleft+text_width-1;
644 if(eme_active_flag != 0)
645   {
646   xi=xj+3.5*text_width;
647   yi=eg.ytop+2*text_height;
648   egbutt[EG_LOC].x1=xi;
649   egbutt[EG_LOC].x2=xi+text_width*(EG_LOC_CHARS+0.5);
650   egbutt[EG_LOC].y1=yi;
651   yi+=text_height;
652   xi-=2*text_width;
653   egbutt[EG_LOC].y2=yi;
654   lir_hline(egbutt[EG_LOC].x1,egbutt[EG_LOC].y1,egbutt[EG_LOC].x2,7);
655   if(kill_all_flag) return;
656   lir_hline(egbutt[EG_LOC].x1,egbutt[EG_LOC].y2,egbutt[EG_LOC].x2,7);
657   if(kill_all_flag) return;
658   lir_line(egbutt[EG_LOC].x1,egbutt[EG_LOC].y1,egbutt[EG_LOC].x1,
659                                                       egbutt[EG_LOC].y2,7);
660   if(kill_all_flag) return;
661   lir_line(egbutt[EG_LOC].x2,egbutt[EG_LOC].y1,egbutt[EG_LOC].x2,
662                                                       egbutt[EG_LOC].y2,7);
663   if(kill_all_flag) return;
664   yi+=2;
665   yj=yi+text_height/2;
666   egbutt[EG_DX].x1=xi;
667   egbutt[EG_DX].x2=xi+text_width*(EG_DX_CHARS+0.5);
668   egbutt[EG_DX].y1=yi;
669   yi+=text_height;
670   egbutt[EG_DX].y2=yi;
671   yi+=2;
672   if(dxflag != 0)
673     {
674     show_dx_location();
675     }
676   lir_hline(egbutt[EG_DX].x1,egbutt[EG_DX].y1,egbutt[EG_DX].x2,7);
677   if(kill_all_flag) return;
678   lir_hline(egbutt[EG_DX].x1,egbutt[EG_DX].y2,egbutt[EG_DX].x2,7);
679   if(kill_all_flag) return;
680   lir_line(egbutt[EG_DX].x1,egbutt[EG_DX].y1,egbutt[EG_DX].x1,
681                                                       egbutt[EG_DX].y2,7);
682   if(kill_all_flag) return;
683   lir_line(egbutt[EG_DX].x2,egbutt[EG_DX].y1,egbutt[EG_DX].x2,
684                                                       egbutt[EG_DX].y2,7);
685   if(kill_all_flag) return;
686   }
687 else
688   {
689   yj=eg.ybottom-text_height/2-1;
690   }
691 make_button(xj,yj,egbutt,EG_MINIMISE,'X');
692 resume_thread(THREAD_SCREEN);
693 make_modepar_file(GRAPHTYPE_EG);
694 }
695 
init_eme_graph(void)696 void init_eme_graph(void)
697 {
698 FILE *file;
699 int i, j, k;
700 char s[80];
701 // In case we process saved data from disk, the real time
702 // moon window is useless, just skip it.
703 if(savefile_parname[0] != 0)return;
704 s[0]=0;
705 if (read_modepar_file(GRAPHTYPE_EG) == 0)
706   {
707   eg.xleft=15*text_width;
708   eg.xright=17*text_width;
709   eg.ybottom=0.7*screen_height;
710   eg.ytop=eg.ybottom-1.5*text_height;
711   eg.minimise=1;
712   }
713 dxflag=0;
714 if(eme_flag == 2)
715   {
716   if(dx!=NULL)
717     {
718     lirerr(81975);
719     return;
720     }
721   file = fopen(eme_dxdata_filename, "r");
722   if(file == NULL)
723     {
724     lirerr(1130);
725     return;
726     }
727   k=fread(s,1,1,file);
728   j=0;
729   while(k!=0 && s[j] != 10 && s[j] != 13)
730     {
731     j++;
732     k=fread(&s[j],1,1,file);
733     if(j >= 80)
734       {
735 err1131:;
736       lirerr(1131);
737       return;
738       }
739     }
740   if(j == 0 || k == 0)goto err1131;
741   s[j]=0;
742   sscanf(s,"%d",&dx_no);
743   if(dx_no > MAX_DXCALLS)goto err1131;
744   dx=malloc(dx_no*sizeof(DXDATA));
745   if(dx == NULL)
746     {
747     lirerr(1132);
748     return;
749     }
750   i=0;
751 read_dx:;
752   k=fread(s,1,1,file);
753   j=0;
754   while(k!=0 && (s[j] == 10 || s[j] == 13)) k=fread(s,1,1,file);
755   if(k == 0)
756     {
757     lirerr(1131);
758     return;
759     }
760   while(k!=0 && s[j] != 10 && s[j] != 13)
761     {
762     j++;
763     k=fread(&s[j],1,1,file);
764     if(j >= 80)
765       {
766       lirerr(1131);
767       return;
768       }
769     }
770   if(j == 0 || k == 0)
771     {
772     lirerr(1131);
773     return;
774     }
775   s[j]=0;
776   for(k=0; k<CALLSIGN_CHARS; k++)dx[i].call[k]=s[k];
777   sscanf(&s[CALLSIGN_CHARS],"%f %f",&dx[i].lat,&dx[i].lon);
778   i++;
779   if(i<dx_no)goto read_dx;
780   fclose(file);
781   }
782 eme_graph_scro=no_of_scro;
783 make_eme_graph(FALSE);
784 no_of_scro++;
785 if(no_of_scro >= MAX_SCRO)lirerr(89);
786 }
787 
788 
dist_az(float * dist,float * azimuth,float lat,float lon,float dxlat,float dxlon)789 void dist_az(float *dist, float *azimuth, float lat, float lon,
790                                         float dxlat, float dxlon)
791 {
792 float sin_dxl, cos_dxl;
793 float sin_lat, cos_lat;
794 float t1,t2,t3;
795 cos_dxl=cos(PI_L*dxlat/180);
796 sin_dxl=sin(PI_L*dxlat/180);
797 cos_lat=cos(PI_L*lat/180);
798 sin_lat=sin(PI_L*lat/180);
799 t1=PI_L*(lon-dxlon)/180;
800 t2=sin_dxl*sin_lat+cos_dxl*cos_lat*cos(t1);
801 if(fabs(t2)>1)t2=1;
802 t2=atan2(sqrt(1-t2*t2),t2);
803 dist[0]=t2*6366;
804 if(dist[0] < 5)
805   {
806   dist[0]=0;
807   azimuth[0]=0;
808   return;
809   }
810 if(t1<-PI_L)t1+=2*PI_L;
811 if(t1> PI_L)t1-=2*PI_L;
812 t3=(sin_dxl-sin_lat*cos(t2))/(cos_lat*sin(t2));
813 if(fabs(t3) > 1)t3=1;
814 azimuth[0]=atan2(sqrt(1-t3*t3),t3);
815 if(t1 == 0)
816   {
817   if(dxlat < lat)
818     {
819     azimuth[0]=PI_L;
820     }
821   else
822     {
823     azimuth[0]=2*PI_L;
824     }
825   }
826 else
827   {
828   if(t1 > 0)azimuth[0]=2*PI_L-azimuth[0];
829   }
830 }
831 
check_latest_dx(void)832 void check_latest_dx(void)
833 {
834 char s[80];
835 int i, j, k;
836 float dist, az;
837 // Check that the latest call sign is not already in the data base.
838 for(i=0; i<dx_no; i++)
839   {
840   j=0;
841   while(j<CALLSIGN_CHARS && dx[i].call[j] == dx[dx_no].call[j])j++;
842   if(j==CALLSIGN_CHARS)
843     {
844 // We have located a duplicate call sign.
845 // Just ignore it in case the location is the same (or close to)
846 // If longitude or latitude is 1000 for one, use the other.
847     if(dx[i].lon == 1000)dx[i].lon=dx[dx_no].lon;
848     if(dx[i].lat == 1000)dx[i].lat=dx[dx_no].lat;
849     if(dx[dx_no].lon == 1000)dx[dx_no].lon=dx[i].lon;
850     if(dx[dx_no].lat == 1000)dx[dx_no].lat=dx[i].lat;
851     if(fabs(dx[i].lon-dx[dx_no].lon) > 0.1 ||
852        fabs(dx[i].lat-dx[dx_no].lat) > 0.1)
853       {
854       dist_az(&dist, &az, dx[i].lon,dx[i].lat,dx[dx_no].lon,dx[dx_no].lat);
855       if(dist > 200)
856         {
857         if(locerr_file == NULL)
858           {
859           locerr_file = fopen(eme_error_report_file, "w");
860           if(locerr_file == NULL)
861             {
862             lirerr(1133);
863             return;
864             }
865           }
866         for(k=0; k<CALLSIGN_CHARS; k++)s[k]=dx[i].call[k];
867         s[CALLSIGN_CHARS]=0;
868         fprintf(locerr_file,
869               "%s %d km   lon %.2f lat %.2f          [lon %.2f lat %.2f]\n",
870                                    s, (int)(dist), dx[i].lon, dx[i].lat,
871                                          dx[dx_no].lon, dx[dx_no].lat);
872         }
873       }
874     dx[i].lon=0.5*(dx[i].lon+dx[dx_no].lon);
875     dx[i].lat=0.5*(dx[i].lat+dx[dx_no].lat);
876     dx_no--;
877     }
878   }
879 }
880 
881 
882 
latlong_to_locator(float lon,float lat)883 void latlong_to_locator(float lon, float lat)
884 {
885 int i;
886 float t1,t2;
887 t1=lon;
888 t2=lat;
889 t1+=180;
890 i=t1/20;
891 t1=t1-20*i;
892 tmp_locator[0]=i+'A';
893 i=t1/2;
894 t1=t1-2*i;
895 tmp_locator[2]=i+'0';
896 t1*=12;
897 tmp_locator[4]=t1+'a';
898 t2+=90;
899 i=t2/10;
900 t2=t2-10*i;
901 tmp_locator[1]=i+'A';
902 i=t2;
903 tmp_locator[3]=i+'0';
904 t2-=i;
905 t2*=24;
906 tmp_locator[5]=t2+'a';
907 }
908 
909 
910 
911 
912 
913 
914 
locator_to_latlong(void)915 void locator_to_latlong(void)
916 {
917 int flg;
918 float lat, lon;
919 tmp_locator[0]=toupper(tmp_locator[0]);
920 tmp_locator[1]=toupper(tmp_locator[1]);
921 tmp_locator[4]=tolower(tmp_locator[4]);
922 tmp_locator[5]=tolower(tmp_locator[5]);
923 flg=0;
924 if(tmp_locator[0]<'A')
925   {
926   tmp_locator[0]='A';
927   flg=1;
928   }
929 if(tmp_locator[0]>'R')
930   {
931   tmp_locator[0]='R';
932   flg=1;
933   }
934 if(tmp_locator[1]<'A')
935   {
936   tmp_locator[1]='A';
937   flg=1;
938   }
939 if(tmp_locator[1]>'R')
940   {
941   tmp_locator[1]='R';
942   flg=1;
943   }
944 if(tmp_locator[2]<'0' || tmp_locator[2]>'9')flg=1;
945 if(tmp_locator[3]<'0' || tmp_locator[3]>'9')flg=1;
946 if(flg != 0)
947   {
948   tmp_locator[2]='4';
949   tmp_locator[3]='4';
950   tmp_locator[4]='a';
951   tmp_locator[5]='a';
952   }
953 if( tmp_locator[4]<'a' ||
954     tmp_locator[4]>'x' ||
955     tmp_locator[5]<'a' ||
956     tmp_locator[5]>'x' )
957   {
958   tmp_locator[4]='l';
959   tmp_locator[5]='l';
960   }
961 lon=tmp_locator[4]-'a'+0.5;
962 lon/=12;
963 lon-=180;
964 lon+=(tmp_locator[2]-'0')*2;
965 lon+=(tmp_locator[0]-'A')*20;
966 if(fabs(lon)>180.001)lon=0;
967 lat=tmp_locator[5]-'a'+0.5;
968 lat/=24;
969 lat-=90;
970 lat+=(tmp_locator[3]-'0');
971 lat+=(tmp_locator[1]-'A')*10;
972 if(fabs(lat)>90.001)lat=0;
973 tmp_lon=lon;
974 tmp_lat=lat;
975 }
976 
977 
978 // eme_flag=0  Nothing loaded. Load all data in case the first parameter =1
979 // eme_flag=1  Nothing loaded. Load all data unconditionally.
980 // eme_flag=2  Database loaded. Ask if it should be changed.
981 
read_eme_database(void)982 void read_eme_database(void)
983 {
984 int i, j, k, m;
985 char s[80];
986 FILE *own_file;
987 char *tmpbuf;
988 emeparm_float=(float*)((void*)(emeparm_int));
989 // Set flag to zero if file is empty
990 own_file = fopen(eme_own_info_filename, "r");
991 if(own_file == NULL)
992   {
993   eme_flag=0;
994   return;
995   }
996 // Allocate a lot of scratch memory.
997 // No processing arrays are allocated this early in program
998 // execution so there should be plenty of memory available.
999 tmpbuf=malloc(131072);
1000 for(i=0;i<4096; i++)tmpbuf[i]=0;
1001 if(tmpbuf == NULL)
1002   {
1003   lirerr(1075);
1004   return;
1005   }
1006 m=fread(tmpbuf,1,4096,own_file);
1007 fclose(own_file);
1008 if(m == 4096)
1009   {
1010 // Set flag to zero if the data is incorrect.
1011 daterr:;
1012   eme_flag=0;
1013   clear_screen();
1014   sprintf(s,"Data error in file %s",eme_own_info_filename);
1015   lir_text(5,5,s);
1016   lir_text(8,8,"PRESS ANY KEY");
1017   clear_await_keyboard();
1018   if(kill_all_flag) goto read_eme_x;
1019   process_current_lir_inkey();
1020   goto read_eme_x;
1021   }
1022 k=0;
1023 for(i=0; i<MAX_EMEPARM; i++)
1024   {
1025   while( (tmpbuf[k]==' ' || tmpbuf[k]== '\n') && k<m)k++;
1026   j=0;
1027   while(tmpbuf[k]== emeparm_text[i][j])
1028     {
1029     k++;
1030     j++;
1031     }
1032   if(emeparm_text[i][j] != 0)
1033     {
1034     tmpbuf=chk_free(tmpbuf);
1035     goto daterr;
1036     }
1037   while(tmpbuf[k]!='['&&k<m-1)k++;
1038   k++;
1039   if(i<2)
1040     {
1041     sscanf(&tmpbuf[k],"%d",&emeparm_int[i]);
1042     }
1043   else
1044     {
1045     sscanf(&tmpbuf[k],"%f",&emeparm_float[i]);
1046     }
1047 // If the first parameter is zero, do not read database now.
1048 // The user wants to save time, memory or screen space.
1049 // Just set flag and exit.
1050   if( eme_flag == 0 && i == 0 && emeparm_int[0] == 0)
1051     {
1052     eme_flag=1;
1053     goto read_eme_x;
1054     }
1055   while(tmpbuf[k]!='\n'&&k<m)k++;
1056   }
1057 latlong_to_locator(emeparm_float[3], emeparm_float[2]);
1058 eme_flag=2;
1059 read_eme_x:;
1060 free(tmpbuf);
1061 }
1062 
init_eme_database(void)1063 void init_eme_database(void)
1064 {
1065 int i, j, k, m, hr, min;
1066 char s[384];
1067 float t1;
1068 FILE *own_file, *dx_file;
1069 clear_screen();
1070 if(eme_flag != 0)
1071   {
1072   read_eme_database();
1073   if(kill_all_flag) return;
1074   if(eme_flag == 2)
1075     {
1076 begin:;
1077     clear_screen();
1078     lir_text(5,5,"Press M to update, F1 for help.");
1079     lir_text(5,6,"Any other key to use old data.");
1080     clear_await_keyboard();
1081     if(kill_all_flag) return;
1082     process_current_lir_inkey();
1083     if(kill_all_flag) return;
1084     if(lir_inkey == F1_KEY || lir_inkey == '!')
1085       {
1086       help_message(301);
1087       if(kill_all_flag) return;
1088       goto begin;
1089       }
1090     else
1091       {
1092       if(lir_inkey != 'M')return;
1093       }
1094     }
1095   }
1096 if(eme_flag == 0)
1097   {
1098   for(i=0; i<MAX_EMEPARM; i++)emeparm_int[i]=0;
1099   tmp_locator[0]=0;
1100   }
1101 new_lin:;
1102 tmp_locator[6]=0;
1103 clear_screen();
1104 sprintf(s,"Locator: %6s (%d to enter new)",tmp_locator,MAX_EMEPARM);
1105 lir_text(10,0,s);
1106 t1=lir_get_epoch_seconds();
1107 t1+=3600*emeparm_int[1];
1108 min=t1/60;
1109 hr=min/60;
1110 hr%=24;
1111 min%=60;
1112 sprintf(s,"UTC time is %d.%02d (set correction if needed)",hr,min);
1113 lir_text(10,1,s);
1114 for(i=0; i<MAX_EMEPARM; i++)
1115   {
1116   if(i<2)
1117     {
1118     sprintf(s,"%d  %s  [%d]",i,emeparm_text[i],emeparm_int[i]);
1119     }
1120   else
1121     {
1122     sprintf(s,"%d  %s  [%f]",i,emeparm_text[i],emeparm_float[i]);
1123     }
1124   lir_text(0,i+2,s);
1125   }
1126 lir_text(8,MAX_EMEPARM+5,"Enter line number to change.");
1127 lir_text(8,MAX_EMEPARM+6,"(9 to save and exit)");
1128 clear_await_keyboard();
1129 if(kill_all_flag) return;
1130 if(lir_inkey != '9')
1131   {
1132   i=lir_inkey-'0';
1133   if(i<0 || i>MAX_EMEPARM)goto new_lin;
1134   sprintf(s,"Enter new value for %s",emeparm_text[i]);
1135   lir_text(8,MAX_EMEPARM+8,s);
1136   j=0;
1137   while(s[j]!=0)j++;
1138   j=lir_get_filename(j+10,MAX_EMEPARM+8,s);
1139   if(kill_all_flag) return;
1140   if(j==0)goto new_lin;
1141   switch (i)
1142     {
1143     case 0:
1144     sscanf(s,"%d",&emeparm_int[0]);
1145     if(emeparm_int[0] != 0)emeparm_int[0]=1;
1146     break;
1147 
1148     case 1:
1149     sscanf(s,"%d",&emeparm_int[1]);
1150     if(abs(emeparm_int[1])>23)emeparm_int[1]=0;
1151     break;
1152 
1153     case 2:
1154     sscanf(s,"%f",&emeparm_float[2]);
1155     if(fabs(emeparm_float[2])>90)emeparm_float[2]=0;
1156     latlong_to_locator(emeparm_float[3], emeparm_float[2]);
1157     break;
1158 
1159     case 3:
1160     sscanf(s,"%f",&emeparm_float[3]);
1161     if(fabs(emeparm_float[3])>180)emeparm_float[3]=0;
1162     latlong_to_locator(emeparm_float[3], emeparm_float[2]);
1163     break;
1164 
1165     case 4:
1166     j=0;
1167     while(s[j]==0)j++;
1168     i=0;
1169     while(i<6)
1170       {
1171       tmp_locator[i]=s[j];
1172       i++;
1173       j++;
1174       if(s[j] == 0)
1175         {
1176         while(i<6)
1177           {
1178           tmp_locator[i]=' ';
1179           i++;
1180           }
1181         }
1182       }
1183     tmp_locator[6]=0;
1184     locator_to_latlong();
1185     emeparm_float[3]=tmp_lon;
1186     emeparm_float[2]=tmp_lat;
1187     break;
1188     }
1189   goto new_lin;
1190   }
1191 // No processing memory is yet allocated. Store station data
1192 // in a non-economic way that is easy to manipulate.
1193 dx=malloc(MAX_DXCALLS*sizeof(DXDATA));
1194 if(dx == NULL)
1195   {
1196   lirerr(1075);
1197   return;
1198   }
1199 dx_file = fopen(eme_allcalls_filename, "r");
1200 dx_no=0;
1201 clear_screen();
1202 locerr_file=NULL;
1203 if(dx_file != NULL)
1204   {
1205   k=fread(s,1,1,dx_file);
1206 allcall_a:;
1207   j=0;
1208   while(k!=0 && s[j] != 10 && s[j] != 13)
1209     {
1210     j++;
1211     k=fread(&s[j],1,1,dx_file);
1212     if(j >= CALLSIGN_CHARS)
1213       {
1214       lirerr(1122);
1215       return;
1216       }
1217     }
1218   if(j == 0)goto allcall_x;
1219   for(i=0; i<j; i++)dx[dx_no].call[i]=s[i];
1220   for(i=j; i<CALLSIGN_CHARS; i++)dx[dx_no].call[i]=' ';
1221   dx[dx_no].lon=1000;
1222   dx[dx_no].lat=1000;
1223   k=fread(s,1,1,dx_file);
1224   while(k!=0 && (s[0] == 10 || s[0] == 13))
1225     {
1226     k=fread(s,1,1,dx_file);
1227     }
1228   check_latest_dx();
1229   dx_no++;
1230   if(dx_no>=MAX_DXCALLS)
1231     {
1232     lirerr(1123);
1233     return;
1234     }
1235   if(k > 0)goto allcall_a;
1236 allcall_x:;
1237   fclose(dx_file);
1238   }
1239 dx_file = fopen(eme_emedta_filename, "r");
1240 if(dx_file != NULL)
1241   {
1242 emedta_a:;
1243 // Read this file with a fixed record length.
1244   k=fread(s,1,277,dx_file);
1245   if(k<277 || s[0]==92)goto emedta_x;
1246   j=0;
1247   while(j<11 && s[j]!=' ' && s[j]!='(' && s[j]<'a')j++;
1248   for(i=0; i<j; i++)dx[dx_no].call[i]=s[i];
1249   for(i=j; i<CALLSIGN_CHARS; i++)dx[dx_no].call[i]=' ';
1250   sscanf(&s[166],"%f",&dx[dx_no].lat);
1251   i=167;
1252   while(i<175 && toupper(s[i]) != 'S' && toupper(s[i]) != 'N')i++;
1253   if(i==175)
1254     {
1255     dx[dx_no].lat=1000;
1256     dx[dx_no].lon=1000;
1257     }
1258   else
1259     {
1260     if(toupper(s[i]) == 'S')
1261       {
1262       dx[dx_no].lat=-dx[dx_no].lat;
1263       }
1264     i++;
1265     sscanf(&s[i],"%f",&dx[dx_no].lon);
1266     while(i<181 && toupper(s[i]) != 'E' && toupper(s[i]) != 'W')i++;
1267     if(i==181)
1268       {
1269       dx[dx_no].lat=1000;
1270       dx[dx_no].lon=1000;
1271       }
1272     else
1273       {
1274       if(toupper(s[i]) == 'E')
1275         {
1276         dx[dx_no].lon=-dx[dx_no].lon;
1277         }
1278       }
1279     }
1280   check_latest_dx();
1281   dx_no++;
1282   if(dx_no>=MAX_DXCALLS)
1283     {
1284     lirerr(1123);
1285     return;
1286     }
1287   goto emedta_a;
1288 emedta_x:;
1289   fclose(dx_file);
1290   }
1291 dx_file = fopen(eme_dirskd_filename, "r");
1292 if(dx_file != NULL)
1293   {
1294   k=fread(s,1,1,dx_file);
1295 dirskd_a:;
1296   j=0;
1297   while(k!=0 && s[j] != ',')
1298     {
1299     j++;
1300     k=fread(&s[j],1,1,dx_file);
1301     if(j >= CALLSIGN_CHARS)
1302       {
1303       lirerr(1124);
1304       return;
1305       }
1306     }
1307   if(j == 0)goto dirskd_x;
1308   for(i=0; i<j; i++)dx[dx_no].call[i]=s[i];
1309   for(i=j; i<CALLSIGN_CHARS; i++)dx[dx_no].call[i]=' ';
1310   k=fread(s,1,1,dx_file);
1311   j=0;
1312   while(k!=0 && s[j] != ',')
1313     {
1314     j++;
1315     k=fread(&s[j],1,1,dx_file);
1316     if(j >= 10)
1317       {
1318       lirerr(1124);
1319       return;
1320       }
1321     }
1322   sscanf(s,"%f",&dx[dx_no].lat);
1323   while(j > 0 && toupper(s[j])!='S' && toupper(s[j])!='N')j--;
1324   if(toupper(s[j]) == 'S')
1325     {
1326     dx[dx_no].lat=-dx[dx_no].lat;
1327     }
1328   k=fread(s,1,1,dx_file);
1329   j=0;
1330   while(k!=0 && s[j] != ',')
1331     {
1332     j++;
1333     k=fread(&s[j],1,1,dx_file);
1334     if(j >= 10)
1335       {
1336       lirerr(1124);
1337       return;
1338       }
1339     }
1340   if(k == 0)goto dirskd_x;
1341   sscanf(s,"%f",&dx[dx_no].lon);
1342   while(j > 0 && toupper(s[j])!='E' && toupper(s[j])!='W')j--;
1343   if(toupper(s[j]) == 'E')
1344     {
1345     dx[dx_no].lon=-dx[dx_no].lon;
1346     }
1347   if(dx[dx_no].lon == 0 && dx[dx_no].lat == 0)
1348     {
1349     dx[dx_no].lat=1000;
1350     dx[dx_no].lon=1000;
1351     }
1352   check_latest_dx();
1353   dx_no++;
1354   if(dx_no>=MAX_DXCALLS)
1355     {
1356     lirerr(1123);
1357     return;
1358     }
1359   while(k!=0 && s[0] != 10 && s[0] != 13)
1360     {
1361     k=fread(s,1,1,dx_file);
1362     }
1363   while(k!=0 && (s[0] == 10 || s[0] == 13))
1364     {
1365     k=fread(s,1,1,dx_file);
1366     }
1367   if(k > 0)goto dirskd_a;
1368 dirskd_x:;
1369   fclose(dx_file);
1370   }
1371 dx_file = fopen(eme_call3_filename, "r");
1372 if(dx_file != NULL)
1373   {
1374   k=fread(s,1,1,dx_file);
1375   while(k!=0 && s[0]=='/')
1376     {
1377     while(k!=0 && s[0] != 10 && s[0] != 13)
1378       {
1379       k=fread(s,1,1,dx_file);
1380       }
1381     while(k!=0 && (s[0] == 10 || s[0] == 13))
1382       {
1383       k=fread(s,1,1,dx_file);
1384       }
1385     }
1386   if(k==0)goto call3_x;
1387 call3_a:;
1388   j=0;
1389   while(k!=0 && s[j] != ',')
1390     {
1391     j++;
1392     k=fread(&s[j],1,1,dx_file);
1393     if(j >= CALLSIGN_CHARS)
1394       {
1395       clear_screen();
1396       s[j+1]=0;
1397       lir_text(0,0,"This line is in error (field too long)");
1398       lir_text(0,2,s);
1399       lir_text(0,4,press_any_key);
1400       await_keyboard();
1401       lirerr(1230);
1402       return;
1403       }
1404     }
1405   if(j == 0)goto call3_x;
1406   if(j==6)
1407     {
1408     i=0;
1409     while(s[i]=='Z')i++;
1410     if(i == 6)goto call3_x;
1411     }
1412   for(i=0; i<j; i++)dx[dx_no].call[i]=s[i];
1413   for(i=j; i<CALLSIGN_CHARS; i++)dx[dx_no].call[i]=' ';
1414   k=fread(s,1,1,dx_file);
1415   j=0;
1416   while(k!=0 && s[j] != ',')
1417     {
1418     j++;
1419     k=fread(&s[j],1,1,dx_file);
1420     if(j > 6)
1421       {
1422       clear_screen();
1423       dx[dx_no].call[CALLSIGN_CHARS-1]=0;
1424       s[j+1]=0;
1425       lir_text(0,0,dx[dx_no].call);
1426       lir_text(0,2,"field too long");
1427       lir_text(0,4,s);
1428       lir_text(0,6,press_any_key);
1429       await_keyboard();
1430       lirerr(1230);
1431       return;
1432       }
1433     }
1434   for(i=0; i<j; i++)tmp_locator[i]=s[i];
1435   for(i=j; i<6; i++)tmp_locator[i]=' ';
1436   locator_to_latlong();
1437   dx[dx_no].lat=tmp_lat;
1438   dx[dx_no].lon=-tmp_lon;
1439 // locator to lat/lon
1440 //  sscanf(s,"%f",&dx[dx_no].lat);
1441   if(dx[dx_no].lon == 0 && dx[dx_no].lat == 0)
1442     {
1443     dx[dx_no].lat=1000;
1444     dx[dx_no].lon=1000;
1445     }
1446   check_latest_dx();
1447   dx_no++;
1448   if(dx_no>=MAX_DXCALLS)
1449     {
1450     lirerr(1123);
1451     return;
1452     }
1453   while(k!=0 && s[0] != 10 && s[0] != 13)
1454     {
1455     k=fread(s,1,1,dx_file);
1456     }
1457   while(k!=0 && (s[0] == 10 || s[0] == 13))
1458     {
1459     k=fread(s,1,1,dx_file);
1460     }
1461   if(k > 0)goto call3_a;
1462 call3_x:;
1463   fclose(dx_file);
1464   }
1465 if(locerr_file != NULL)
1466   {
1467   fclose(locerr_file);
1468   }
1469 // Sort the dx data in alphabetical order.
1470 if(dx_no >= 2)
1471   {
1472   m=dx_no-1;
1473   for(i=0; i<m; i++)
1474     {
1475     for(k=i+1; k<dx_no; k++)
1476       {
1477       for(j=0; j<CALLSIGN_CHARS; j++)
1478         {
1479         if(dx[i].call[j] > dx[k].call[j])goto swap;
1480         if(dx[i].call[j] < dx[k].call[j])goto noswap;
1481         }
1482       lirerr(1129);
1483       return;
1484 swap:;
1485       for(j=0; j<CALLSIGN_CHARS; j++)
1486         {
1487         s[0]=dx[i].call[j];
1488         dx[i].call[j]=dx[k].call[j];
1489         dx[k].call[j]=s[0];
1490         }
1491       t1=dx[i].lat;
1492       dx[i].lat=dx[k].lat;
1493       dx[k].lat=t1;
1494       t1=dx[i].lon;
1495       dx[i].lon=dx[k].lon;
1496       dx[k].lon=t1;
1497 noswap:;
1498       }
1499     }
1500   }
1501 // Store call sign and geographical position in linrad's own format:
1502 dx_file = fopen(eme_dxdata_filename, "w");
1503 if(dx_file == NULL)
1504   {
1505   lirerr(1128);
1506   return;
1507   }
1508 else
1509   {
1510   fprintf(dx_file,"%d\n",dx_no);
1511   for(i=0; i<dx_no; i++)
1512     {
1513     for(j=0; j<CALLSIGN_CHARS; j++)s[j]=dx[i].call[j];
1514     s[CALLSIGN_CHARS]=0;
1515     fprintf(dx_file,"%s  %.2f %.2f\n",s,dx[i].lat,dx[i].lon);
1516     }
1517   }
1518 fprintf(dx_file,"%d\n",dx_no);
1519 fclose(dx_file);
1520 own_file = fopen(eme_own_info_filename, "w");
1521 if(own_file == NULL)
1522   {
1523   lirerr(1121);
1524   return;
1525   }
1526 for(i=0; i<2; i++)
1527   {
1528   fprintf(own_file,"%s [%d]\n",emeparm_text[i],emeparm_int[i]);
1529   }
1530 for(i=2; i<MAX_EMEPARM; i++)
1531   {
1532   fprintf(own_file,"%s [%f]\n",emeparm_text[i],emeparm_float[i]);
1533   }
1534 fclose(own_file);
1535 free(dx);
1536 dx=NULL;
1537 }
1538 
1539 
to_first_period(double x)1540 double to_first_period(double x)
1541 {
1542 return (x-(int)(x))*2*PI_L;
1543 }
1544 
1545 
calculate_moon_data()1546 void calculate_moon_data()
1547 {
1548 char s[80];
1549 int k, day;
1550 float dec,dec1,ra,pol,zd,sinref;
1551 float sdtim,gha,uha;
1552 float uhadx;
1553 float elsin,elcos,el,azsin,azcos,az;
1554 float elsindx,elcosdx,eldx,azsindx,azcosdx,azdx,poldx;
1555 double dt1, timofday, a, tottim, f1, f2, f3, f4, dlon, dlat;
1556 double f5,f6,f7;
1557 if(suggested_calls_counter > 1 || eg_move_flag !=0 || eme_flag != 2)return;
1558 // lir_get_epoch_seconds is the number of seconds since 1970
1559 dt1=lir_get_epoch_seconds();
1560 tottim=(dt1-946731602)/(24*3600);
1561 dt1+=3600*emeparm_int[1];
1562 day=dt1/(24*3600)+7305;
1563 timofday=dt1/(24*3600);
1564 timofday-=(int)(timofday);
1565 a=.0657098232*day;
1566 sdtim=6.67170278+(a-24*(int)(a/24))+1.0027379093*timofday*24;
1567 f1=to_first_period(.374897+.03629164709*tottim);
1568 f2=to_first_period(.259091+.0367481952*tottim);
1569 f3=to_first_period(.827362+.03386319198*tottim);
1570 f4=to_first_period(.347343-.00014709391*tottim);
1571 f5=to_first_period(.779072+.00273790931*tottim);
1572 f6=to_first_period(.993126+.0027377785*tottim);
1573 f7=to_first_period(.505498+.00445046867*tottim);
1574 dlon=22640*sin(f1)
1575     -4586*sin(f1-2*f3)
1576     +2370*sin(2*f3)
1577     +769*sin(2*f1)
1578     -668*sin(f6)
1579     -412*sin(2*f2)
1580     -212*sin(2*f1-2*f3)
1581     -206*sin(f1-2*f3+f6)
1582     +192*sin(f1+2*f3)
1583     +165*sin(2*f3-f6)+
1584     148*sin(f1-f6)
1585     -125*sin(f3)
1586     -110*sin(f1+f6)
1587     -55*sin(2*f2-2*f3)
1588     -45*sin(f1+2*f2)
1589     +40*sin(f1-2*f2)
1590     -38*sin(f1-4*f3)
1591     +36*sin(3*f1)
1592     -31*sin(2*f1-4*f3)
1593     +28*sin(f1-2*f3-f6)
1594     -24*sin(2*f3+f6)
1595     +19*sin(f1-f3)
1596     +18*sin(f3+f6)
1597     +15*sin(f1+2*f3-f6)
1598     +14*(sin(2*f1+2*f3)+sin(4*f3))
1599     -13*sin(3*f1-2*f3)
1600     -11*sin(f1+16*f5-18*f7)
1601     +10*sin(2*f1-f6)
1602     +9*(sin(f1-2*f2-2*f3)+cos(f1+16*f5-18*f7)-sin(2*f1-2*f3+f6))
1603     +8*(sin(2*f3-2*f6)-sin(f1+f3)-sin(2*f1+f6))
1604     +7*(sin(f4)-sin(2*f6)-sin(f1-2*f3+2*f6))
1605     -6*(sin(f1-2*f2+2*f3)+sin(2*f2+2*f3))
1606     +4*(tottim/36525+1)*(cos(f1+16*f5-18*f7)+sin(f1+16*f5-18*f7))
1607     -4*(sin(f1-4*f3+f6)+sin(2*f1+2*f2))
1608     +3*(sin(f1-3*f3)+sin(f1-2*f6)+sin(f1-2*f3-2*f6)-
1609                                      sin(f1+2*f3+f6)-sin(2*f1-4*f3+f6))
1610     +2*(sin(f1+4*f3)+sin(4*f1)+sin(4*f3-f6)+sin(2*f1-f3)-
1611                                      sin(2*f1-2*f3-f6)-sin(2*f2-2*f3+f6));
1612 dlon=2*PI_L*(dlon/1296000+.606434+.03660110129*tottim);
1613 dlat=  18461*sin(f2)
1614       +1010*sin(f1+f2)
1615       +1000*sin(f1-f2)
1616       -624*sin(f2-2*f3)
1617       -199*sin(f1-f2-2*f3)
1618       -167*sin(f1+f2-2*f3)
1619       +117*sin(f2+2*f3)
1620       +62*sin(2*f1+f2)
1621       +33*sin(f1-f2+2*f3)
1622       +32*sin(2*f1-f2)
1623       -30*sin(f2-2*f3+f6)
1624       -16*sin(2*f1+f2-2*f3)
1625       +15*sin(f1+f2+2*f3)
1626       +12*sin(f2-2*f3-f6)
1627       -9*sin(f1-f2-2*f3+f6)
1628       +8*(sin(f2+2*f3-f6)-sin(f2+f4))
1629       +7*(sin(f1+f2-f6)-sin(f1+f2-2*f3+f6)-sin(f1+f2-4*f3))
1630       +6*(sin(f1-f2-f6)-sin(f2+f6)-sin(3*f2))
1631       +5*(sin(f2-f6)+sin( f2-f3)-sin(f2+f3)-sin(f1+f2+f6)-sin(f1-f2+f6))
1632       +4*(sin(3*f1+f2)-sin(f2-4*f3))
1633       +3*(sin(f1-3*f2)-sin(f1-f2-4*f3))
1634       +2*(sin(2*f1-f2+2*f3)+sin(f1-f2+2*f3-f6)+sin(2*f1-f2-2*f3)+
1635                             sin(3*f1-f2)-sin(2*f1-f2-4*f3)-sin(3*f2-2*f3));
1636 dlat=2*PI_L*dlat/1296000;
1637 dec1=cos(dlat)*sin(dlon)*.397821+sin(dlat)*.917463;
1638 dec=asin(dec1);
1639 ra=atan2(cos(dlat)*sin(dlon)*.917463-sin(dlat)*.397821, cos(dlat)*cos(dlon));
1640 if(ra < 0)ra+=2*PI_L;
1641 gha=2*PI_L*(sdtim+.00029*sin(0.211417-0.00092422*(day+timofday)))/24-ra;
1642 uha=-RAD*emeparm_float[3]-gha;
1643 elsin=cos_laref*cos(uha)*cos(dec)+dec1*sin_laref;
1644 elcos=sqrt(1-elsin*elsin);
1645 el=atan2(elsin,elcos);
1646 azcos=dec1/(cos_laref*elcos)-(sin_laref/cos_laref)*(elsin/elcos);
1647 azsin=sin_laref*dec1+cos_laref*cos(dec)*cos(uha);
1648 azsin=sin(uha)*cos(dec)/sqrt(1-azsin*azsin);
1649 az=atan2(azsin,azcos);
1650 if(az < 0)az+=2*PI_L;
1651 el-=atan2(cos(el),60.4-sin(el));
1652 moon_az=az/RAD;
1653 moon_el=el/RAD;
1654 sprintf(s,"az=%.1f el=%.1f      ",az/RAD,el/RAD);
1655 s[EGH-1]=0;
1656 lir_pixwrite(eg.xleft+text_width/2,eg.ytop+2,s);
1657 if(dxflag != 0)
1658   {
1659   uhadx=-RAD*dx_lon-gha;
1660   elsindx=cos_dxlat*cos(uhadx)*cos(dec)+dec1*sin_dxlat;
1661   elcosdx=sqrt(1-elsindx*elsindx);
1662   eldx=atan2(elsindx,elcosdx);
1663   azcosdx=dec1/(cos_dxlat*elcosdx)-(sin_dxlat/cos_dxlat)*(elsindx/elcosdx);
1664   azsindx=sin_dxlat*dec1+cos_dxlat*cos(dec)*cos(uhadx);
1665   azsindx=sin(uhadx)*cos(dec)/sqrt(1-azsindx*azsindx);
1666   azdx=atan2(azsindx,azcosdx);
1667   if(azdx < 0)azdx+=2*PI_L;
1668   eldx-=atan2(cos(eldx),60.4-sin(eldx));
1669   if(eldx > 0 && eldx < .27925)
1670     {
1671     zd=PI_L/2-eldx;
1672     sinref=.9986047*sin(.9967614*zd);
1673     sinref=atan2(sinref,sqrt(1-sinref*sinref));
1674     eldx-=0.00104329*(196.5411*(zd-sinref)-.6393802*zd);
1675     }
1676   settextcolor(10);
1677   sprintf(s,"az=%.1f el=%.1f      ",azdx/RAD,eldx/RAD);
1678   s[EGH-1]=0;
1679   lir_pixwrite(eg.xleft+text_width/2,eg.ytop+1+text_height,s);
1680   settextcolor(7);
1681   if(fabs(cos_laref*azsin) <  0.0001*
1682                            fabs(sin_laref*cos(el)-cos_laref*cos(az)*sin(el)))
1683     {
1684     pol=PI_L/2;
1685     }
1686   else
1687     {
1688     pol=(sin_laref*cos(el)-cos_laref*cos(az)*sin(el))/(cos_laref*azsin);
1689     pol=atan(pol);
1690     }
1691   if(fabs(cos_dxlat*azsindx) < 0.0001*
1692                      fabs(sin_dxlat*cos(eldx)-cos_dxlat*cos(azdx)*sin(eldx)))
1693     {
1694     poldx=PI_L/2;
1695     }
1696   else
1697     {
1698     poldx=(sin_dxlat*cos(eldx)-cos_dxlat*cos(azdx)*sin(eldx))/
1699                                                       (cos_dxlat*azsindx);
1700     poldx=atan(poldx);
1701     }
1702   k=2*(poldx-pol)/RAD+pg_pol_angle;
1703   while(k<0)k+=180;
1704   while(k>180)k-=180;
1705   sprintf(s,"Tx pol %d   ",k);
1706   lir_pixwrite(eg.xleft+1.5*text_width,egbutt[EG_DX].y2+text_height/2,s);
1707   }
1708 users_eme();
1709 }
1710