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