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