1 /*
2 This file is part of Warzone 2100.
3 Copyright (C) 1999-2004 Eidos Interactive
4 Copyright (C) 2005-2020 Warzone 2100 Project
5
6 Warzone 2100 is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Warzone 2100 is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Warzone 2100; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 /** @file
21 * \brief Cursor definitions (32x32)
22 */
23
24 #include "lib/framework/frame.h"
25 #include "lib/ivis_opengl/bitimage.h"
26 #include "lib/ivis_opengl/tex.h"
27 #include "src/warzoneconfig.h"
28 #include "cursors_sdl.h"
29 #include <SDL.h>
30
31 static CURSOR currentCursor = CURSOR_MAX;
32 static CURSOR lastAppliedCursor = CURSOR_MAX;
33 static SDL_Cursor *aCursors[CURSOR_MAX] = {};
34 static bool monoCursor;
35 static bool cursorsEnabled = false;
36
37 /* TODO: do bridge and attach need swapping? */
38 static const char *cursor_arrow[] =
39 {
40 /* width height num_colors chars_per_pixel */
41 " 32 32 3 1",
42 /* colors */
43 "X c #000000",
44 ". c #ffffff",
45 " c None",
46 /* pixels */
47 "X ",
48 "XX ",
49 "X.X ",
50 "X..X ",
51 "X...X ",
52 "X....X ",
53 "X.....X ",
54 "X......X ",
55 "X.......X ",
56 "X........X ",
57 "X.....XXXXX ",
58 "X..X..X ",
59 "X.X X..X ",
60 "XX X..X ",
61 "X X..X ",
62 " X..X ",
63 " X..X ",
64 " X..X ",
65 " XX ",
66 " ",
67 " ",
68 " ",
69 " ",
70 " ",
71 " ",
72 " ",
73 " ",
74 " ",
75 " ",
76 " ",
77 " ",
78 " ",
79 "0,0"
80 };
81
82 static const char *cursor_dest[] =
83 {
84 /* width height num_colors chars_per_pixel */
85 " 32 32 3 1",
86 /* colors */
87 "X c #000000",
88 ". c #ffffff",
89 " c None",
90 /* pixels */
91 " ",
92 " ",
93 " ",
94 " ",
95 " ",
96 " ",
97 " ",
98 " ",
99 " ",
100 " .. ",
101 " ...X ",
102 " ..X.X ",
103 " ..X .X ",
104 " .X.X .X ",
105 " .X.X .X ",
106 " .X .X .X ",
107 " .X .X ....... ",
108 " .X .X .XX....X ",
109 " .X .X .XXX....X ",
110 " .X ..XXXX....X ",
111 " ...X ..XXXX....X ",
112 " .....X ..........X ",
113 " .....X ..........X ",
114 " .....X .XX.XX.XX.. ",
115 " ...X .X..X..X..X.. ",
116 " XX .X..X..X..XX.X ",
117 " X...........XX ",
118 " XXXXXXXXXXXX ",
119 " ",
120 " ",
121 " ",
122 " ",
123 "15,18"
124 };
125
126 static const char *cursor_sight[] =
127 {
128 /* width height num_colors chars_per_pixel */
129 " 32 32 3 1",
130 /* colors */
131 "X c #000000",
132 ". c #ffffff",
133 " c None",
134 /* pixels */
135 " ",
136 " ",
137 " ....... ",
138 " .. ........... .. ",
139 " .... X..XXXXXXX..X ....X ",
140 " .....XXXX XXX.....XX ",
141 " .......X .......X ",
142 " ........ ........XX ",
143 " .......XX .......X ",
144 " XX.....XX .....XXX ",
145 " ..X....XX ....X..X ",
146 " ..XX..XX ..XX..X ",
147 " ...X .XX .X ...X ",
148 " ..XX X X ..X ",
149 " ..X ..X ",
150 " ..X ..X ",
151 " ..X ..X ",
152 " ..X ..X ",
153 " ... . .X ...X ",
154 " ..X .. ..X ..XX ",
155 " ..X.... ....X..X ",
156 " XX..... .....XXXX ",
157 " ....... .......XX ",
158 " ........ ........XX ",
159 " .......XXX XX.......X ",
160 " .....XXX XX.....X ",
161 " ....XXX... ...XXX.... ",
162 " ..XXX X...........XXX X..X ",
163 " XX XX.......XXX XX ",
164 " XXXXXXXX ",
165 " ",
166 " ",
167 "15,16"
168 };
169
170 static const char *cursor_target[] =
171 {
172 /* width height num_colors chars_per_pixel */
173 " 32 32 3 1",
174 /* colors */
175 "X c #000000",
176 ". c #ffffff",
177 " c None",
178 /* pixels */
179 " ",
180 " ",
181 " ",
182 " . ",
183 " .X ",
184 " ....X.. ",
185 " ......X.... ",
186 " ...XXX.XXX... ",
187 " ..XX .X X.. ",
188 " ..X .X .. ",
189 " ..X XX .. ",
190 " ..X ..X ",
191 " ..X ..X ",
192 " ..X ..X ",
193 " ..X ..X ",
194 " ........X . ........X ",
195 " XXXXXXXX X XXXXXXXX ",
196 " ..X ..X ",
197 " ..X ..X ",
198 " ..X ..X ",
199 " .. .X ",
200 " ..X . ..X ",
201 " .. .X ..X ",
202 " .. .X ..X ",
203 " ... .X ..X ",
204 " X......X....X ",
205 " XX....X..XX ",
206 " XXX.XXX ",
207 " .X ",
208 " XX ",
209 " ",
210 " ",
211 "15,15"
212 };
213
214 static const char *cursor_larrow[] =
215 {
216 /* width height num_colors chars_per_pixel */
217 " 32 32 3 1",
218 /* colors */
219 "X c #000000",
220 ". c #ffffff",
221 " c None",
222 /* pixels */
223 " ",
224 " ",
225 " ",
226 " ",
227 " ",
228 " ",
229 " ",
230 " ",
231 " ",
232 " .. ",
233 " ...X ",
234 " ....X ",
235 " ............... ",
236 " .................X ",
237 " ...................X ",
238 " .....................X ",
239 " XX...................X ",
240 " XX.................X ",
241 " XX...............X ",
242 " XX....XXXXXXXXXX ",
243 " XX...X ",
244 " XX..X ",
245 " XXX ",
246 " ",
247 " ",
248 " ",
249 " ",
250 " ",
251 " ",
252 " ",
253 " ",
254 " ",
255 "7,15"
256 };
257
258 static const char *cursor_rarrow[] =
259 {
260 /* width height num_colors chars_per_pixel */
261 " 32 32 3 1",
262 /* colors */
263 "X c #000000",
264 ". c #ffffff",
265 " c None",
266 /* pixels */
267 " ",
268 " ",
269 " ",
270 " ",
271 " ",
272 " ",
273 " ",
274 " ",
275 " ",
276 " ",
277 " .. ",
278 " ... ",
279 " .... ",
280 " ............... ",
281 " ................. ",
282 " ................... ",
283 " .....................X ",
284 " ...................XX ",
285 " .................XX ",
286 " ...............XX ",
287 " XXXXXXXX....XX ",
288 " X...XX ",
289 " ..XX ",
290 " XX ",
291 " ",
292 " ",
293 " ",
294 " ",
295 " ",
296 " ",
297 " ",
298 " ",
299 "25,16"
300 };
301
302 static const char *cursor_darrow[] =
303 {
304 /* width height num_colors chars_per_pixel */
305 " 32 32 3 1",
306 /* colors */
307 "X c #000000",
308 ". c #ffffff",
309 " c None",
310 /* pixels */
311 " ",
312 " ",
313 " ",
314 " ",
315 " ",
316 " ",
317 " ",
318 " ....... ",
319 " .......X ",
320 " .......X ",
321 " .......X ",
322 " .......X ",
323 " .......X ",
324 " .......X XX ",
325 " .X .......XX.X ",
326 " ..X.......X..X ",
327 " ...........X ",
328 " ...........X ",
329 " .........X ",
330 " .........X ",
331 " .......X ",
332 " .......X ",
333 " .....X ",
334 " .....X ",
335 " ...X ",
336 " ...X ",
337 " .X ",
338 " .X ",
339 " ",
340 " ",
341 " ",
342 " ",
343 "15,24"
344 };
345
346 static const char *cursor_uarrow[] =
347 {
348 /* width height num_colors chars_per_pixel */
349 " 32 32 3 1",
350 /* colors */
351 "X c #000000",
352 ". c #ffffff",
353 " c None",
354 /* pixels */
355 " ",
356 " ",
357 " ",
358 " ",
359 " . ",
360 " .X ",
361 " ...X ",
362 " ...X ",
363 " .....X ",
364 " .....X ",
365 " .......X ",
366 " .......X ",
367 " .........X ",
368 " .........X ",
369 " ...........X ",
370 " ...........X ",
371 " ..X.......X..X ",
372 " .X .......XX.X ",
373 " .......X XX ",
374 " .......X ",
375 " .......X ",
376 " .......X ",
377 " .......X ",
378 " .......X ",
379 " .......X ",
380 " XXXXXXX ",
381 " ",
382 " ",
383 " ",
384 " ",
385 " ",
386 " ",
387 "15,8"
388 };
389
390 static const char *cursor_default[] =
391 {
392 /* width height num_colors chars_per_pixel */
393 " 32 32 3 1",
394 /* colors */
395 "X c #000000",
396 ". c #ffffff",
397 " c None",
398 /* pixels */
399 " ",
400 " ",
401 " ",
402 " ",
403 " ",
404 " ",
405 " ",
406 " ",
407 " ",
408 " ",
409 " ",
410 " ",
411 " ..XX ",
412 " ....XX ",
413 " .....XX ",
414 " .......XX ",
415 " ........XX ",
416 " ..........XX ",
417 " ...........X ",
418 " ....XXXXXXXX ",
419 " ...X ",
420 " ...X ",
421 " ..X ",
422 " ..X ",
423 " .X ",
424 " .X ",
425 " ",
426 " ",
427 " ",
428 " ",
429 " ",
430 " ",
431 "12,12"
432 };
433
434 static const char *cursor_attach[] =
435 {
436 /* width height num_colors chars_per_pixel */
437 " 32 32 3 1",
438 /* colors */
439 "X c #000000",
440 ". c #ffffff",
441 " c None",
442 /* pixels */
443 " ",
444 " ",
445 " ",
446 " ",
447 " ",
448 " ",
449 " ",
450 " ",
451 " ",
452 " ",
453 " ",
454 " ",
455 " ",
456 " ...X ....X ....X ... ",
457 " XXX.X.XXXX.X.XXXX.X.XXX ",
458 " ..... ..... ..... ",
459 " .X.X .X.X .X.X ",
460 " ...X ....X ....X ... ",
461 " XXX XXXX XXXX XXX ",
462 " ",
463 " ",
464 " ",
465 " ",
466 " ",
467 " ",
468 " ",
469 " ",
470 " ",
471 " ",
472 " ",
473 " ",
474 " ",
475 "17,14"
476 };
477
478 static const char *cursor_attack[] =
479 {
480 /* width height num_colors chars_per_pixel */
481 " 32 32 3 1",
482 /* colors */
483 "X c #000000",
484 ". c #ffffff",
485 " c None",
486 /* pixels */
487 " ",
488 " ",
489 " ",
490 " . ",
491 " .X ",
492 " ....X.. ",
493 " ......X.... ",
494 " ...XXX.XXX... ",
495 " ..XX .X X.. ",
496 " ..X .X .. ",
497 " ..X XX .. ",
498 " ..X ..X ",
499 " ..X ..X ",
500 " ..X ..X ",
501 " ..X ..X ",
502 " ........X . ........X ",
503 " XXXXXXXX X XXXXXXXX ",
504 " ..X ..X ",
505 " ..X ..X ",
506 " ..X ..X ",
507 " .. .X ",
508 " ..X . ..X ",
509 " .. .X ..X ",
510 " .. .X ..X ",
511 " ... .X ..X ",
512 " X......X....X ",
513 " XX....X..XX ",
514 " XXX.XXX ",
515 " .X ",
516 " XX ",
517 " ",
518 " ",
519 "15,15"
520 };
521
522 static const char *cursor_bomb[] =
523 {
524 /* width height num_colors chars_per_pixel */
525 " 32 32 3 1",
526 /* colors */
527 "X c #000000",
528 ". c #ffffff",
529 " c None",
530 /* pixels */
531 " ",
532 " ",
533 " ",
534 " . . ",
535 " . . . ",
536 " XXX. ",
537 " XXXX . . ",
538 " XX . . ",
539 " XX ",
540 " ....X ",
541 " ....X ",
542 " .XXXXXX.XX ",
543 " ............X ",
544 " ..............X ",
545 " ................X ",
546 " ..................X ",
547 " ..................X ",
548 " ....................X ",
549 " ....................X ",
550 " ....................X ",
551 " ....................X ",
552 " ....................X ",
553 " ..................X ",
554 " ..................X ",
555 " ................X ",
556 " ..............X ",
557 " ............X ",
558 " ........XX ",
559 " XXXXXXXX ",
560 " ",
561 " ",
562 " ",
563 "16,16"
564 };
565
566 static const char *cursor_bridge[] =
567 {
568 /* width height num_colors chars_per_pixel */
569 " 32 32 3 1",
570 /* colors */
571 "X c #000000",
572 ". c #ffffff",
573 " c None",
574 /* pixels */
575 " ",
576 " ",
577 " .. ",
578 " .... ",
579 " ....... ",
580 " ......... ",
581 " ............ ",
582 " ............ .. ",
583 " X............ .. . ",
584 " X............ ..XX. ",
585 " X............ ..XXX. ",
586 " X............ ..XXXX. ",
587 " X..............XXXXX. ",
588 " ..X............XXXXXX. ",
589 " ....X..........XXXXX.. ",
590 " ....X.........XXXX...... ",
591 " .....X.......XXX......... ",
592 " .....X......XX............ ",
593 " ......X....XXXXX..........X ",
594 " ......X...XX..XXXX........X ",
595 " ........X. ..XXX .......X ",
596 ".........X..XXX .......X.. ",
597 " XX......X XX ..........X",
598 " XXX...X .........XX",
599 " XXXX .........X ",
600 " ........XX ",
601 " ..........X ",
602 " XX......XX ",
603 " XXX...X ",
604 " XXXX ",
605 " ",
606 " ",
607 "16,16"
608 };
609
610 static const char *cursor_build[] =
611 {
612 /* width height num_colors chars_per_pixel */
613 " 32 32 3 1",
614 /* colors */
615 "X c #000000",
616 ". c #ffffff",
617 " c None",
618 /* pixels */
619 " ",
620 " ",
621 " ",
622 " ",
623 " ",
624 " ",
625 " ",
626 " ",
627 " ...... ",
628 " .....XX..X ",
629 " .X.....X XXX ",
630 " .X......X ",
631 " X.......X ",
632 " .......XX ",
633 " .......X ",
634 " ......X.X ",
635 " .......X...X ",
636 " .......X ....X ",
637 " ....XX ....X ",
638 " ...X ....X ",
639 " .X ....X ",
640 " ....X ",
641 " ....X ",
642 " ...X ",
643 " ..X ",
644 " X ",
645 " ",
646 " ",
647 " ",
648 " ",
649 " ",
650 " ",
651 "15,15"
652 };
653
654 static const char *cursor_embark[] =
655 {
656 /* width height num_colors chars_per_pixel */
657 " 32 32 3 1",
658 /* colors */
659 "X c #000000",
660 ". c #ffffff",
661 " c None",
662 /* pixels */
663 " ",
664 " ",
665 " ",
666 " ",
667 " ",
668 " ...........X ",
669 " ...........X ",
670 " ...........X ",
671 " ...........X ",
672 " .................X ",
673 " ...............XX ",
674 " .............X ",
675 " ...........X ",
676 " X.........X ",
677 " ...XX.......XX...X ",
678 " ...XX.....XX...X ",
679 " ...XX...XX...X ",
680 " ...XX.XX...X ",
681 " ...XXX...X ",
682 " ...X...X ",
683 " .....X ",
684 " ...X ",
685 " .X ",
686 " ",
687 " ",
688 " ",
689 " ",
690 " ",
691 " ",
692 " ",
693 " ",
694 " ",
695 "16,22"
696 };
697
698 static const char *cursor_disembark[] =
699 {
700 /* width height num_colors chars_per_pixel */
701 " 32 32 3 1",
702 /* colors */
703 "X c #000000",
704 ". c #ffffff",
705 " c None",
706 /* pixels */
707 " ",
708 " ",
709 " ",
710 " ",
711 " ",
712 " ...........X ",
713 " ...........X ",
714 " ...........X ",
715 " ...........X ",
716 " .................X ",
717 " ...............XX ",
718 " .............X ",
719 " ...........X ",
720 " X.........X ",
721 " ...XX.......XX...X ",
722 " ...XX.....XX...X ",
723 " ...XX...XX...X ",
724 " ...XX.XX...X ",
725 " ...XXX...X ",
726 " ...X...X ",
727 " .....X ",
728 " ...X ",
729 " .X ",
730 " ",
731 " ",
732 " ",
733 " ",
734 " ",
735 " ",
736 " ",
737 " ",
738 " ",
739 "16,22"
740 };
741
742 static const char *cursor_fix[] =
743 {
744 /* width height num_colors chars_per_pixel */
745 " 32 32 3 1",
746 /* colors */
747 "X c #000000",
748 ". c #ffffff",
749 " c None",
750 /* pixels */
751 " ",
752 " ",
753 " ",
754 " ",
755 " ",
756 " ",
757 " ... ",
758 " ..X ",
759 " ..X ",
760 " ..X ",
761 " . ..X ",
762 " .X ..X ",
763 " .X X..X ",
764 " ..XXXX...X ",
765 " .........X ",
766 " .........X ",
767 " .....X ",
768 " .....XXXXX ",
769 " .........X ",
770 " .........X ",
771 " ...X ..X ",
772 " ..X .X ",
773 " ..X .X ",
774 " ..X ",
775 " ..X ",
776 " ..XXX ",
777 " ...X ",
778 " ",
779 " ",
780 " ",
781 " ",
782 " ",
783 "16,16"
784 };
785
786 static const char *cursor_guard[] =
787 {
788 /* width height num_colors chars_per_pixel */
789 " 32 32 3 1",
790 /* colors */
791 "X c #000000",
792 ". c #ffffff",
793 " c None",
794 /* pixels */
795 " ",
796 " ",
797 " ",
798 " ",
799 " ",
800 " ",
801 " ",
802 " ",
803 " ",
804 " .....X ..... ",
805 " .XXX.........XXX.X ",
806 " .X..XXXXXXXXX..X.X ",
807 " .X.............X.X ",
808 " .X.............X.X ",
809 " .X.............X.X ",
810 " .X............X.X ",
811 " .X...........X.X ",
812 " .X...........X.X ",
813 " .XX.........XX.X ",
814 " .X.........X.X ",
815 " .XX.......XX.X ",
816 " .XX.....XX.X ",
817 " .XX...XX.X ",
818 " ..XXX..X ",
819 " .....X ",
820 " .XX ",
821 " ",
822 " ",
823 " ",
824 " ",
825 " ",
826 " ",
827 "16,17"
828 };
829
830 static const char *cursor_jam[] =
831 {
832 /* width height num_colors chars_per_pixel */
833 " 32 32 3 1",
834 /* colors */
835 "X c #000000",
836 ". c #ffffff",
837 " c None",
838 /* pixels */
839 " ",
840 " ",
841 " ",
842 " ",
843 " ",
844 " ",
845 " .....X ",
846 " ...XXX...X ",
847 " ..XX XX..X ",
848 " ..X X..X ",
849 " .X ...X X.X ",
850 " ..X .X .X ..X ",
851 " .X .X .X .X ",
852 " .X .X .X .X .X ",
853 " .X .XX.XX.X .X ",
854 " ..X X...XX ..X ",
855 " .X ...X .X ",
856 " ..X .....X ..X ",
857 " .XX.....XX.X ",
858 " X.......XX ",
859 " .......X ",
860 " .........X ",
861 " .........X ",
862 " XXXXXXXXX ",
863 " ",
864 " ",
865 " ",
866 " ",
867 " ",
868 " ",
869 " ",
870 " ",
871 "15,15"
872 };
873
874 static const char *cursor_lockon[] =
875 {
876 /* width height num_colors chars_per_pixel */
877 " 32 32 3 1",
878 /* colors */
879 "X c #000000",
880 ". c #ffffff",
881 " c None",
882 /* pixels */
883 " ",
884 " ",
885 " ",
886 " ",
887 " ",
888 " ",
889 " .....X ",
890 " ...XXX...X ",
891 " ..XX XX..X ",
892 " ..X X..X ",
893 " .X ...X X.X ",
894 " ..X .X .X ..X ",
895 " .X .X .X .X ",
896 " .X .X .X .X .X ",
897 " .X .XX.XX.X .X ",
898 " ..X X...XX ..X ",
899 " .X ...X .X ",
900 " ..X .....X ..X ",
901 " .XX.....XX.X ",
902 " X.......XX ",
903 " .......X ",
904 " .........X ",
905 " .........X ",
906 " XXXXXXXXX ",
907 " ",
908 " ",
909 " ",
910 " ",
911 " ",
912 " ",
913 " ",
914 " ",
915 "15,15"
916 };
917
918 static const char *cursor_scout[] =
919 {
920 /* width height num_colors chars_per_pixel */
921 " 32 32 3 1",
922 /* colors */
923 "X c #000000",
924 ". c #ffffff",
925 " c None",
926 /* pixels */
927 " ",
928 " ",
929 " ",
930 " ",
931 " ",
932 " ",
933 " .....X ",
934 " ...XXX...X ",
935 " ..XX XX..X ",
936 " ..X X..X ",
937 " .X ...X X.X ",
938 " ..X .X .X ..X ",
939 " .X .X .X .X ",
940 " .X .X .X .X .X ",
941 " .X .XX.XX.X .X ",
942 " ..X X...XX ..X ",
943 " .X ...X .X ",
944 " ..X .....X ..X ",
945 " .XX.....XX.X ",
946 " X.......XX ",
947 " .......X ",
948 " .........X ",
949 " .........X ",
950 " XXXXXXXXX ",
951 " ",
952 " ",
953 " ",
954 " ",
955 " ",
956 " ",
957 " ",
958 " ",
959 "15,15"
960 };
961
962 static const char *cursor_menu[] =
963 {
964 /* width height num_colors chars_per_pixel */
965 " 32 32 3 1",
966 /* colors */
967 "X c #000000",
968 ". c #ffffff",
969 " c None",
970 /* pixels */
971 " ",
972 " ",
973 " ",
974 " ",
975 " ",
976 " ",
977 " ",
978 " ",
979 " ",
980 " ",
981 " ",
982 " ..XX ",
983 " ....XX ",
984 " .....XX ",
985 " .......XX ",
986 " ........XX ",
987 " ..........XX ",
988 " ........XX ",
989 " .....XX ",
990 " ...XX ",
991 " ...XX ",
992 " ..XX ",
993 " . X ",
994 " ",
995 " ",
996 " ",
997 " ",
998 " ",
999 " ",
1000 " ",
1001 " ",
1002 " ",
1003 "11,11"
1004 };
1005
1006 static const char *cursor_move[] =
1007 {
1008 /* width height num_colors chars_per_pixel */
1009 " 32 32 3 1",
1010 /* colors */
1011 "X c #000000",
1012 ". c #ffffff",
1013 " c None",
1014 /* pixels */
1015 " ",
1016 " ",
1017 " ",
1018 " ",
1019 " ",
1020 " ",
1021 " ",
1022 " . .....X . ",
1023 " ..X.XXXXX.X.. ",
1024 " ...XXX XX... ",
1025 " ....X.X .X.... ",
1026 " .....X.X .X..... ",
1027 " XXXXX.X .XXXXX ",
1028 " .X....X ....X.X ",
1029 " .XXXXXXX .X ",
1030 " .X .X ",
1031 " .X .X ",
1032 " .X .X ",
1033 " .X .X ",
1034 " .X.... ....X.X ",
1035 " XXXXX.X .XXXXX ",
1036 " .....X.X .X..... ",
1037 " ....X.X .X....X ",
1038 " ...XXX XX...X ",
1039 " ..X.X .X..X ",
1040 " .X .....X .X ",
1041 " XXXXX ",
1042 " ",
1043 " ",
1044 " ",
1045 " ",
1046 " ",
1047 "15,15"
1048 };
1049
1050 static const char *cursor_notpossible[] =
1051 {
1052 /* width height num_colors chars_per_pixel */
1053 " 32 32 3 1",
1054 /* colors */
1055 "X c #000000",
1056 ". c #ffffff",
1057 " c None",
1058 /* pixels */
1059 " ",
1060 " ",
1061 " ",
1062 " ",
1063 " ",
1064 " ",
1065 " ",
1066 " .X .X ",
1067 " ...X ...X ",
1068 " .....X .....X ",
1069 " .......X .......X ",
1070 " .......X .......X ",
1071 " .......X .......X ",
1072 " .......X.......X ",
1073 " .............X ",
1074 " ...........X ",
1075 " .........X ",
1076 " .......X ",
1077 " .........X ",
1078 " ...........X ",
1079 " .............X ",
1080 " .......X.......X ",
1081 " .......X .......X ",
1082 " .......X .......X ",
1083 " .......X .......X ",
1084 " .....X .....X ",
1085 " ...X ...X ",
1086 " .X .X ",
1087 " ",
1088 " ",
1089 " ",
1090 " ",
1091 "15,17"
1092 };
1093
1094 static const char *cursor_pickup[] =
1095 {
1096 /* width height num_colors chars_per_pixel */
1097 " 32 32 3 1",
1098 /* colors */
1099 "X c #000000",
1100 ". c #ffffff",
1101 " c None",
1102 /* pixels */
1103 " ",
1104 " ",
1105 " ",
1106 " .X .X ",
1107 " .X .X ",
1108 " .X.X.X ",
1109 " ...X ",
1110 " .X ",
1111 " ...X ",
1112 " .X.X.X ",
1113 " .X .X ",
1114 " .X.X.X ",
1115 " ...X ",
1116 " X.XX ",
1117 " .X.X.X ",
1118 " ..X.X..X ",
1119 " ...X.X...X ",
1120 " ....X.X....X ",
1121 " .....XXX.....X ",
1122 " ...XXXXXXX...X ",
1123 " .XXX XX.X ",
1124 " .X .X ",
1125 " .X .X ",
1126 " .X .X ",
1127 " .X .X ",
1128 " ..X ..X ",
1129 " ..X ..X ",
1130 " ..X ..X ",
1131 " .X .X ",
1132 " ",
1133 " ",
1134 " ",
1135 "15,20"
1136 };
1137
1138 static const char *cursor_seekrepair[] =
1139 {
1140 /* width height num_colors chars_per_pixel */
1141 " 32 32 3 1",
1142 /* colors */
1143 "X c #000000",
1144 ". c #ffffff",
1145 " c None",
1146 /* pixels */
1147 " ",
1148 " ",
1149 " ",
1150 " ",
1151 " ",
1152 " ",
1153 " ... ",
1154 " ..X X ",
1155 " ..X .X ",
1156 " ..X ..X ",
1157 " . ..X XXXX...X ",
1158 " .X ..X ........X ",
1159 " .X X..X .........X ",
1160 " ..XXXX...X .......... ",
1161 " .........X ......... ",
1162 " .........X ........ ",
1163 " .....X ... ",
1164 " .....XXXXX .. ",
1165 " .........X . ",
1166 " .........X ",
1167 " ...X ..X ",
1168 " ..X .X ",
1169 " ..X .X ",
1170 " ..X ",
1171 " ..X ",
1172 " ..XXX ",
1173 " ...X ",
1174 " ",
1175 " ",
1176 " ",
1177 " ",
1178 " ",
1179 "16,15"
1180 };
1181
1182 static const char *cursor_select[] =
1183 {
1184 /* width height num_colors chars_per_pixel */
1185 " 32 32 3 1",
1186 /* colors */
1187 "X c #000000",
1188 ". c #ffffff",
1189 " c None",
1190 /* pixels */
1191 " ",
1192 " ",
1193 " ",
1194 " ",
1195 " .....X .....X ",
1196 " .XXXXX XXX.X ",
1197 " .X .X ",
1198 " .X .X ",
1199 " .X .X ",
1200 " XX XX ",
1201 " ",
1202 " ",
1203 " ",
1204 " ",
1205 " ",
1206 " .X ",
1207 " XX ",
1208 " ",
1209 " ",
1210 " ",
1211 " ",
1212 " ",
1213 " . . ",
1214 " .X .X ",
1215 " .X .X ",
1216 " .X .X ",
1217 " .....X .....X ",
1218 " XXXXXX XXXXXX ",
1219 " ",
1220 " ",
1221 " ",
1222 " ",
1223 "15,15"
1224 };
1225
1226 static const struct
1227 {
1228 const char **image;
1229 CURSOR cursor_num;
1230 } cursors[CURSOR_MAX] =
1231 {
1232 { cursor_arrow, CURSOR_ARROW },
1233 { cursor_dest, CURSOR_DEST },
1234 { cursor_sight, CURSOR_SIGHT },
1235 { cursor_target, CURSOR_TARGET },
1236 { cursor_larrow, CURSOR_LARROW },
1237 { cursor_rarrow, CURSOR_RARROW },
1238 { cursor_darrow, CURSOR_DARROW },
1239 { cursor_uarrow, CURSOR_UARROW },
1240 { cursor_default, CURSOR_DEFAULT },
1241 { cursor_default, CURSOR_EDGEOFMAP },
1242 { cursor_attach, CURSOR_ATTACH },
1243 { cursor_attack, CURSOR_ATTACK },
1244 { cursor_bomb, CURSOR_BOMB },
1245 { cursor_bridge, CURSOR_BRIDGE },
1246 { cursor_build, CURSOR_BUILD },
1247 { cursor_embark, CURSOR_EMBARK },
1248 { cursor_disembark, CURSOR_DISEMBARK },
1249 { cursor_fix, CURSOR_FIX },
1250 { cursor_guard, CURSOR_GUARD },
1251 { cursor_jam, CURSOR_JAM },
1252 { cursor_lockon, CURSOR_LOCKON },
1253 { cursor_scout, CURSOR_SCOUT },
1254 { cursor_menu, CURSOR_MENU },
1255 { cursor_move, CURSOR_MOVE },
1256 { cursor_notpossible, CURSOR_NOTPOSSIBLE },
1257 { cursor_pickup, CURSOR_PICKUP },
1258 { cursor_seekrepair, CURSOR_SEEKREPAIR },
1259 { cursor_select, CURSOR_SELECT },
1260 };
1261
1262 /**
1263 init_system_ColorCursor()-- Create a colored mouse cursor image
1264 */
init_system_ColorCursor(CURSOR cur,const char * fileName)1265 SDL_Cursor *init_system_ColorCursor(CURSOR cur, const char *fileName)
1266 {
1267
1268 iV_Image *psSprite = (iV_Image *)malloc(sizeof(iV_Image));
1269 if (!psSprite)
1270 {
1271 debug(LOG_FATAL, "Could not allocate memory for cursor sprite. Exiting.");
1272 exit(-1);
1273 }
1274
1275 if (!iV_loadImage_PNG(fileName, psSprite))
1276 {
1277 debug(LOG_FATAL, "Could not load cursor sprite. Exiting.");
1278 exit(-1);
1279 }
1280
1281 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1282 uint32_t rmask = 0xff000000;
1283 uint32_t gmask = 0x00ff0000;
1284 uint32_t bmask = 0x0000ff00;
1285 uint32_t amask = 0x000000ff;
1286 #else
1287 uint32_t rmask = 0x000000ff;
1288 uint32_t gmask = 0x0000ff00;
1289 uint32_t bmask = 0x00ff0000;
1290 uint32_t amask = 0xff000000;
1291 #endif
1292
1293 SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(psSprite->bmp, psSprite->width, psSprite->height, psSprite->depth * 8, psSprite->width * 4, rmask, gmask, bmask, amask);
1294 SDL_Cursor *pointer = SDL_CreateColorCursor(surface, psSprite->width / 2, psSprite->height / 2); // We center the hotspot for all (FIXME ?)
1295 if (!pointer)
1296 {
1297 debug(LOG_FATAL, "Could not create cursor because %s", SDL_GetError());
1298 exit(-1);
1299 }
1300
1301 // free up image & surface data
1302 free(psSprite->bmp);
1303 free(psSprite);
1304 SDL_FreeSurface(surface);
1305
1306 return pointer;
1307 }
1308
1309 /**
1310 init_system_cursor32()-- Create a monochrome mouse cursor image
1311 */
init_system_cursor32(CURSOR cur)1312 SDL_Cursor *init_system_cursor32(CURSOR cur)
1313 {
1314 int i, row, col;
1315 uint8_t data[4 * 32];
1316 uint8_t mask[4 * 32];
1317 int hot_x, hot_y;
1318 const char **image;
1319 ASSERT(cur < CURSOR_MAX, "Attempting to load non-existent cursor: %u", (unsigned int)cur);
1320 ASSERT(cursors[cur].cursor_num == cur, "Bad cursor mapping");
1321 image = cursors[cur].image;
1322
1323 i = -1;
1324 for (row = 0; row < 32; ++row)
1325 {
1326 for (col = 0; col < 32; ++col)
1327 {
1328 if (col % 8)
1329 {
1330 data[i] <<= 1;
1331 mask[i] <<= 1;
1332 }
1333 else
1334 {
1335 ++i;
1336 data[i] = mask[i] = 0;
1337 }
1338 switch (image[4 + row][col])
1339 {
1340 case 'X':
1341 data[i] |= 0x01;
1342 mask[i] |= 0x01;
1343 break;
1344
1345 case '.':
1346 mask[i] |= 0x01;
1347 break;
1348
1349 case ' ':
1350 break;
1351 }
1352 }
1353 }
1354
1355 sscanf(image[4 + row], "%d,%d", &hot_x, &hot_y);
1356 return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
1357 }
1358
1359 /**
1360 wzSetCursor()-- Set the current cursor. Cursor is actually applied in wzApplyCursor() in mainLoop()
1361 */
wzSetCursor(CURSOR cur)1362 void wzSetCursor(CURSOR cur)
1363 {
1364 ASSERT(cur < CURSOR_MAX, "Specified cursor(%d) is over our limit of (%d)!", (int)cur, (int)CURSOR_MAX);
1365
1366 currentCursor = cur;
1367 }
1368
wzApplyCursor()1369 void wzApplyCursor()
1370 {
1371 if (!cursorsEnabled) return;
1372
1373 // If mouse cursor options change, change cursors (used to only work on mouse options screen for some reason)
1374 if (!(war_GetColouredCursor() ^ monoCursor))
1375 {
1376 sdlFreeCursors();
1377 war_GetColouredCursor() ? sdlInitColoredCursors() : sdlInitCursors();
1378 SDL_SetCursor(aCursors[currentCursor]);
1379 lastAppliedCursor = currentCursor;
1380 return;
1381 }
1382
1383 // If we are already using this cursor then return
1384 if (currentCursor == lastAppliedCursor)
1385 {
1386 return;
1387 }
1388
1389 SDL_SetCursor(aCursors[currentCursor]);
1390 lastAppliedCursor = currentCursor;
1391 }
1392
1393 /**
1394 sdlInitColoredCursors() --Setup the mouse cursor with bitmaps
1395 */
sdlInitColoredCursors()1396 void sdlInitColoredCursors()
1397 {
1398 monoCursor = false;
1399 aCursors[CURSOR_ARROW] = init_system_cursor32(CURSOR_ARROW);
1400 aCursors[CURSOR_DEST] = init_system_ColorCursor(CURSOR_DEST, "images/intfac/image_cursor_dest.png");
1401 aCursors[CURSOR_SIGHT] = init_system_cursor32(CURSOR_SIGHT);
1402 aCursors[CURSOR_TARGET] = init_system_cursor32(CURSOR_TARGET);
1403 aCursors[CURSOR_LARROW] = init_system_ColorCursor(CURSOR_LARROW, "images/intfac/image_cursor_larrow.png");
1404 aCursors[CURSOR_RARROW] = init_system_ColorCursor(CURSOR_RARROW, "images/intfac/image_cursor_rarrow.png");
1405 aCursors[CURSOR_DARROW] = init_system_ColorCursor(CURSOR_DARROW, "images/intfac/image_cursor_darrow.png");
1406 aCursors[CURSOR_UARROW] = init_system_ColorCursor(CURSOR_UARROW, "images/intfac/image_cursor_uarrow.png");
1407 aCursors[CURSOR_DEFAULT] = init_system_ColorCursor(CURSOR_DEFAULT, "images/intfac/image_cursor_default.png");
1408 aCursors[CURSOR_EDGEOFMAP] = init_system_cursor32(CURSOR_EDGEOFMAP);
1409 aCursors[CURSOR_ATTACH] = init_system_ColorCursor(CURSOR_ATTACH, "images/intfac/image_cursor_attach.png");
1410 aCursors[CURSOR_ATTACK] = init_system_ColorCursor(CURSOR_ATTACK, "images/intfac/image_cursor_attack.png");
1411 aCursors[CURSOR_BOMB] = init_system_ColorCursor(CURSOR_BOMB, "images/intfac/image_cursor_bomb.png");
1412 aCursors[CURSOR_BRIDGE] = init_system_ColorCursor(CURSOR_BRIDGE, "images/intfac/image_cursor_bridge.png");
1413 aCursors[CURSOR_BUILD] = init_system_ColorCursor(CURSOR_BUILD, "images/intfac/image_cursor_build.png");
1414 aCursors[CURSOR_EMBARK] = init_system_ColorCursor(CURSOR_EMBARK, "images/intfac/image_cursor_embark.png");
1415 aCursors[CURSOR_DISEMBARK] = init_system_ColorCursor(CURSOR_DISEMBARK, "images/intfac/image_cursor_disembark.png");
1416 aCursors[CURSOR_FIX] = init_system_ColorCursor(CURSOR_FIX, "images/intfac/image_cursor_fix.png");
1417 aCursors[CURSOR_GUARD] = init_system_ColorCursor(CURSOR_GUARD, "images/intfac/image_cursor_guard.png");
1418 aCursors[CURSOR_JAM] = init_system_ColorCursor(CURSOR_JAM, "images/intfac/image_cursor_ecm.png");
1419 aCursors[CURSOR_LOCKON] = init_system_ColorCursor(CURSOR_LOCKON, "images/intfac/image_cursor_lockon.png");
1420 aCursors[CURSOR_SCOUT] = init_system_ColorCursor(CURSOR_SCOUT, "images/intfac/image_cursor_scout.png");
1421 aCursors[CURSOR_MENU] = init_system_cursor32(CURSOR_MENU);
1422 aCursors[CURSOR_MOVE] = init_system_ColorCursor(CURSOR_MOVE, "images/intfac/image_cursor_move.png");
1423 aCursors[CURSOR_NOTPOSSIBLE] = init_system_ColorCursor(CURSOR_NOTPOSSIBLE, "images/intfac/image_cursor_notpos.png");
1424 aCursors[CURSOR_PICKUP] = init_system_ColorCursor(CURSOR_PICKUP, "images/intfac/image_cursor_pickup.png");
1425 aCursors[CURSOR_SEEKREPAIR] = init_system_ColorCursor(CURSOR_SEEKREPAIR, "images/intfac/image_cursor_repair.png");
1426 aCursors[CURSOR_SELECT] = init_system_ColorCursor(CURSOR_SELECT, "images/intfac/image_cursor_select.png");
1427 cursorsEnabled = true;
1428 }
1429
1430 /**
1431 sdlInitCursors() --Setup the mouse cursor with monochrome data
1432 */
sdlInitCursors()1433 void sdlInitCursors()
1434 {
1435 monoCursor = true;
1436 aCursors[CURSOR_ARROW] = init_system_cursor32(CURSOR_ARROW);
1437 aCursors[CURSOR_DEST] = init_system_cursor32(CURSOR_DEST);
1438 aCursors[CURSOR_SIGHT] = init_system_cursor32(CURSOR_SIGHT);
1439 aCursors[CURSOR_TARGET] = init_system_cursor32(CURSOR_TARGET);
1440 aCursors[CURSOR_LARROW] = init_system_cursor32(CURSOR_LARROW);
1441 aCursors[CURSOR_RARROW] = init_system_cursor32(CURSOR_RARROW);
1442 aCursors[CURSOR_DARROW] = init_system_cursor32(CURSOR_DARROW);
1443 aCursors[CURSOR_UARROW] = init_system_cursor32(CURSOR_UARROW);
1444 aCursors[CURSOR_DEFAULT] = init_system_cursor32(CURSOR_DEFAULT);
1445 aCursors[CURSOR_EDGEOFMAP] = init_system_cursor32(CURSOR_EDGEOFMAP);
1446 aCursors[CURSOR_ATTACH] = init_system_cursor32(CURSOR_ATTACH);
1447 aCursors[CURSOR_ATTACK] = init_system_cursor32(CURSOR_ATTACK);
1448 aCursors[CURSOR_BOMB] = init_system_cursor32(CURSOR_BOMB);
1449 aCursors[CURSOR_BRIDGE] = init_system_cursor32(CURSOR_BRIDGE);
1450 aCursors[CURSOR_BUILD] = init_system_cursor32(CURSOR_BUILD);
1451 aCursors[CURSOR_EMBARK] = init_system_cursor32(CURSOR_EMBARK);
1452 aCursors[CURSOR_DISEMBARK] = init_system_cursor32(CURSOR_DISEMBARK);
1453 aCursors[CURSOR_FIX] = init_system_cursor32(CURSOR_FIX);
1454 aCursors[CURSOR_GUARD] = init_system_cursor32(CURSOR_GUARD);
1455 aCursors[CURSOR_JAM] = init_system_cursor32(CURSOR_JAM);
1456 aCursors[CURSOR_LOCKON] = init_system_cursor32(CURSOR_LOCKON);
1457 aCursors[CURSOR_SCOUT] = init_system_cursor32(CURSOR_SCOUT);
1458 aCursors[CURSOR_MENU] = init_system_cursor32(CURSOR_MENU);
1459 aCursors[CURSOR_MOVE] = init_system_cursor32(CURSOR_MOVE);
1460 aCursors[CURSOR_NOTPOSSIBLE] = init_system_cursor32(CURSOR_NOTPOSSIBLE);
1461 aCursors[CURSOR_PICKUP] = init_system_cursor32(CURSOR_PICKUP);
1462 aCursors[CURSOR_SEEKREPAIR] = init_system_cursor32(CURSOR_SEEKREPAIR);
1463 aCursors[CURSOR_SELECT] = init_system_cursor32(CURSOR_SELECT);
1464 cursorsEnabled = true;
1465 }
1466
sdlFreeCursors()1467 void sdlFreeCursors()
1468 {
1469 unsigned int i;
1470 for (i = 0 ; i < ARRAY_SIZE(aCursors); ++i)
1471 {
1472 SDL_FreeCursor(aCursors[i]);
1473 aCursors[i] = nullptr;
1474 }
1475 cursorsEnabled = false;
1476 }
1477