1 /***************************************************************************
2 radar.cpp - description
3 -------------------
4 begin : Fri August 2 2001
5 copyright : (C) 2001 by Rick McDaniel
6 email : rickeym@swbell.net
7 $Id: radar.cpp,v 1.16 2003/05/17 22:25:34 mbridak Exp $
8 ***************************************************************************/
9
10 /***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License. *
15 * . *
16 * *
17 ***************************************************************************/
18 #include <string>
19 #include "math.h"
20 #include "SDL/SDL.h"
21 #include "SDL/SDL_image.h"
22 #include "SDL/SDL_thread.h"
23 #include "dfont.h"
24 #include "files.h"
25 #include "submarine.h"
26
27 //VENZON: need rotozoom now
28 #include "SDL_rotozoom.h"
29
30 // rdm windows
31 #include <iostream>
32 using namespace std;
33
34 #include "radar.h"
35
36 //VENZON: I've replaced all occurrances of 10*tick with tick, since I upped
37 //the resolution by a factor of 10
38
Radar(Submarine * temp)39 Radar::Radar(Submarine *temp): Subs(temp)
40 {
41 // Default values: Mast down, RangeRing off, RangeScale = 10
42
43 MastHeight = 59; // Max height of radar mast
44 Mast = false;
45 RangeRing = 0;
46 RangeScale = 10;
47 rangescale10 = true;
48 rangescale20 = false;
49 rangescale30 = false;
50 rangescale40 = false;
51 rangescale50 = false;
52 rangescale60 = false;
53
54 rangering0 = true;
55 rangering10 = false;
56 rangering15 = false;
57 rangering20 = false;
58 rangering25 = false;
59
60 // radar sweep counter
61 tick = 0;
62 ALPHA = 255;
63
64 }
~Radar()65 Radar::~Radar(){
66 SDL_FreeSurface(blip);
67
68 //gotta free it, or we get a segfault
69 SDL_FreeSurface(sweep[0]);
70 }
71
InitGraphics(SDL_Surface * temp,SDL_Surface * tempradarscreen)72 void Radar::InitGraphics(SDL_Surface *temp, SDL_Surface *tempradarscreen)
73 {
74 screen=temp;
75 radarscreen=tempradarscreen;
76
77 temp = SDL_CreateRGBSurface(SDL_SWSURFACE, 420, 490, 16,
78 screen->format->Rmask,
79 screen->format->Gmask,
80 screen->format->Bmask,
81 screen->format->Amask);
82 tempscreen=SDL_DisplayFormat(temp);
83 SDL_FreeSurface(temp);
84
85 LoadWidgets();
86 DisplayWidgets();
87
88 orange = SDL_MapRGB(screen->format, 238, 118, 0);
89
90 //load the picture of a blip (blip.png)
91 temp = Load_Image("images/blip.png");
92 if(temp != NULL) {
93 blip = SDL_DisplayFormat(temp);
94 SDL_SetAlpha(blip, SDL_SRCALPHA, 128);
95 }
96 if ( blip == NULL ) {
97 cerr<<"Function LoadWidgets()" << endl
98 << SDL_GetError() << endl;
99 SDL_Quit();
100 exit(0);
101 }
102 SDL_FreeSurface(temp);
103 }
104
LoadWidgets()105 void Radar::LoadWidgets(){
106
107 SDL_Surface *temp;
108
109 // Load Range Scale Widgets
110 temp = Load_Image("images/range10off.png");
111 if(temp != NULL) range10off = SDL_DisplayFormat(temp);
112 if ( range10off == NULL ) {
113 cerr<<"Function LoadWidgets()" << endl
114 << SDL_GetError() << endl;
115 SDL_Quit();
116 exit(0);
117 }
118 SDL_FreeSurface(temp);
119
120 temp = Load_Image("images/range10on.png");
121 if(temp != NULL) range10on = SDL_DisplayFormat(temp);
122 if ( range10on == NULL ) {
123 cerr<<"Function LoadWidgets()" << endl
124 << SDL_GetError() << endl;
125 SDL_Quit();
126 exit(0);
127 }
128 SDL_FreeSurface(temp);
129
130 temp = Load_Image("images/range20off.png");
131 if(temp != NULL) range20off = SDL_DisplayFormat(temp);
132 if ( range20off == NULL ) {
133 cerr<<"Function LoadWidgets()" << endl
134 << SDL_GetError() << endl;
135 SDL_Quit();
136 exit(0);
137 }
138 SDL_FreeSurface(temp);
139
140 temp = Load_Image("images/range20on.png");
141 if(temp != NULL) range20on = SDL_DisplayFormat(temp);
142 if ( range20on == NULL ) {
143 cerr<<"Function LoadWidgets()" << endl
144 << SDL_GetError() << endl;
145 SDL_Quit();
146 exit(0);
147 }
148 SDL_FreeSurface(temp);
149
150 temp = Load_Image("images/range30off.png");
151 if(temp != NULL) range30off = SDL_DisplayFormat(temp);
152 if ( range30off == NULL ) {
153 cerr<<"Function LoadWidgets()" << endl
154 << SDL_GetError() << endl;
155 SDL_Quit();
156 exit(0);
157 }
158 SDL_FreeSurface(temp);
159
160 temp = Load_Image("images/range30on.png");
161 if(temp != NULL) range30on = SDL_DisplayFormat(temp);
162 if ( range30on == NULL ) {
163 cerr<<"Function LoadWidgets()" << endl
164 << SDL_GetError() << endl;
165 SDL_Quit();
166 exit(0);
167 }
168 SDL_FreeSurface(temp);
169
170 temp = Load_Image("images/range40off.png");
171 if(temp != NULL) range40off = SDL_DisplayFormat(temp);
172 if ( range40off == NULL ) {
173 cerr<<"Function LoadWidgets()" << endl
174 << SDL_GetError() << endl;
175 SDL_Quit();
176 exit(0);
177 }
178 SDL_FreeSurface(temp);
179
180 temp = Load_Image("images/range40on.png");
181 if(temp != NULL) range40on = SDL_DisplayFormat(temp);
182 if ( range40on == NULL ) {
183 cerr<<"Function LoadWidgets()" << endl
184 << SDL_GetError() << endl;
185 SDL_Quit();
186 exit(0);
187 }
188 SDL_FreeSurface(temp);
189
190
191 temp = Load_Image("images/range50off.png");
192 if(temp != NULL) range50off = SDL_DisplayFormat(temp);
193 if ( range50off == NULL ) {
194 cerr<<"Function LoadWidgets()" << endl
195 << SDL_GetError() << endl;
196 SDL_Quit();
197 exit(0);
198 }
199 SDL_FreeSurface(temp);
200
201 temp = Load_Image("images/range50on.png");
202 if(temp != NULL) range50on = SDL_DisplayFormat(temp);
203 if ( range50on == NULL ) {
204 cerr<<"Function LoadWidgets()" << endl
205 << SDL_GetError() << endl;
206 SDL_Quit();
207 exit(0);
208 }
209 SDL_FreeSurface(temp);
210
211 temp = Load_Image("images/range60off.png");
212 if(temp != NULL) range60off = SDL_DisplayFormat(temp);
213 if ( range60off == NULL ) {
214 cerr<<"Function LoadWidgets()" << endl
215 << SDL_GetError() << endl;
216 SDL_Quit();
217 exit(0);
218 }
219 SDL_FreeSurface(temp);
220
221 temp = Load_Image("images/range60on.png");
222 if(temp != NULL) range60on = SDL_DisplayFormat(temp);
223 if ( range60on == NULL ) {
224 cerr<<"Function LoadWidgets()" << endl
225 << SDL_GetError() << endl;
226 SDL_Quit();
227 exit(0);
228 }
229 SDL_FreeSurface(temp);
230
231 // Load Range Ring Widgets
232
233 temp = Load_Image("images/ring0off.png");
234 if(temp != NULL) ring0off = SDL_DisplayFormat(temp);
235 if ( ring0off == NULL ) {
236 cerr<<"Function LoadWidgets()" << endl
237 << SDL_GetError() << endl;
238 SDL_Quit();
239 exit(0);
240 }
241 SDL_FreeSurface(temp);
242
243 temp = Load_Image("images/ring0on.png");
244 if(temp != NULL) ring0on = SDL_DisplayFormat(temp);
245 if ( ring0on == NULL ) {
246 cerr<<"Function LoadWidgets()" << endl
247 << SDL_GetError() << endl;
248 SDL_Quit();
249 exit(0);
250 }
251 SDL_FreeSurface(temp);
252
253 temp = Load_Image("images/ring5off.png");
254 if(temp != NULL) ring5off = SDL_DisplayFormat(temp);
255 if ( ring5off == NULL ) {
256 cerr<<"Function LoadWidgets()" << endl
257 << SDL_GetError() << endl;
258 SDL_Quit();
259 exit(0);
260 }
261 SDL_FreeSurface(temp);
262
263 temp = Load_Image("images/ring5on.png");
264 if(temp != NULL) ring5on = SDL_DisplayFormat(temp);
265 if ( ring5on == NULL ) {
266 cerr<<"Function LoadWidgets()" << endl
267 << SDL_GetError() << endl;
268 SDL_Quit();
269 exit(0);
270 }
271
272 SDL_FreeSurface(temp);
273
274 temp = Load_Image("images/ring10off.png");
275 if(temp != NULL) ring10off = SDL_DisplayFormat(temp);
276 if ( ring10off == NULL ) {
277 cerr<<"Function LoadWidgets()" << endl
278 << SDL_GetError() << endl;
279 SDL_Quit();
280 exit(0);
281 }
282 SDL_FreeSurface(temp);
283
284 temp = Load_Image("images/ring10on.png");
285 if(temp != NULL) ring10on = SDL_DisplayFormat(temp);
286 if ( ring10on == NULL ) {
287 cerr<<"Function LoadWidgets()" << endl
288 << SDL_GetError() << endl;
289 SDL_Quit();
290 exit(0);
291 }
292 SDL_FreeSurface(temp);
293
294 temp = Load_Image("images/ring15off.png");
295 if(temp != NULL) ring15off = SDL_DisplayFormat(temp);
296 if ( ring15off == NULL ) {
297 cerr<<"Function LoadWidgets()" << endl
298 << SDL_GetError() << endl;
299 SDL_Quit();
300 exit(0);
301 }
302 SDL_FreeSurface(temp);
303
304 temp = Load_Image("images/ring15on.png");
305 if(temp != NULL) ring15on = SDL_DisplayFormat(temp);
306 if ( ring15on == NULL ) {
307 cerr<<"Function LoadWidgets()" << endl
308 << SDL_GetError() << endl;
309 SDL_Quit();
310 exit(0);
311 }
312 SDL_FreeSurface(temp);
313
314 temp = Load_Image("images/ring20off.png");
315 if(temp != NULL) ring20off = SDL_DisplayFormat(temp);
316 if ( ring20off == NULL ) {
317 cerr<<"Function LoadWidgets()" << endl
318 << SDL_GetError() << endl;
319 SDL_Quit();
320 exit(0);
321 }
322 SDL_FreeSurface(temp);
323
324 temp = Load_Image("images/ring20on.png");
325 if(temp != NULL) ring20on = SDL_DisplayFormat(temp);
326 if ( ring20on == NULL ) {
327 cerr<<"Function LoadWidgets()" << endl
328 << SDL_GetError() << endl;
329 SDL_Quit();
330 exit(0);
331 }
332 SDL_FreeSurface(temp);
333
334 temp = Load_Image("images/ring25off.png");
335 if(temp != NULL) ring25off = SDL_DisplayFormat(temp);
336 if ( ring25off == NULL ) {
337 cerr<<"Function LoadWidgets()" << endl
338 << SDL_GetError() << endl;
339 SDL_Quit();
340 exit(0);
341 }
342 SDL_FreeSurface(temp);
343
344 temp = Load_Image("images/ring25on.png");
345 if(temp != NULL) ring25on = SDL_DisplayFormat(temp);
346 if ( ring25on == NULL ) {
347 cerr<<"Function LoadWidgets()" << endl
348 << SDL_GetError() << endl;
349 SDL_Quit();
350 exit(0);
351 }
352 SDL_FreeSurface(temp);
353
354 // Load Mast Widgets
355 temp = Load_Image("images/mastdownoff.png");
356 if(temp != NULL) mastdownoff = SDL_DisplayFormat(temp);
357 if ( mastdownoff == NULL ) {
358 cerr<<"Function LoadWidgets()" << endl
359 << SDL_GetError() << endl;
360 SDL_Quit();
361 exit(0);
362 }
363 SDL_FreeSurface(temp);
364
365
366 temp = Load_Image("images/mastdownon.png");
367 if(temp != NULL) mastdownon = SDL_DisplayFormat(temp);
368 if ( mastdownon == NULL ) {
369 cerr<<"Function LoadWidgets()" << endl
370 << SDL_GetError() << endl;
371 SDL_Quit();
372 exit(0);
373 }
374 SDL_FreeSurface(temp);
375
376 temp = Load_Image("images/mastupoff.png");
377 if(temp != NULL) mastupoff = SDL_DisplayFormat(temp);
378 if ( mastupoff== NULL ) {
379 cerr<<"Function LoadWidgets()" << endl
380 << SDL_GetError() << endl;
381 SDL_Quit();
382 exit(0);
383 }
384 SDL_FreeSurface(temp);
385
386 temp = Load_Image("images/mastupon.png");
387 if(temp != NULL) mastupon = SDL_DisplayFormat(temp);
388 if ( mastupon == NULL ) {
389 cerr<<"Function LoadWidgets()" << endl
390 << SDL_GetError() << endl;
391 SDL_Quit();
392 exit(0);
393 }
394 SDL_FreeSurface(temp);
395
396 // VENZON: only need 1 sweep image now
397 sweep[0] = Load_Image("images/sweep0.png");
398
399 }
400
DisplayWidgets()401 void Radar::DisplayWidgets(){
402 // Range Scale Widgets
403 if(rangescale10)
404 {
405 dest.x = 748;
406 dest.y = 320;
407 dest.h = range10on->h;
408 dest.w = range10on->w;
409 SDL_BlitSurface(range10on, NULL, screen, &dest);
410 SDL_UpdateRects(screen, 1, &dest);
411 }
412 else
413 {
414 dest.x = 748;
415 dest.y = 320;
416 dest.h = range10off->h;
417 dest.w = range10off->w;
418 SDL_BlitSurface(range10off, NULL, screen, &dest);
419 SDL_UpdateRects(screen, 1, &dest);
420 }
421
422 if(rangescale20)
423 {
424 dest.x = 795;
425 dest.y = 320;
426 dest.h = range20on->h;
427 dest.w = range20on->w;
428 SDL_BlitSurface(range20on, NULL, screen, &dest);
429 SDL_UpdateRects(screen, 1, &dest);
430 }
431 else
432 {
433 dest.x = 795;
434 dest.y = 320;
435 dest.h = range20off->h;
436 dest.w = range20off->w;
437 SDL_BlitSurface(range20off, NULL, screen, &dest);
438 SDL_UpdateRects(screen, 1, &dest);
439 }
440
441 if(rangescale30)
442 {
443 dest.x = 842;
444 dest.y = 320;
445 dest.h = range30on->h;
446 dest.w = range30on->w;
447 SDL_BlitSurface(range30on, NULL, screen, &dest);
448 SDL_UpdateRects(screen, 1, &dest);
449 }
450 else
451 {
452 dest.x = 842;
453 dest.y = 320;
454 dest.h = range30off->h;
455 dest.w = range30off->w;
456 SDL_BlitSurface(range30off, NULL, screen, &dest);
457 SDL_UpdateRects(screen, 1, &dest);
458 }
459
460 if(rangescale40)
461 {
462 dest.x = 748;
463 dest.y = 367;
464 dest.h = range40on->h;
465 dest.w = range40on->w;
466 SDL_BlitSurface(range40on, NULL, screen, &dest);
467 SDL_UpdateRects(screen, 1, &dest);
468 }
469 else
470 {
471 dest.x = 748;
472 dest.y = 367;
473 dest.h = range40off->h;
474 dest.w = range40off->w;
475 SDL_BlitSurface(range40off, NULL, screen, &dest);
476 SDL_UpdateRects(screen, 1, &dest);
477 }
478
479 if(rangescale50)
480 {
481 dest.x = 795;
482 dest.y = 367;
483 dest.h = range50on->h;
484 dest.w = range50on->w;
485 SDL_BlitSurface(range50on, NULL, screen, &dest);
486 SDL_UpdateRects(screen, 1, &dest);
487 }
488 else
489 {
490 dest.x = 795;
491 dest.y = 367;
492 dest.h = range50off->h;
493 dest.w = range50off->w;
494 SDL_BlitSurface(range50off, NULL, screen, &dest);
495 SDL_UpdateRects(screen, 1, &dest);
496 }
497
498 if(rangescale60)
499 {
500 dest.x = 842;
501 dest.y = 367;
502
503 dest.h = range60on->h;
504 dest.w = range60on->w;
505 SDL_BlitSurface(range60on, NULL, screen, &dest);
506 SDL_UpdateRects(screen, 1, &dest);
507 }
508 else
509 {
510 dest.x = 842;
511 dest.y = 367;
512 dest.h = range60off->h;
513 dest.w = range60off->w;
514 SDL_BlitSurface(range60off, NULL, screen, &dest);
515 SDL_UpdateRects(screen, 1, &dest);
516 }
517
518 // Mast Widgets
519 if(Mast)
520 {
521 dest.x = 850;
522 dest.y = 185;
523 dest.h = mastupon->h;
524 dest.w = mastupon->w;
525 SDL_BlitSurface(mastupon, NULL, screen, &dest);
526 SDL_UpdateRects(screen, 1, &dest);
527
528 dest.x = 744;
529 dest.y = 185;
530 dest.h = mastdownoff->h;
531 dest.w = mastdownoff->w;
532 SDL_BlitSurface(mastdownoff, NULL, screen, &dest);
533 SDL_UpdateRects(screen, 1, &dest);
534 }
535 else
536 {
537 dest.x = 850;
538 dest.y = 185;
539 dest.h = mastupoff->h;
540 dest.w = mastupoff->w;
541 SDL_BlitSurface(mastupoff, NULL, screen, &dest);
542 SDL_UpdateRects(screen, 1, &dest);
543
544 dest.x = 744;
545 dest.y = 185;
546 dest.h = mastdownon->h;
547 dest.w = mastdownon->w;
548 SDL_BlitSurface(mastdownon, NULL, screen, &dest);
549 SDL_UpdateRects(screen, 1, &dest);
550 }
551
552 // Range Ring Widgets
553 if(rangering0)
554 {
555 dest.x = 749;
556 dest.y = 501;
557 dest.h = ring0on->h;
558 dest.w = ring0on->w;
559 SDL_BlitSurface(ring0on, NULL, screen, &dest);
560 SDL_UpdateRects(screen, 1, &dest);
561 }
562 else
563 {
564 dest.x = 749;
565 dest.y = 501;
566 dest.h = ring0off->h;
567 dest.w = ring0off->w;
568 SDL_BlitSurface(ring0off, NULL, screen, &dest);
569 SDL_UpdateRects(screen, 1, &dest);
570 }
571
572 if(rangering5)
573 {
574 dest.x = 796;
575 dest.y = 501;
576 dest.h = ring5on->h;
577 dest.w = ring5on->w;
578 SDL_BlitSurface(ring5on, NULL, screen, &dest);
579 SDL_UpdateRects(screen, 1, &dest);
580 }
581 else
582 {
583 dest.x = 796;
584 dest.y = 501;
585 dest.h = ring5off->h;
586 dest.w = ring5off->w;
587 SDL_BlitSurface(ring5off, NULL, screen, &dest);
588 SDL_UpdateRects(screen, 1, &dest);
589 }
590
591 if(rangering10)
592 {
593 dest.x = 843;
594 dest.y = 501;
595 dest.h = ring10on->h;
596 dest.w = ring10on->w;
597 SDL_BlitSurface(ring10on, NULL, screen, &dest);
598 SDL_UpdateRects(screen, 1, &dest);
599 }
600 else
601 {
602 dest.x = 843;
603 dest.y = 501;
604 dest.h = ring10off->h;
605 dest.w = ring10off->w;
606 SDL_BlitSurface(ring10off, NULL, screen, &dest);
607 SDL_UpdateRects(screen, 1, &dest);
608 }
609
610 if(rangering15)
611 {
612 dest.x = 749;
613 dest.y = 548;
614 dest.h = ring15on->h;
615 dest.w = ring15on->w;
616 SDL_BlitSurface(ring15on, NULL, screen, &dest);
617 SDL_UpdateRects(screen, 1, &dest);
618 }
619 else
620 {
621 dest.x = 749;
622 dest.y = 548;
623 dest.h = ring15off->h;
624 dest.w = ring15off->w;
625 SDL_BlitSurface(ring15off, NULL, screen, &dest);
626 SDL_UpdateRects(screen, 1, &dest);
627 }
628
629 if(rangering20)
630 {
631 dest.x = 796;
632 dest.y = 548;
633 dest.h = ring20on->h;
634 dest.w = ring20on->w;
635 SDL_BlitSurface(ring20on, NULL, screen, &dest);
636 SDL_UpdateRects(screen, 1, &dest);
637 }
638 else
639 {
640 dest.x = 796;
641 dest.y = 548;
642 dest.h = ring20off->h;
643 dest.w = ring20off->w;
644 SDL_BlitSurface(ring20off, NULL, screen, &dest);
645 SDL_UpdateRects(screen, 1, &dest);
646 }
647
648 if(rangering25)
649 {
650 dest.x = 843;
651 dest.y = 548;
652 dest.h = ring25on->h;
653 dest.w = ring25on->w;
654 SDL_BlitSurface(ring25on, NULL, screen, &dest);
655 SDL_UpdateRects(screen, 1, &dest);
656 }
657 else
658 {
659 dest.x = 843;
660 dest.y = 548;
661 dest.h = ring25off->h;
662 dest.w = ring25off->w;
663 SDL_BlitSurface(ring25off, NULL, screen, &dest);
664 SDL_UpdateRects(screen, 1, &dest);
665 }
666
667
668 // Need this for the time compression??
669 SDL_UpdateRect(screen,0, 0, 0, 0);
670
671 }
672
ClearScreen()673 void Radar::ClearScreen(){
674 // Clear the screen
675 SDL_Surface *temp;
676 temp = Load_Image("images/ClearRadar.png");
677 if(temp != NULL) ClearRadar = SDL_DisplayFormat(temp);
678 if ( ClearRadar == NULL ) {
679 cerr<<"Function LoadWidgets()" << endl
680 << SDL_GetError() << endl;
681 SDL_Quit();
682 exit(0);
683 }
684
685 src.x = 0;
686 src.y = 0;
687 src.w = ClearRadar->w;
688 src.h = ClearRadar->h;
689
690 dest.x = 98; // Blit destination x&y to the upper left
691 dest.y = 154;
692 dest.w = ClearRadar->w; // Height and width equal to the
693 dest.h = ClearRadar->h; // source images....
694 SDL_BlitSurface(ClearRadar, NULL, screen, &dest); // Do the actual Blit
695
696 SDL_FreeSurface(temp);
697
698 SDL_UpdateRects(screen, 1, &dest); //Show the screen.
699 SDL_FreeSurface(ClearRadar); //Free up the surface memory.
700 DisplayWidgets();
701
702 }
703
ClearTextBox()704 void Radar::ClearTextBox(){
705 // Clear the screen
706 SDL_Surface *temp;
707 temp = Load_Image("images/ClearRadar2.png");
708 if(temp != NULL) ClearRadar = SDL_DisplayFormat(temp);
709 if ( ClearRadar == NULL ) {
710 cerr<<"Function LoadWidgets()" << endl
711 << SDL_GetError() << endl;
712 SDL_Quit();
713 exit(0);
714 }
715
716 src.x = 0;
717 src.y = 0;
718 src.w = ClearRadar->w;
719 src.h = ClearRadar->h;
720
721 dest.x = 139; // Blit destination x&y to the upper left
722 dest.y = 572;
723 dest.w = ClearRadar->w; // Height and width equal to the
724 dest.h = ClearRadar->h; // source images....
725 SDL_BlitSurface(ClearRadar, NULL, screen, &dest); // Do the actual Blit
726
727 SDL_FreeSurface(temp);
728
729 SDL_UpdateRects(screen, 1, &dest); //Show the screen.
730 SDL_FreeSurface(ClearRadar); //Free up the surface memory.
731 DisplayWidgets();
732
733 }
734
Sweep(float gametime)735 void Radar::Sweep(float gametime)
736 {
737 if(getMastStatus()) // If the mast is up start sweep
738 {
739 tick+=gametime/25.0f;
740
741 if(tick > 360) tick -= 360;
742 }
743 }
744
DisplaySweep()745 void Radar::DisplaySweep()
746 {
747 if(getMastStatus()) // If the mast is up start sweep
748 {
749
750 src.x = 0;
751 src.y = 0;
752 src.w = sweep[0]->w;
753 src.h = sweep[0]->h;
754
755 dest.x = 193;
756 dest.y = 245;
757 dest.w = sweep[0]->w;
758 dest.h = sweep[0]->h;
759
760 //VENZON: some rotozooming!
761 SDL_SetAlpha(sweep[0], SDL_SRCALPHA, 128);
762 SDL_FillRect(screen, &dest, black);
763 SDL_Surface *sweeprot;
764
765 //set the last argument of this function to 0 for a bit faster
766 //(but much crappier looking) rotozooming
767 sweeprot = rotozoomSurface(sweep[0], -tick, 1.0, 1);
768
769 //the rotozoomer seems to create a surface with whatever width and
770 //height necessary, so we have to recompute the destination coords
771 src.w = sweeprot->w;
772 src.h = sweeprot->h;
773 dest.x = sweep[0]->w/2 + dest.x - sweeprot->w/2;
774 dest.y = sweep[0]->h/2 + dest.y - sweeprot->h/2;
775 dest.w = src.w;
776 dest.h = src.h;
777
778 //I'm not sure what this alpha stuff is for, but hopefully
779 //the rotozoomer won't mess it up
780 SDL_SetAlpha(sweeprot, SDL_SRCALPHA, 128);
781 SDL_BlitSurface(sweeprot, NULL, screen, &dest); // Do the actual Blit
782 SDL_FreeSurface(sweeprot);
783 }
784 }
785
DisplayRings()786 void Radar::DisplayRings()
787 {
788 int number;
789
790 if (RangeRing == 0)
791 {
792 number = 0;
793 }
794 else
795 {
796 number = int(float(RangeScale)/float(RangeRing));
797 }
798
799 for(int i = 0; i < number; i++)
800 {
801 DrawCircle(screen, 320, 371, int((144.0/getRangeScale())*RangeRing*(i+1)), orange);
802 }
803 }
804
DisplayContacts()805 void Radar::DisplayContacts()
806 {
807 float radians;
808 int bearing, range, depth;
809 Submarine *target;
810
811 DisplaySweep(); // Start the radar sweep
812
813 DisplayRings(); // Draw Range Rings
814
815 // Note: Center of radar screen @ (x,y) = (316,374)
816 // set dx = 144 dy = 144
817
818 target = Subs->next;
819 while (target)
820 {
821 bearing = (int)Subs->BearingToTarget(target);
822 range = (int)Subs->DistanceToTarget(target);
823 depth = (int)Subs->Depth;
824
825 radians = float(bearing) *(3.14/180.0); // degrees to radians
826
827 if(isTargetVisible(target, range, depth, 100, 3))
828 {
829 // Find where we plot the dot
830 x = 316 + int((460-316)*(range/float(1000*RangeScale))*cos(1.57-radians));
831 y = 374 - int((374-230)* (range/float(1000*RangeScale))*sin(1.57-radians));
832
833 src.x = 0;
834 src.y = 0;
835 src.w = blip->w;
836 src.h = blip->h;
837
838 dest.x = x;
839 dest.y = y;
840 dest.w = blip->w;
841 dest.h = blip->h;
842
843 // Here's where we set the alpha level
844
845 if(bearing <= 180)
846 {
847 if(tick >= bearing && tick <= ReciprocalBearing(bearing))
848 {
849 ALPHA = int(-(255.0/180.0)* float(DeltaBearing((int) tick, bearing))+255.0);
850 }
851 else
852 {
853
854 ALPHA = 0;
855 }
856 }
857
858 if(bearing >= 180)
859 {
860 if(tick <= bearing && tick >= ReciprocalBearing(bearing))
861 {
862 ALPHA = 0;
863 }
864 else
865 {
866
867 ALPHA = int(-(255.0/180.0)* float(DeltaBearing((int) tick, bearing))+255.0);
868 }
869 }
870
871 SDL_SetAlpha(blip, SDL_SRCALPHA, ALPHA);
872 SDL_FillRect(screen, &dest, black);
873
874 SDL_BlitSurface(blip, NULL, screen, &dest); // Do the actual Blit
875
876 } // if visible
877 target = target->next;
878 } // end of while
879 SDL_UpdateRect(screen,0, 0, 0, 0);
880 }
881
ClearRangeScale()882 void Radar::ClearRangeScale()
883 {
884 rangescale10 = false;
885 rangescale20 = false;
886 rangescale30 = false;
887 rangescale40 = false;
888 rangescale50 = false;
889 rangescale60 = false;
890 ClearScreen();
891 }
892
ClearRangeRing()893 void Radar::ClearRangeRing()
894 {
895 rangering0 = false;
896 rangering5 = false;
897 rangering10 = false;
898 rangering15 = false;
899 rangering20 = false;
900 rangering25 = false;
901 ClearScreen();
902 }
903
904 // Toggle Range Scale
ToggleRangeScale10()905 void Radar::ToggleRangeScale10(){
906 ClearRangeScale();
907 rangescale10 = !rangescale10;
908 setRangeScale(10);
909 }
ToggleRangeScale20()910 void Radar::ToggleRangeScale20(){
911 ClearRangeScale();
912 rangescale20 = !rangescale20;
913 setRangeScale(20);
914 }
ToggleRangeScale30()915 void Radar::ToggleRangeScale30(){
916 ClearRangeScale();
917 rangescale30 = !rangescale30;
918 setRangeScale(30);
919 }
ToggleRangeScale40()920 void Radar::ToggleRangeScale40(){
921 ClearRangeScale();
922 rangescale40 = !rangescale40;
923 setRangeScale(40);
924 }
ToggleRangeScale50()925 void Radar::ToggleRangeScale50(){
926 ClearRangeScale();
927 rangescale50 = !rangescale50;
928 setRangeScale(50);
929 }
ToggleRangeScale60()930 void Radar::ToggleRangeScale60(){
931 ClearRangeScale();
932 rangescale60 = !rangescale60;
933 setRangeScale(60);
934 }
935
936 // Toggle Range Rings
ToggleRangeRing0()937 void Radar::ToggleRangeRing0(){
938 ClearRangeRing();
939 rangering0 = !rangering0;
940 setRangeRing(0);
941 }
942
ToggleRangeRing5()943 void Radar::ToggleRangeRing5(){
944 ClearRangeRing();
945 rangering5 = !rangering5;
946 setRangeRing(5);
947 }
948
ToggleRangeRing10()949 void Radar::ToggleRangeRing10(){
950 ClearRangeRing();
951 rangering10 = !rangering10;
952 setRangeRing(10);
953 }
954
ToggleRangeRing15()955 void Radar::ToggleRangeRing15(){
956 ClearRangeRing();
957 rangering15 = !rangering15;
958 setRangeRing(15);
959 }
960
ToggleRangeRing20()961 void Radar::ToggleRangeRing20(){
962 ClearRangeRing();
963 rangering20 = !rangering20;
964 setRangeRing(20);
965 }
966
ToggleRangeRing25()967 void Radar::ToggleRangeRing25(){
968 ClearRangeRing();
969 rangering25 = !rangering25;
970 setRangeRing(25);
971 }
972
RaiseMast()973 void Radar::RaiseMast()
974 {
975 Mast = true;
976 }
977
LowerMast()978 void Radar::LowerMast()
979 {
980 Mast = false;
981 }
982
983
ToggleMast()984 void Radar::ToggleMast()
985 {
986 // ClearScreen();
987 Mast = !Mast;
988 }
setRangeScale(int RS)989 void Radar::setRangeScale(int RS)
990 {
991 // Set Radar RangeScale
992 RangeScale = (RS == 10 || RS == 20 || RS == 30 ||
993 RS == 40 || RS == 50 || RS == 60) ? RS : 10;
994 }
setRangeRing(int RR)995 void Radar::setRangeRing(int RR)
996 {
997 // Set Radar RangeRing
998 RangeRing = (RR == 0 || RR == 5 || RR == 10 ||
999 RR == 15 || RR == 20 || RR == 25) ? RR : 0;
1000 }
getRangeScale() const1001 int Radar::getRangeScale() const
1002 {
1003 return RangeScale;
1004 }
getRangeRing() const1005 int Radar::getRangeRing() const
1006 {
1007 return RangeRing;
1008 }
getMastStatus() const1009 bool Radar::getMastStatus()const
1010 {
1011 return Mast;
1012 }
getAntennaHeight(int Depth,int SeaState) const1013 int Radar::getAntennaHeight(int Depth,int SeaState) const
1014 {
1015 // Effective Height of radar mast above water.
1016 // Note at SeaState > 5, must be on the surface to use radar
1017 // Also at SeaState > 5, effective length on mast = 1 ft.
1018 switch (SeaState)
1019 {
1020 case 0:
1021 case 1: return(MastHeight - Depth);
1022 case 2: return(MastHeight - Depth - 1);
1023 case 3: return(MastHeight - Depth - 3);
1024 case 4: return(MastHeight - Depth - 5);
1025 case 5: return(MastHeight - Depth - 8);
1026 default: return(MastHeight - Depth - 58);
1027 }
1028 }
1029
isTargetVisible(Submarine * target,int TargetRange,int ObserverDepth,int TargetHeight,int SeaState)1030 bool Radar::isTargetVisible(Submarine *target, int TargetRange,
1031 int ObserverDepth,
1032 int TargetHeight, int SeaState)
1033 {
1034 // Determines if observer's radar can detect target.
1035 // Returns a 1 if true or a 0 if false.
1036
1037 // TargetRange is the true range to the target.
1038
1039 // TargetHeight is the height of the tallest mast on a surface ship
1040 // (usually 50 ft - 175 ft), height of conning tower for a submarine
1041 // (usually 40-50 ft), or altitude for airplane.
1042
1043 /* To see Target, Mast must be up, Range < RadarHorizon, Range < RangeScale.
1044
1045 Radar horizon is the earliest posssible target detection due to
1046 the Earth-Curvature. Radar horizon = 2400(sqrt(ha)+ sqrt(ht))
1047 ha = antenna height(ft), ht = target height(ft), RadarHorizon(yds)
1048
1049 When sea state (SS) <= 1, Depth should be < 58 ft or mast will be below
1050 water. At SS = 2, depth <= 57 ft. At SS = 3, depth <= 55 ft.
1051 At SS = 4, depth <= 53 ft. At SS = 5, depth <= 50 ft.
1052 */
1053
1054 bool boolean = false;
1055
1056 // if target is under water we cannot see them
1057 if (target->Depth > 0.0)
1058 return false;
1059
1060 CurrentAntennaHeight = getAntennaHeight(ObserverDepth,SeaState);
1061 if(CurrentAntennaHeight <= 0) return boolean; // Mast is below water!
1062
1063 RadarHorizon = 2400*(int)(sqrt(float(CurrentAntennaHeight)) + sqrt(float(TargetHeight)));
1064
1065 if(target->Depth <= 0 && int(TargetRange) <= 1000*getRangeScale() && getMastStatus() == 1 &&
1066 TargetRange <= RadarHorizon) boolean = true;
1067 return boolean;
1068
1069 }
1070
getRadarHorizon(int ObserverDepth,int TargetHeight,int SeaState)1071 float Radar::getRadarHorizon(int ObserverDepth, int TargetHeight, int SeaState)
1072 {
1073 /* Radar horizon is the earliest posssible target detection due to
1074 the Earth-Curvature. Radar horizon = 2400(sqrt(ha)+ sqrt(ht))
1075 ha = antenna height(ft), ht = target height(ft), RadarHorizon(yds)
1076
1077 When sea state (SS) <= 1, Depth should be < 58 ft or mast will be below
1078 water. At SS = 2, depth <= 57 ft. At SS = 3, depth <= 55 ft.
1079 At SS = 4, depth <= 53 ft. At SS = 5, depth <= 50 ft.
1080 */
1081
1082 CurrentAntennaHeight = getAntennaHeight(ObserverDepth,SeaState);
1083 if(CurrentAntennaHeight <= 0) return 0; // Mast is below water!
1084
1085 return(2400.0*(sqrt(float(CurrentAntennaHeight)) + sqrt(float(TargetHeight))));
1086
1087 }
1088
getBearing(int TargetBearing)1089 int Radar::getBearing(int TargetBearing)
1090 {
1091 // Returns the bearing to the target.
1092 bearing = TargetBearing;
1093 return bearing;
1094 }
1095
getRange(int TargetRange)1096 int Radar::getRange(int TargetRange)
1097 {
1098 // Returns the range to the target.
1099 range = TargetRange;
1100 return range;
1101 }
1102
ShowData(SDL_Surface * screen,int x,int y)1103 void Radar::ShowData(SDL_Surface *screen, int x, int y){
1104 static char text[120];
1105 // string file1 = "font.png";
1106 //string file2 = "font.dat";
1107 char filename[] = "images/largefont.png";
1108 char filename2[] = "data/largefont.dat";
1109 static DFont largeFont(filename, filename2);
1110
1111 double c1, c2, c3, c4, c5, c6;
1112 int bearing;
1113 int range;
1114
1115 c1 = double(316);
1116 c2 = double((460 - 316))/double(RangeScale);
1117 c3 = double(374);
1118 c4 = double((374 - 230))/double(RangeScale);
1119
1120 c5 = c2*(double(y)-c3);
1121 c6 = c4*(double(x)-c1);
1122
1123 ClearTextBox();
1124
1125
1126 if(x >= 316)
1127 {
1128 bearing = int(90.0 + (180/3.14)*atan(c5/c6));
1129 }
1130 else
1131 {
1132 bearing = int(270.0 + (180/3.14)*atan(c5/c6));
1133 }
1134
1135 range = int(1000.0*sqrt(pow(((double(x)-c1)/c2),2)+pow(((double(y)-c3)/c4),2)));
1136
1137
1138 src.x=166;
1139 src.y=608; //define a rectangle on the screen and make it black
1140 src.h=30;
1141 src.w=90;
1142
1143 sprintf(text, " %i ", bearing);
1144 largeFont.PutString(screen, 170, 615, text);
1145
1146 src.x=383;
1147 src.y=608; //define a rectangle on the screen and make it black
1148 src.h=30;
1149 src.w=90;
1150
1151 sprintf(text, " %i ", range);
1152 largeFont.PutString(screen, 370, 615, text);
1153
1154 return;
1155
1156 }
1157
DeltaBearing(int bearing1,int bearing2)1158 int Radar::DeltaBearing(int bearing1, int bearing2)
1159 {
1160 // Difference between two bearings
1161 int deltabearing;
1162 // for POSIX systems
1163 #ifndef WIN32
1164 if (fabs(bearing1 - bearing2) < 180){
1165 deltabearing = (int) fabs(bearing1 - bearing2);
1166 }else{
1167 deltabearing = (int) (360 - fabs(bearing1 - bearing2));
1168 }
1169 // WIN32 prefers abs when dealignwith int
1170 #else
1171 if (abs(bearing1 - bearing2) < 180){
1172 deltabearing = (int) abs(bearing1 - bearing2);
1173 }else{
1174 deltabearing = (int) (360 - abs(bearing1 - bearing2));
1175 }
1176 #endif
1177 return deltabearing;
1178 }
1179
ReciprocalBearing(int bearing)1180 int Radar::ReciprocalBearing(int bearing)
1181 {
1182 // returns the 180 degree opposite of the bearing given to it..
1183 int recipbearing;
1184 if (bearing >= 180){
1185 recipbearing = bearing - 180;
1186 }else{
1187 recipbearing = bearing + 180;
1188 }
1189 return recipbearing;
1190 }
1191
DrawPixel(SDL_Surface * screen,int x,int y,Uint32 color)1192 void Radar::DrawPixel(SDL_Surface *screen, int x, int y, Uint32 color)
1193 {
1194 //this only works for 16bpp screens
1195 //are we outside the screen?????
1196 //If we are bail out now before it's too late!
1197
1198 if (x > 1023 || x < 0 || y > 759 || y < 0) {
1199 return;
1200 }
1201
1202 //place the pixel on the screen
1203 Uint16 *pixel_location;
1204 pixel_location = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
1205 *pixel_location = color;
1206 }
1207
DrawArc(SDL_Surface * screen,int X1,int Y1,int Radius,int Theta1,int Theta2,Uint32 Color)1208 void Radar::DrawArc(SDL_Surface *screen, int X1, int Y1, int Radius, int Theta1, int Theta2, Uint32 Color)
1209 {
1210
1211 //Draw an arc at (X1,Y1) of a given radius from theta1 to theta2 using specified Color.
1212 int x, y, xc, yc, radius;
1213 int theta, theta1, theta2;
1214 xc = X1;
1215 yc = Y1;
1216 radius = Radius;
1217 theta1 = Theta1;
1218 theta2 = Theta2;
1219
1220 for(theta=theta1;theta<=theta2;theta+=5) {
1221 x = xc + int(radius*cos(theta*3.14/180.0));
1222 y = yc - int(radius*sin(theta*3.14/180.0));
1223 DrawPixel(screen, x, y, Color);
1224 }
1225 }
1226
DrawCircle(SDL_Surface * screen,int X1,int Y1,int Radius,Uint32 Color)1227 void Radar::DrawCircle(SDL_Surface *screen, int X1, int Y1, int Radius, Uint32 Color)
1228 {
1229
1230 //Draw a circle at (X1,Y1) of a given radius using specified Color.
1231 int xc, yc, radius;
1232 xc = X1;
1233 yc = Y1;
1234 radius = Radius;
1235 DrawArc(screen, xc, yc, radius, 0, 360, Color);
1236 }
1237
1238
1239
1240
1241