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 <string.h>
25 #include "globdef.h"
26 #include "uidef.h"
27 #include "screendef.h"
28 #include "vernr.h"
29 #include "rusage.h"
30 #include "thrdef.h"
31 
32 #define PGW (7*text_width)
33 #define PGH (PGW+3.5*text_height)
34 void make_pol_graph(int clear_old);
35 int pg_old_y1;
36 int pg_old_y2;
37 int pg_old_x1;
38 int pg_old_x2;
39 
40 int pol_graph_scro;
41 
42 
check_pg_borders(void)43 void check_pg_borders(void)
44 {
45 current_graph_minh=PGH;
46 current_graph_minw=PGW;
47 check_graph_placement((void*)(&pg));
48 set_graph_minwidth((void*)(&pg));
49 }
50 
help_on_pol_graph(void)51 void help_on_pol_graph(void)
52 {
53 int msg_no;
54 int event_no;
55 // Set msg invalid in case we are not in any select area.
56 msg_no=-1;
57 for(event_no=0; event_no<MAX_PGBUTT; event_no++)
58   {
59   if( pgbutt[event_no].x1 <= mouse_x &&
60       pgbutt[event_no].x2 >= mouse_x &&
61       pgbutt[event_no].y1 <= mouse_y &&
62       pgbutt[event_no].y2 >= mouse_y)
63     {
64     switch (event_no)
65       {
66       case PG_TOP:
67       case PG_BOTTOM:
68       case PG_LEFT:
69       case PG_RIGHT:
70       msg_no=101;
71       break;
72 
73       case PG_AUTO:
74       msg_no=54;
75       break;
76 
77       case PG_ANGLE:
78       msg_no=55;
79       break;
80 
81       case PG_CIRC:
82       msg_no=56;
83       break;
84 
85       case PG_AVGNUM:
86       msg_no=57;
87       break;
88       }
89     }
90   }
91 help_message(msg_no);
92 }
93 
94 
95 
96 
mouse_continue_pol_graph(void)97 void mouse_continue_pol_graph(void)
98 {
99 int i, j;
100 float t1,t2;
101 switch (mouse_active_flag-1)
102   {
103   case PG_TOP:
104   if(pg.ytop!=mouse_y)goto pgm;
105   break;
106 
107   case PG_BOTTOM:
108   if(pg.ybottom!=mouse_y)goto pgm;
109   break;
110 
111   case PG_LEFT:
112   if(pg.xleft!=mouse_x)goto pgm;
113   break;
114 
115   case PG_RIGHT:
116   if(pg.xright==mouse_x)break;
117 pgm:;
118   pause_screen_and_hide_mouse();
119   graph_borders((void*)&pg,0);
120   if(pg_oldx==-10000)
121     {
122     pg_oldx=mouse_x;
123     pg_oldy=mouse_y;
124     }
125   else
126     {
127     i=mouse_x-pg_oldx;
128     j=mouse_y-pg_oldy;
129     pg_oldx=mouse_x;
130     pg_oldy=mouse_y;
131     pg.ytop+=j;
132     pg.ybottom+=j;
133     pg.xleft+=i;
134     pg.xright+=i;
135     check_pg_borders();
136     }
137   graph_borders((void*)&pg,15);
138   resume_thread(THREAD_SCREEN);
139 
140   break;
141 
142 
143   default:
144   goto await_release;
145   }
146 if(leftpressed == BUTTON_RELEASED)goto finish;
147 return;
148 await_release:;
149 if(leftpressed != BUTTON_RELEASED) return;
150 switch (mouse_active_flag-1)
151   {
152   case PG_AUTO:
153   pg.adapt^=1;
154   break;
155 
156   case PG_ANGLE:
157   t1=mouse_x-pg_x0;
158   t2=mouse_y-pg_y0;
159   if(fabs(t1)+fabs(t2)>0)
160     {
161     t1=atan2(-t2,t1)+PI_L*pg.angle/180;
162     }
163   else
164     {
165     t1=0;
166     }
167 // Polarization plane is periodic in 180 degrees.
168 // Place angle in the interval 0 to 180 degrees so sin(angle) is
169 // always positive.
170   while(t1 < 0)t1+=PI_L;
171   if(t1>=PI_L)t1-=PI_L;
172   pg.c1=cos(t1);
173   t2=sin(t1);
174   pg.c2=sin(t1)*cos(pg_b);
175   pg.c3=sin(t1)*sin(pg_b);
176   break;
177 
178   case PG_CIRC:
179   pg_b=1.2*PI_L*(mouse_x-pg_x0)/(pgbutt[PG_CIRC].x2-pgbutt[PG_CIRC].x1);
180   if(pg_b > 0.499*PI_L)pg_b= 0.499*PI_L;
181   if(pg_b < -0.499*PI_L)pg_b=-0.499*PI_L;
182   if(pg.c1 == 0)pg.c1=0.0001;
183   t2=sqrt(1-pg.c1*pg.c1);
184   if(pg.c2 < 0)t2*=-1;
185   if(t2 == 0)t2=0.0001;
186   pg.c2=t2*cos(pg_b);
187   pg.c3=t2*sin(pg_b);
188   break;
189 
190   case PG_AVGNUM:
191   pg.avg=mouse_x-pg_x0;
192   break;
193   }
194 finish:;
195 leftpressed=BUTTON_IDLE;
196 mouse_active_flag=0;
197 make_pol_graph(TRUE);
198 if(genparm[SECOND_FFT_ENABLE] != 0)new_hg_pol();
199 pg_oldx=-10000;
200 }
201 
mouse_on_pol_graph(void)202 void mouse_on_pol_graph(void)
203 {
204 int event_no;
205 // First find out is we are on a button or border line.
206 for(event_no=0; event_no<MAX_PGBUTT; event_no++)
207   {
208   if( pgbutt[event_no].x1 <= mouse_x &&
209       pgbutt[event_no].x2 >= mouse_x &&
210       pgbutt[event_no].y1 <= mouse_y &&
211       pgbutt[event_no].y2 >= mouse_y)
212     {
213     pg_old_y1=pg.ytop;
214     pg_old_y2=pg.ybottom;
215     pg_old_x1=pg.xleft;
216     pg_old_x2=pg.xright;
217     mouse_active_flag=1+event_no;
218     current_mouse_activity=mouse_continue_pol_graph;
219     return;
220     }
221   }
222 // Not button or border.
223 // Do nothing.
224 current_mouse_activity=mouse_nothing;
225 mouse_active_flag=1;
226 }
227 
228 
make_pol_graph(int clear_old)229 void make_pol_graph(int clear_old)
230 {
231 int i, j;
232 char *adafix[]={"Adapt","Fixed"};
233 pause_thread(THREAD_SCREEN);
234 if(clear_old)
235   {
236   hide_mouse(pg_old_x1,pg_old_x2,pg_old_y1,pg_old_y2);
237   lir_fillbox(pg_old_x1,pg_old_y1,pg_old_x2-pg_old_x1+1,
238                                                     pg_old_y2-pg_old_y1+1,0);
239   }
240 check_pg_borders();
241 clear_button(pgbutt, MAX_PGBUTT);
242 hide_mouse(pg.xleft,pg.xright,pg.ytop,pg.ybottom);
243 scro[pol_graph_scro].no=POL_GRAPH;
244 scro[pol_graph_scro].x1=pg.xleft;
245 scro[pol_graph_scro].x2=pg.xright;
246 scro[pol_graph_scro].y1=pg.ytop;
247 scro[pol_graph_scro].y2=pg.ybottom;
248 pgbutt[PG_LEFT].x1=pg.xleft;
249 pgbutt[PG_LEFT].x2=pg.xleft+2;
250 pgbutt[PG_LEFT].y1=pg.ytop;
251 pgbutt[PG_LEFT].y2=pg.ybottom;
252 pgbutt[PG_RIGHT].x1=pg.xright-2;
253 pgbutt[PG_RIGHT].x2=pg.xright;
254 pgbutt[PG_RIGHT].y1=pg.ytop;
255 pgbutt[PG_RIGHT].y2=pg.ybottom;
256 pgbutt[PG_TOP].x1=pg.xleft;
257 pgbutt[PG_TOP].x2=pg.xright;
258 pgbutt[PG_TOP].y1=pg.ytop;
259 pgbutt[PG_TOP].y2=pg.ytop+2;
260 pgbutt[PG_BOTTOM].x1=pg.xleft;
261 pgbutt[PG_BOTTOM].x2=pg.xright;
262 pgbutt[PG_BOTTOM].y1=pg.ybottom-2;
263 pgbutt[PG_BOTTOM].y2=pg.ybottom;
264 // Draw the border lines
265 graph_borders((void*)&pg,7);
266 settextcolor(7);
267 pg_oldx=-10000;
268 // Place the Adapt/Fixed button in lower left corner
269 i=1+text_width/2;
270 pgbutt[PG_AUTO].x1=pg.xleft+i;
271 pgbutt[PG_AUTO].x2=pgbutt[PG_AUTO].x1+5*text_width+i;
272 pgbutt[PG_AUTO].y2=pg.ybottom-2;
273 pgbutt[PG_AUTO].y1=pgbutt[PG_AUTO].y2-text_width-i;
274 lir_pixwrite(pgbutt[PG_AUTO].x1+i,pgbutt[PG_AUTO].y1+i/2,adafix[pg.adapt]);
275 if(kill_all_flag) return;
276 lir_hline(pgbutt[PG_AUTO].x1,pgbutt[PG_AUTO].y1,pgbutt[PG_AUTO].x2,7);
277 if(kill_all_flag) return;
278 lir_hline(pgbutt[PG_AUTO].x1,pgbutt[PG_AUTO].y2,pgbutt[PG_AUTO].x2,7);
279 if(kill_all_flag) return;
280 lir_line(pgbutt[PG_AUTO].x1,pgbutt[PG_AUTO].y1,
281         pgbutt[PG_AUTO].x1,pgbutt[PG_AUTO].y2,7);
282 if(kill_all_flag) return;
283 lir_line(pgbutt[PG_AUTO].x2,pgbutt[PG_AUTO].y1,
284         pgbutt[PG_AUTO].x2,pgbutt[PG_AUTO].y2,7);
285 if(kill_all_flag) return;
286 // Control for major axis angle
287 pg_x0=(pg.xleft+pg.xright)/2;
288 i=pg.xright-pg.xleft-2;
289 j=pg.ybottom-pg.ytop-3*text_height;
290 if(i>j)i=j;
291 i/=2;
292 pg_y0=pg.ytop+i+2;
293 pgbutt[PG_ANGLE].x1=pg_x0-i;
294 pgbutt[PG_ANGLE].x2=pg_x0+i;
295 pgbutt[PG_ANGLE].y1=pg_y0-i;
296 pgbutt[PG_ANGLE].y2=pg_y0+i;
297 // Control for interchannel phase (circular / linear)
298 pgbutt[PG_CIRC].x1=pgbutt[PG_ANGLE].x1;
299 pgbutt[PG_CIRC].x2=pgbutt[PG_ANGLE].x2;
300 pgbutt[PG_CIRC].y1=pgbutt[PG_ANGLE].y2+text_height/2;
301 pgbutt[PG_CIRC].y2=pgbutt[PG_CIRC].y1+text_height/2;
302 // Control for averaging parameter.
303 pgbutt[PG_AVGNUM].x1=pg_x0+1;
304 pgbutt[PG_AVGNUM].x2=pgbutt[PG_ANGLE].x2;
305 pgbutt[PG_AVGNUM].y1=pgbutt[PG_CIRC].y2+1;
306 pgbutt[PG_AVGNUM].y2=pgbutt[PG_CIRC].y2+text_height-2;
307 if(pg.adapt == 0)
308   {
309   i=pgbutt[PG_AVGNUM].x2-pgbutt[PG_AVGNUM].x1-1;
310   if(pg.avg>i)pg.avg=i;
311   i=pgbutt[PG_AVGNUM].x1+pg.avg;
312   lir_fillbox(pgbutt[PG_AVGNUM].x1,pgbutt[PG_AVGNUM].y1,
313              pgbutt[PG_AVGNUM].x2-pgbutt[PG_AVGNUM].x1,
314              pgbutt[PG_AVGNUM].y2-pgbutt[PG_AVGNUM].y1,PC_CONTROL_COLOR);
315   lir_line(i,pgbutt[PG_AVGNUM].y1,i,pgbutt[PG_AVGNUM].y2,15);
316   }
317 dpg.xleft=pg.xleft;
318 dpg.xright=pg.xright;
319 dpg.ytop=pg.ytop;
320 dpg.ybottom=pg.ybottom;
321 make_modepar_file(GRAPHTYPE_PG);
322 resume_thread(THREAD_SCREEN);
323 show_pol_time=current_time();
324 sc[SC_SHOW_POL]++;
325 }
326 
327 
select_pol_default(void)328 void select_pol_default(void)
329 {
330 char s[80];
331 int iang,isign,iaut,istrt;
332 float t1;
333 char sgn[]={'+','-'};
334 char *amode[]={"Auto","Man"};
335 char sta[]={'H','V'};
336 iang=dpg.angle;
337 isign=0;
338 if(iang > 135)
339   {
340   iang-=180;
341   isign=1;
342   }
343 iaut=dpg.adapt;
344 istrt=0;
345 t1=180*atan2(dpg.c2,dpg.c1)/PI_L;
346 t1=fabs(t1-dpg.angle);
347 if(t1 > 180)t1-=360;
348 if( fabs(t1) > 45)
349   {
350   istrt=1;
351   }
352 pol_menu:;
353 clear_screen();
354 settextcolor(14);
355 lir_text(5,5,"INIT POLARISATION PARAMETERS FOR TWO CHANNEL RADIO");
356 settextcolor(7);
357 sprintf(s,"A => Angle for channel 1 (0=Hor, 90=vert)  %d",iang);
358 lir_text(5,8,s);
359 sprintf(s,"B => Toggle sign for channel 2             %c",sgn[isign]);
360 lir_text(5,9,s);
361 sprintf(s,"C => Toggle mode                           %s",amode[iaut]);
362 lir_text(5,10,s);
363 sprintf(s,"D => Toggle start polarization             %c",sta[istrt]);
364 lir_text(5,11,s);
365 lir_text(5,13,"S => Save to disk and exit");
366 await_processed_keyboard();
367 if(kill_all_flag) return;
368 switch (lir_inkey)
369   {
370   case 'A':
371   lir_text(10,16,"Angle:");
372   iang=lir_get_integer(16, 16, 4, 0, 90);
373   if(kill_all_flag) return;
374   break;
375 
376   case 'B':
377   isign^=1;
378   break;
379 
380   case 'C':
381   iaut^=1;
382   break;
383 
384   case 'D':
385   istrt^=1;
386   break;
387 
388   case 'S':
389   dpg.angle=iang;
390   if(isign != 0)dpg.angle+=180;
391   dpg.adapt=iaut;
392 // Get polarization coefficients for start polarization
393   t1=dpg.angle;
394   if(istrt != 0)t1+=90;
395   t1*=PI_L/180;
396   dpg.c1=cos(t1);
397   dpg.c2=sin(t1);
398   dpg.c3=0;
399   dpg.check=PG_VERNR;
400   make_modepar_file(GRAPHTYPE_PG);
401   return;
402   }
403 goto pol_menu;
404 }
405 
406 
init_pol_graph(void)407 void init_pol_graph(void)
408 {
409 float t1;
410 if (read_modepar_file(GRAPHTYPE_PG) == 0)
411   {
412 pg_default:;
413   dpg.xleft=27*text_width;
414   dpg.xright=dpg.xleft+PGW;
415   dpg.ytop=0.72*screen_height;
416   dpg.ybottom=dpg.ytop+PGH;
417   lir_status=LIR_NEW_POL;
418   dpg.avg=8;
419   dpg.angle=0;
420   dpg.adapt=0;
421   dpg.c1=1;
422   dpg.c2=0;
423   dpg.c3=0;
424   return;
425   }
426 if(dpg.check != PG_VERNR)goto pg_default;
427 if(dpg.avg < 1 || dpg.avg > 1000)goto pg_default;
428 t1=dpg.c1*dpg.c1+dpg.c2*dpg.c2+dpg.c3*dpg.c3;
429 if(t1 < 0.98 || t1 > 1.02)goto pg_default;
430 if(dpg.angle < 0 || dpg.angle > 180.00001)goto pg_default;
431 if( (dpg.adapt&-2) != 0)goto pg_default;
432 pg=dpg;
433 pg_oldx=-10000;
434 pg_flag=1;
435 pol_graph_scro=no_of_scro;
436 make_pol_graph(FALSE);
437 no_of_scro++;
438 if(no_of_scro >= MAX_SCRO)lirerr(89);
439 }
440