1 #include <setjmp.h>
2 #include "config.h"
3 #include "copyright.h"
4
5 #include <stdio.h>
6 #include <math.h>
7 #include <sys/types.h>
8 #include <time.h>
9 #include INC_SYS_TIME
10 #include INC_SYS_SELECT
11 #include INC_STRINGS
12 #include <signal.h>
13 #include <errno.h>
14
15 #include "Wlib.h"
16 #include "defs.h"
17 #include "struct.h"
18 #include "data.h"
19 #include "packets.h"
20
21 #include "cowmain.h"
22 #include "defaults.h"
23 #include "defwin.h"
24 #include "docwin.h"
25 #include "helpwin.h"
26 #include "inform.h"
27 #include "interface.h"
28 #include "macrowin.h"
29 #include "map.h"
30 #include "netstatopt.h"
31 #include "option.h"
32 #include "pingstats.h"
33 #include "playback.h"
34 #include "playerlist.h"
35 #include "redraw.h"
36 #include "senddist.h"
37 #include "short.h"
38 #include "smessage.h"
39 #include "socket.h"
40 #include "spopt.h"
41 #include "tools.h"
42 #include "war.h"
43 #include "warning.h"
44 #include "udpopt.h"
45
46 #include "input.h"
47
48 static void detmine(void);
49 static void keyaction(W_Event * data);
50
51 int detallow = 1; /* flag used to figure out *
52
53 *
54 *
55 * * if we're allowing det */
56
57 #ifdef DOC_WIN
58 static int docline = 0;
59 static int xtrekrcline = 0;
60
61 #endif
62
63 int opened_info = -2; /* counter for infowin popup, 6/1/93 LAB */
64
65 void doMacro(W_Event *);
66
67 #ifdef THREADED
68 void input2();
69 extern jmp_buf env;
70
71 #endif
72
73 struct obtype *gettarget(W_Window ww, int x, int y, int targtype), *target;
74 unsigned char key = ' ';
75
76 /* this used to be 177 for an unknown reason...I think it may * have included
77 * various control characters. We don't support * those anyway right?? - jn */
78 #define MAXKEY 224
79 #define MAXASCII 128
80
81 /* this method of avoiding a massive switch should represent * massive
82 * performance gains... instead of having to test * n/2 times for n different
83 * keys, the key is run directly * via an array of input functions whose
84 * index happens * to coorespond to the value of input char. - jn */
85 static void emptyKey(void), Key32(void), Key33(void), Key34(W_Event * data),
86 Key35(void), Key36(void), Key37(void), Key38(void), Key39(void),
87 Key40(void), Key41(W_Event * data), Key42(void), Key43(void), Key44(void),
88 Key45(void), Key46(void), Key47(void), Key48(void), Key49(void),
89 Key50(void), Key51(void), Key52(void), Key53(void), Key54(void),
90 Key55(void), Key56(void), Key57(void), Key58(void), Key59(W_Event * data),
91 Key60(void), Key61(void), Key62(void), Key63(void), Key64(void),
92 Key65(W_Event * data), Key66(void), Key67(void), Key68(void), Key69(W_Event * data),
93 Key70(W_Event * data), Key71(W_Event * data), Key72(W_Event * data),
94 Key73(W_Event * data), Key74(W_Event * data), Key75(void), Key76(void),
95 Key77(W_Event * data), Key78(void), Key79(void), Key80(void), Key81(void),
96 Key82(void), Key83(void), Key84(W_Event * data), Key85(void), Key86(void),
97 Key87(W_Event * data), Key88(void), Key89(W_Event * data), Key90(W_Event * data),
98 Key91(void), Key92(void), Key93(void), Key94(W_Event * data), Key95(W_Event * data),
99 Key96(void), Key98(void), Key99(void), Key100(void),
100 Key101(void), Key102(W_Event * data), Key103(W_Event * data), Key104(void),
101 Key105(W_Event * data), Key106(W_Event * data), Key107(W_Event * data),
102 Key108(W_Event * data), Key110(W_Event * data), Key111(void),
103 Key112(W_Event * data), Key113(void), Key114(void), Key115(void),
104 Key116(W_Event * data), Key117(void), Key118(W_Event * data), Key119(void),
105 Key120(void), Key121(W_Event * data), Key122(void), Key123(void),
106 Key124(void), Key125(void), Key126(W_Event * data), Key127(W_Event * data);
107 void Key109(void);
108
109 /* control keys */
110 static void Key131(W_Event * data), Key144(W_Event * data), Key145(W_Event * data),
111 Key146(W_Event * data), Key147(W_Event * data), Key148(W_Event * data),
112 Key149(W_Event * data), Key150(W_Event * data), Key151(W_Event * data),
113 Key152(W_Event * data), Key153(W_Event * data), Key160(W_Event * data),
114 Key162(W_Event * data), Key163(W_Event * data), Key175(W_Event * data),
115 Key180(W_Event * data), Key194(W_Event * data), Key195(W_Event * data),
116 Key197(W_Event * data), Key198(W_Event * data), Key200(W_Event * data),
117 Key206(W_Event * data), Key207(W_Event * data), Key204(W_Event * data),
118 Key205(W_Event * data), Key208(W_Event * data), Key212(W_Event * data);
119
120 typedef struct
121 {
122 void (*handler) ();
123 }
124 key_handler_type;
125
126 key_handler_type key_handlers[MAXKEY] =
127 {
128 { emptyKey }, /* \0 */
129 { emptyKey }, /* 1 */
130 { emptyKey }, /* 2 */
131 { emptyKey }, /* 3 */
132 { emptyKey }, /* 4 */
133 { emptyKey }, /* 5 */
134 { emptyKey }, /* 6 */
135 { emptyKey }, /* 7 */
136 { emptyKey }, /* 8 */
137 { emptyKey }, /* 9 */
138 { emptyKey }, /* 10 */
139 { emptyKey }, /* 11 */
140 { emptyKey }, /* 12 */
141 { emptyKey }, /* 13 */
142 { emptyKey }, /* 14 */
143 { emptyKey }, /* 15 */
144 { emptyKey }, /* 16 */
145 { emptyKey }, /* 17 */
146 { emptyKey }, /* 18 */
147 { emptyKey }, /* 19 */
148 { emptyKey }, /* 20 */
149 { emptyKey }, /* 21 */
150 { emptyKey }, /* 22 */
151 { emptyKey }, /* 23 */
152 { emptyKey }, /* 24 */
153 { emptyKey }, /* 25 */
154 { emptyKey }, /* 26 */
155 { emptyKey }, /* 27 */
156 { emptyKey }, /* 28 */
157 { emptyKey }, /* 29 */
158 { emptyKey }, /* 30 */
159 { emptyKey }, /* 31 */
160
161 { Key32 }, /* space */
162 { Key33 }, /* ! */
163 { Key34 }, /* " */
164 { Key35 }, /* # */
165 { Key36 }, /* $ */
166 { Key37 }, /* % */
167 { Key38 }, /* & */
168 { Key39 }, /* ' */
169 { Key40 }, /* ( */
170 { Key41 }, /* ) */
171 { Key42 }, /* * */
172 { Key43 }, /* + */
173 { Key44 }, /* , */
174 { Key45 }, /* - */
175 { Key46 }, /* . */
176 { Key47 }, /* / */
177 { Key48 }, /* 0 */
178 { Key49 }, /* 1 */
179 { Key50 }, /* 2 */
180 { Key51 }, /* 3 */
181 { Key52 }, /* 4 */
182 { Key53 }, /* 5 */
183 { Key54 }, /* 6 */
184 { Key55 }, /* 7 */
185 { Key56 }, /* 8 */
186 { Key57 }, /* 9 */
187 { Key58 }, /* : */
188 { Key59 }, /* ; */
189 { Key60 }, /* < */
190 { Key61 }, /* = */
191 { Key62 }, /* > */
192 { Key63 }, /* ? - you know this is *
193 * * boring as hell... */
194 { Key64 }, /* @ */
195 { Key65 }, /* A */
196 { Key66 }, /* B */
197 { Key67 }, /* C */
198 { Key68 }, /* D */
199 { Key69 }, /* E */
200 { Key70 }, /* F */
201 { Key71 }, /* G */
202 { Key72 }, /* H */
203 { Key73 }, /* I */
204 { Key74 }, /* J */
205 { Key75 }, /* K */
206 { Key76 }, /* L */
207 { Key77 }, /* M */
208 { Key78 }, /* N */
209 { Key79 }, /* O */
210 { Key80 }, /* P */
211 { Key81 }, /* Q */
212 { Key82 }, /* R */
213 { Key83 }, /* S */
214 { Key84 }, /* T */
215 { Key85 }, /* U */
216 { Key86 }, /* V */
217 { Key87 }, /* W */
218 { Key88 }, /* X */
219 { Key89 }, /* Y */
220 { Key90 }, /* Z */
221 { Key91 }, /* [ */
222 { Key92 }, /* \ */
223 { Key93 }, /* ] - ascii is fucked... */
224 { Key94 }, /* ^ */
225 { Key95 }, /* _ */
226 { Key96 }, /* ` */
227 { emptyKey }, /* a */
228 { Key98 }, /* b */
229 { Key99 }, /* c */
230 { Key100 }, /* d */
231 { Key101 }, /* e */
232 { Key102 }, /* f */
233 { Key103 }, /* g */
234 { Key104 }, /* h */
235 { Key105 }, /* i */
236 { Key106 }, /* j */
237 { Key107 }, /* k */
238 { Key108 }, /* l */
239 { Key109 }, /* m */
240 { Key110 }, /* n */
241 { Key111 }, /* o */
242 { Key112 }, /* p */
243 { Key113 }, /* q */
244 { Key114 }, /* r */
245 { Key115 }, /* s */
246 { Key116 }, /* t */
247 { Key117 }, /* u */
248 { Key118 }, /* v */
249 { Key119 }, /* w */
250 { Key120 }, /* x */
251 { Key121 }, /* y */
252 { Key122 }, /* z */
253 { Key123 }, /* { */
254 { Key124 }, /* | */
255 { Key125 }, /* } - my wife was once * *
256 * bitten by a lhama */
257 { Key126 }, /* ~ */
258 { Key127 }, /* delete */
259 { emptyKey }, /* 128 */
260 { emptyKey }, /* 31 */
261 { emptyKey }, /* 31 */
262 { Key131 }, /* ^# */
263 { emptyKey }, /* 31 */
264 { emptyKey }, /* 31 */
265 { emptyKey }, /* 31 */
266 { emptyKey }, /* 31 */
267 { emptyKey }, /* 31 */
268 { emptyKey }, /* 31 */
269 { emptyKey }, /* 31 */
270 { emptyKey }, /* 31 */
271 { emptyKey }, /* 31 */
272 { emptyKey }, /* 31 */
273 { emptyKey }, /* 31 */
274 { emptyKey }, /* 31 */
275 { Key144 }, /* ^0 */
276 { Key145 }, /* ^1 */
277 { Key146 }, /* ^2 */
278 { Key147 }, /* ^3 */
279 { Key148 }, /* ^4 */
280 { Key149 }, /* ^5 */
281 { Key150 }, /* ^6 */
282 { Key151 }, /* ^7 */
283 { Key152 }, /* ^8 */
284 { Key153 }, /* ^9 */
285 { emptyKey }, /* 31 */
286 { emptyKey }, /* 31 */
287 { emptyKey }, /* 31 */
288 { emptyKey }, /* 31 */
289 { emptyKey }, /* 31 */
290 { emptyKey }, /* 31 */
291 { Key160 }, /* ^@ */
292 { emptyKey }, /* 31 */
293 { Key162 }, /* ^B */
294 { Key163 }, /* ^C */
295 { emptyKey }, /* 31 */
296 { emptyKey }, /* 31 */
297 { emptyKey }, /* 31 */
298 { emptyKey }, /* 31 */
299 { emptyKey }, /* 31 */
300 { emptyKey }, /* 31 */
301 { emptyKey }, /* 31 */
302 { emptyKey }, /* 31 */
303 { emptyKey }, /* 31 */
304 { emptyKey }, /* 31 */
305 { emptyKey }, /* 31 */
306 { Key175 }, /* ^O */
307 { emptyKey }, /* 31 */
308 { emptyKey }, /* 31 */
309 { emptyKey }, /* 31 */
310 { emptyKey }, /* 31 */
311 { Key180 }, /* ^T */
312 { emptyKey }, /* 31 */
313 { emptyKey }, /* 31 */
314 { emptyKey }, /* 31 */
315 { emptyKey }, /* 31 */
316 { emptyKey }, /* 31 */
317 { emptyKey }, /* 31 */
318 { emptyKey }, /* 31 */
319 { emptyKey }, /* 31 */
320 { emptyKey }, /* 31 */
321 { emptyKey }, /* 31 */
322 { emptyKey }, /* 31 */
323 { emptyKey }, /* 31 */
324 { emptyKey }, /* 31 */
325 { Key194 }, /* ^b */
326 { Key195 }, /* ^c */
327 { emptyKey }, /* 31 */
328 { Key197 }, /* ^e */
329 { Key198 }, /* ^f */
330 { emptyKey }, /* 31 */
331 { Key200 }, /* ^h */
332 { emptyKey }, /* 31 */
333 { emptyKey }, /* 31 */
334 { emptyKey }, /* 31 */
335 { Key204 }, /* ^l */
336 { Key205 }, /* ^m */
337 { Key206 }, /* ^n */
338 { Key207 }, /* ^o */
339 { Key208 }, /* ^p */
340 { emptyKey }, /* 31 */
341 { emptyKey }, /* 31 */
342 { emptyKey }, /* 31 */
343 { Key212 }, /* ^t */
344 { emptyKey }, /* 31 */
345 { emptyKey }, /* 31 */
346 { emptyKey }, /* 31 */
347 { emptyKey }, /* 31 */
348 { emptyKey }, /* 31 */
349 { emptyKey }, /* 31 */
350 { emptyKey }, /* 31 */
351 { emptyKey }, /* 31 */
352 { emptyKey }, /* 31 */
353 { emptyKey }, /* 31 */
354 { emptyKey }, /* 223 */
355 };
356
357 unsigned char
getctrlkey(unsigned char ** s)358 getctrlkey(unsigned char **s)
359 {
360 unsigned char *str = *s;
361 unsigned char c;
362
363 /* Character is control key. */
364 if (*str == '^')
365 {
366 str++;
367 /* check for '^' key being specified with "^^" */
368 if (*str != '^')
369 c = *str + 96;
370 else
371 c = *str;
372 }
373 else
374 c = *str;
375 str++;
376 *s = str;
377 return (c);
378 }
379
380 extern struct shipdef *myshipdef;
381
initkeymap(void)382 void initkeymap(void)
383 {
384 unsigned char *str;
385
386 /* in the future let me strongly recommed we move keymap * completely * *
387 * outside of the stats structure. - jn */
388
389
390 if ((str = myshipdef->keymap) != NULL)
391 {
392 while (*str != '\0')
393 {
394 if (*str >= 32 && *str < 128)
395 {
396 mystats->st_keymap[*str - 32] = *(str + 1);
397 }
398 str += 2;
399 }
400 }
401
402 /* See if we can get macroKey to work. What a hack -SAC */
403 if ((str = (unsigned char *) getdefault("macroKey")) != NULL)
404 {
405 unsigned char *p;
406
407 if (strlen((char *)str) == 1)
408 {
409 /* This is a little pointless, but it'll preform as per * the *
410 * documentation */
411 mystats->st_keymap[*str - 32] = 'X';
412 }
413 else if (!strcmpi((char *) str, "TAB"))
414 {
415 p = (unsigned char *) "^i";
416 mystats->st_keymap[getctrlkey(&p) - 32] = 'X';
417 }
418 else if (!strcmpi((char *) str, "ESC"))
419 {
420 p = (unsigned char *) "^[";
421 mystats->st_keymap[getctrlkey(&p) - 32] = 'X';
422 }
423 }
424
425 if ((str = myshipdef->ckeymap) != NULL)
426 {
427 unsigned char c1, c2;
428
429 while (*str != '\0')
430 {
431
432 if (*str >= 32 && *str < MAXASCII)
433 {
434 c1 = getctrlkey(&str) - 32;
435 c2 = getctrlkey(&str);
436 mystats->st_keymap[c1] = c2;
437 }
438
439 }
440 }
441
442 #ifdef MOUSE_AS_SHIFT
443 if ((str = (unsigned char *) getdefault("b1keymap")) != NULL)
444 {
445 b1_as_shift = 1;
446 while (*str != '\0')
447 {
448 if (*str >= 32 && *str < 176)
449 {
450 mystats->st_keymap[*str - 32 + 192] = *(str + 1);
451 }
452 str += 2;
453 }
454 }
455
456 if ((str = (unsigned char *) getdefault("b2keymap")) != NULL)
457 {
458 b2_as_shift = 1;
459 while (*str != '\0')
460 {
461 if (*str >= 32 && *str < 176)
462 {
463 mystats->st_keymap[*str - 32 + 288] = *(str + 1);
464 }
465 str += 2;
466 }
467 }
468
469 if ((str = (unsigned char *) getdefault("b3keymap")) != NULL)
470 {
471 b3_as_shift = 1;
472 while (*str != '\0')
473 {
474 if (*str >= 32 && *str < 176)
475 {
476 mystats->st_keymap[*str - 32 + 384] = *(str + 1);
477 }
478 str += 2;
479 }
480 }
481 #endif
482
483 /* note: not stored on server */
484 if ((str = myshipdef->buttonmap) != NULL)
485 {
486 while (*str != '\0')
487 {
488 switch (*str++)
489 {
490 case '1':
491 buttonmap[1] = getctrlkey(&str);
492 break;
493 case '2':
494 buttonmap[2] = getctrlkey(&str);
495 break;
496 case '3':
497 buttonmap[3] = getctrlkey(&str);
498 break;
499
500 case 'd':
501 buttonmap[4] = getctrlkey(&str);
502 break;
503 case 'e':
504 buttonmap[5] = getctrlkey(&str);
505 break;
506 case 'f':
507 buttonmap[6] = getctrlkey(&str);
508 break;
509 case 'g':
510 buttonmap[7] = getctrlkey(&str);
511 break;
512
513 #ifdef SHIFTED_MOUSE
514 case '4':
515 buttonmap[9] = getctrlkey(&str);
516 break;
517 case '5':
518 buttonmap[10] = getctrlkey(&str);
519 break;
520 case '6':
521 buttonmap[11] = getctrlkey(&str);
522 break;
523
524 case 'h':
525 buttonmap[12] = getctrlkey(&str);
526 break;
527 case 'i':
528 buttonmap[13] = getctrlkey(&str);
529 break;
530 case 'j':
531 buttonmap[14] = getctrlkey(&str);
532 break;
533 case 'k':
534 buttonmap[15] = getctrlkey(&str);
535 break;
536
537
538 case '7':
539 buttonmap[17] = getctrlkey(&str);
540 break;
541 case '8':
542 buttonmap[18] = getctrlkey(&str);
543 break;
544 case '9':
545 buttonmap[19] = getctrlkey(&str);
546 break;
547
548 case 'l':
549 buttonmap[20] = getctrlkey(&str);
550 break;
551 case 'm':
552 buttonmap[21] = getctrlkey(&str);
553 break;
554 case 'n':
555 buttonmap[22] = getctrlkey(&str);
556 break;
557 case 'o':
558 buttonmap[23] = getctrlkey(&str);
559 break;
560
561 case 'a':
562 buttonmap[25] = getctrlkey(&str);
563 break;
564 case 'b':
565 buttonmap[26] = getctrlkey(&str);
566 break;
567 case 'c':
568 buttonmap[27] = getctrlkey(&str);
569 break;
570
571 case 'p':
572 buttonmap[28] = getctrlkey(&str);
573 break;
574 case 'q':
575 buttonmap[29] = getctrlkey(&str);
576 break;
577 case 'r':
578 buttonmap[30] = getctrlkey(&str);
579 break;
580 case 's':
581 buttonmap[31] = getctrlkey(&str);
582 break;
583
584 #endif
585
586 default:
587 fprintf(stderr, "%c ignored in buttonmap\n", *(str - 1));
588 break;
589 }
590 }
591 }
592
593 }
594
595 RETSIGTYPE
detsetallow(int _dummy)596 detsetallow(int _dummy)
597 {
598 detallow = 1;
599 }
600
601 #ifdef THREADED
input()602 void input()
603 {
604 W_Event event;
605
606 /* Under Windows we spawn off a separate thread to handle network *
607 * interaction; this is because it would require some awkward rewrites to *
608 * integrate event detection and handling into the select() mechanism. It *
609 * probably also increases performance */
610 THREAD(input2);
611
612 while (1)
613 {
614 if (!W_WaitForEvent()) /* W_WaitForEvent returns 0
615 * * if W_TerminateWait is *
616 * called */
617 break;
618 process_event();
619 }
620
621 printf("Resetting game\n");
622
623 while (W_EventsPending())
624 W_NextEvent(&event);
625
626 longjmp(env, 0);
627 }
628
input2()629 void input2()
630 #else
631 void input()
632 #endif
633 {
634 fd_set readfds;
635 #ifndef HAVE_WIN32
636 int xsock = W_Socket();
637 #endif
638 struct timeval timeout;
639 int retval;
640 int flush = 0;
641
642 while (1) {
643 FD_ZERO(&readfds);
644 #ifndef HAVE_WIN32
645 FD_SET(xsock, &readfds);
646 #endif
647 if (!isServerDead()) {
648 FD_SET(sock, &readfds);
649 if (udpSock >= 0)
650 FD_SET(udpSock, &readfds);
651 } else {
652 warning("Lost connection to server, press q to quit.");
653 redrawall = 1;
654 redraw();
655 flush++;
656 }
657
658 timeout.tv_sec = 1;
659 timeout.tv_usec = 100000;
660 retval = SELECT(max_fd, &readfds, 0, 0, &timeout);
661 if (retval == 0) {
662 warning("Stall in data stream from server!");
663 redrawall = 1;
664 redraw();
665 flush++;
666 } else if (retval > 0) {
667 #ifndef THREADED
668 #ifndef HAVE_WIN32
669 /* keyboard, mouse, and expose events from the X server
670 cause the X socket to be readable, so we must direct Xlib
671 to read them (W_EventsQueuedCk), then we process them. */
672 if (FD_ISSET(xsock, &readfds)) {
673 while (W_EventsQueuedCk())
674 process_event();
675 flush++;
676 }
677 #else
678 if (W_EventsPending()) {
679 process_event();
680 flush++;
681 }
682 #endif /* !HAVE_WIN32 */
683 #endif /* !THREADED */
684 /* read from server */
685 if (FD_ISSET(sock, &readfds) ||
686 (udpSock >= 0 && FD_ISSET(udpSock, &readfds))) {
687 intrupt(&readfds);
688 flush++;
689 if (isServerDead()) {
690 warning("Lost connection to server!");
691 }
692
693 /* manage expiry of info window every server update */
694 if (keepInfo > 0 && opened_info != -2) { /* 6/1/93 LAB */
695 opened_info--;
696 if (opened_info < 0 && infomapped) destroyInfo();
697 }
698
699 }
700 }
701
702 if (flush) {
703 W_Flush();
704 flush = 0;
705 }
706 }
707 }
708
process_event(void)709 int process_event(void)
710 {
711 W_Event data;
712 int loop = 0;
713 W_Callback handler;
714
715 do
716 {
717 loop++;
718
719 if (!W_SpNextEvent(&data))
720 continue; /* continues at loop bottom */
721
722 switch ((int) data.type)
723 {
724 case W_EV_KEY:
725 if ((handler = W_GetWindowKeyDownHandler(data.Window)) != NULL)
726 (*handler) (&data);
727
728 if (data.Window == messagew)
729 break;
730 if (isServerDead()) {
731 if (data.key == 'q') terminate(EXIT_DISCONNECTED);
732 }
733 #ifdef DOC_WIN
734 else if (data.Window == docwin)
735 switch (data.key)
736 {
737 case 'f':
738 docline += 28;
739
740 if (docline >= maxdoclines)
741 docline = maxdoclines - 28;
742
743 showdocs(docline);
744 break;
745 case 'b':
746 docline -= 28;
747
748 if (docline < 0)
749 docline = 0;
750
751 showdocs(docline);
752 break;
753 case 'F':
754 docline += 4;
755
756 if (docline >= maxdoclines)
757 docline = maxdoclines - 28;
758
759 showdocs(docline);
760 break;
761 case 'B':
762 docline -= 4;
763
764 if (docline < 0)
765 docline = 0;
766
767 showdocs(docline);
768 break;
769 default:
770 data.Window = w;
771 keyaction(&data);
772 break;
773 }
774 else if (data.Window == xtrekrcwin)
775 switch (data.key)
776 {
777 case 'f':
778 xtrekrcline += 28;
779
780 if (xtrekrcline >= maxxtrekrclines)
781 xtrekrcline = maxxtrekrclines - 28;
782
783 showxtrekrc(xtrekrcline);
784 break;
785 case 'b':
786 xtrekrcline -= 28;
787
788 if (xtrekrcline < 0)
789 xtrekrcline = 0;
790
791 showxtrekrc(xtrekrcline);
792 break;
793 case 'F':
794 xtrekrcline += 4;
795
796 if (xtrekrcline >= maxxtrekrclines)
797 xtrekrcline = maxxtrekrclines - 28;
798
799 showxtrekrc(xtrekrcline);
800 break;
801 case 'B':
802 xtrekrcline -= 4;
803
804 if (xtrekrcline < 0)
805 xtrekrcline = 0;
806
807 showxtrekrc(xtrekrcline);
808 break;
809 default:
810 data.Window = w;
811 keyaction(&data);
812 break;
813 }
814 #endif
815
816 else if (messageon)
817 smessage(data.key);
818 else
819 keyaction(&data);
820 break;
821
822 #ifdef MOTION_MOUSE
823 case W_EV_CM_BUTTON:
824 #endif
825
826 case W_EV_BUTTON:
827 if ((handler = W_GetWindowButtonHandler(data.Window)) != NULL)
828 (*handler) (&data);
829 else
830 buttonaction(&data);
831 break;
832
833 case W_EV_EXPOSE:
834 if ((handler = W_GetWindowExposeHandler(data.Window)) != NULL)
835 (*handler) (&data);
836 else if (data.Window == mapw)
837 redrawall = 1;
838 else if (data.Window == warnw)
839 W_ClearWindow(warnw);
840 else if (data.Window == messagew) {
841 DisplayMessage();
842 }
843
844 #ifdef XTREKRC_HELP
845 else if (defWin && (data.Window == defWin))
846 showdef();
847 #endif
848
849 #ifdef DOC_WIN
850 else if (docwin && (data.Window == docwin))
851 showdocs(docline);
852 else if (xtrekrcwin && (data.Window == xtrekrcwin))
853 showxtrekrc(xtrekrcline);
854 #endif
855
856 break;
857
858 case W_EV_CLOSED:
859 if (data.Window == baseWin) {
860 fprintf(stderr, "you quit, by closing the play window in play\n");
861 fastQuit = 1;
862 sendQuitReq();
863 }
864 default:
865 break;
866 }
867 }
868 while (W_EventsQueued());
869 return loop;
870 }
871
keyaction(W_Event * data)872 static void keyaction(W_Event * data)
873 {
874 fastQuit = 0; /* any event, cancel * *
875 * fastquit! */
876
877 /* remap events in other windows to local window */
878 if (data->Window != mapw && data->Window != w && data->Window != infow
879 && data->Window != scanw)
880 {
881 data->Window = w;
882 data->x = data->y = TWINSIDE / 2;
883 }
884
885 key = data->key;
886
887 /* remap events in information window to the surrounding game window */
888 if (data->Window == infow)
889 {
890 int x, y;
891
892 if (findMouseInWin(&x, &y, w))
893 { /* local window */
894 data->Window = w;
895 data->x = x;
896 data->y = y;
897 }
898 else if (findMouseInWin(&x, &y, mapw))
899 { /* galactic window */
900 data->Window = mapw;
901 data->x = x;
902 data->y = y;
903 }
904 }
905
906
907 /* this may represent a considerable efficiency improvement */
908 /* removes the need for an INDEX and a couple tests */
909 if (localflags & (PFREFIT))
910 {
911 switch (key)
912 {
913 case 'c':
914 sendRefitReq(CRUISER);
915 localflags &= ~(PFREFIT);
916 return;
917 break;
918 case 'o':
919 sendRefitReq(STARBASE);
920 localflags &= ~(PFREFIT);
921 return;
922 break;
923 case 'a':
924 sendRefitReq(ASSAULT);
925 localflags &= ~(PFREFIT);
926 return;
927 break;
928 case 'd':
929 sendRefitReq(DESTROYER);
930 localflags &= ~(PFREFIT);
931 return;
932 break;
933 case 'g':
934 sendRefitReq(SGALAXY);
935 localflags &= ~(PFREFIT);
936 return;
937 break;
938 case 'b':
939 sendRefitReq(BATTLESHIP);
940 localflags &= ~(PFREFIT);
941 return;
942 break;
943 case 's':
944 sendRefitReq(SCOUT);
945 localflags &= ~(PFREFIT);
946 return;
947 break;
948 case '*':
949 sendRefitReq(ATT);
950 localflags &= ~(PFREFIT);
951 return;
952 break;
953 default:
954 localflags &= ~(PFREFIT);
955 return;
956 break;
957 }
958 }
959
960 #ifdef RECORDGAME
961 if (playback)
962 switch(key)
963 {
964 case 0x8:
965 case 0xd:
966 pbsetspeed(key);
967 return;
968 }
969 #endif
970
971 if (key >= 32 && key < MAXKEY)
972 {
973 key = mystats->st_keymap[key - 32];
974 }
975 else
976 {
977 fprintf(stderr, "input.c: keyaction() key %d outside range\n", key);
978 W_Beep();
979 return;
980 }
981
982 #ifdef RECORDGAME
983 /* If playing a recorded game, do not use regular keys. */
984 /* What follows is a hardcoded list of commands */
985 if (playback)
986 {
987 extern int pb_sequence_count;
988 struct obtype *target;
989
990 switch (key)
991 {
992 case 'Q':
993 case 'q':
994 /* Instant Quit */
995 terminate(0);
996 break;
997 case ' ':
998 case '0':
999 case '1':
1000 case '2':
1001 case '3':
1002 case '4':
1003 case '5':
1004 case '6':
1005 case '7':
1006 case '8':
1007 case '9':
1008 case '!':
1009 case '#':
1010 case '%':
1011 case '(':
1012 case ')':
1013 case '<':
1014 case '>':
1015 case '@':
1016 case 'R':
1017 case 'j':
1018 case 'J':
1019 case 's':
1020 pbsetspeed(key);
1021 return;
1022 break;
1023 case 'l':
1024 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER | TARG_CLOAK);
1025 pblockplayer(target->o_num);
1026 return;
1027 break;
1028 case ';':
1029 target = gettarget(data->Window, data->x, data->y, TARG_PLANET);
1030 pblockplanet(target->o_num);
1031 return;
1032 break;
1033 case '=':
1034 printf("sequence #%d\n", pb_sequence_count);
1035 return;
1036 break;
1037 case 'I':
1038 case 'i':
1039 case '?':
1040 /* Do the normal function */
1041 /* Used for commands that do not try to send packets */
1042 break;
1043 default:
1044 /* If key is not in above list dont run it. */
1045 return;
1046 }
1047 }
1048 #endif
1049
1050
1051 /* suggestion: later we can add an option removing this to the emptyKey()
1052 * * * function. This would improve input efficiency considerably when * *
1053 * "singleMacro" is non-NULL. - jn */
1054
1055 if ((!MacroMode)
1056 && singleMacro[0] != '\0'
1057 && INDEX((char *) singleMacro, data->key))
1058 {
1059 MacroMode = 1;
1060 MacroNum = -1;
1061 }
1062
1063 if (MacroMode)
1064 {
1065 doMacro(data);
1066 return;
1067 }
1068
1069 #ifdef MOTION_MOUSE
1070 if ((data->type == W_EV_CM_BUTTON) && /* KOC - 10/18/95 */
1071 (!motion_mouse_enablable) && /* Hack for */
1072 (key != 107)) /* continuous_steer */
1073 return;
1074 #endif
1075
1076 (*(key_handlers[key].handler)) (data);
1077 }
1078
1079 #ifdef MOUSE_AS_SHIFT
mkeyaction(W_Event * data)1080 void mkeyaction(W_Event * data)
1081 {
1082 unsigned char key = data->key;
1083
1084 fastQuit = 0; /* any event, cancel * *
1085 * fastquit! */
1086
1087 if (!INDEX("sbogadc", key) || !(localflags & PFREFIT))
1088 {
1089 if (key >= 32 && key < 176)
1090 {
1091 int offset;
1092
1093 switch (data->modifier)
1094 {
1095 case W_LBUTTON:
1096 offset = 192;
1097 break;
1098
1099 case W_MBUTTON:
1100 offset = 288;
1101 break;
1102
1103 case W_RBUTTON:
1104 offset = 384;
1105 break;
1106 }
1107
1108 key = mystats->st_keymap[key - 32 + offset];
1109 }
1110 }
1111
1112 data->key = key;
1113 keyaction(data);
1114 }
1115 #endif
1116
buttonaction(W_Event * data)1117 void buttonaction(W_Event * data)
1118 {
1119 unsigned char course;
1120 struct obtype *gettarget(W_Window ww, int x, int y, int targtype);
1121
1122 if (messageon)
1123 message_off(); /* ATM */
1124
1125 fastQuit = 0; /* any event, cancel * *
1126 * fastquit! */
1127
1128 #ifdef RECORDGAME
1129 /* While playing back recorded games, ignore the mouse */
1130 if (playback)
1131 return;
1132 #endif
1133
1134 #ifdef SHORT_PACKETS
1135 if (data->Window == reviewWin)
1136 {
1137 if (recv_mesg)
1138 {
1139 sendShortReq(SPK_MOFF);
1140 }
1141 else
1142 {
1143 sendShortReq(SPK_MON);
1144 }
1145 return;
1146 }
1147 #endif
1148
1149 if (data->Window != w && data->Window != mapw
1150 && data->Window != infow)
1151 return;
1152
1153 #ifdef SHIFTED_MOUSE
1154 if (data->key >= W_LBUTTON && data->key < W_BUTTON_RANGE)
1155 #else
1156 if (data->key > 0 && data->key <= 3)
1157 #endif
1158
1159 {
1160 if (buttonmap[data->key] != '\0')
1161 {
1162 data->key = buttonmap[data->key];
1163 keyaction(data);
1164 return;
1165 }
1166 }
1167
1168 #ifdef MOTION_MOUSE
1169 if ((data->type == W_EV_CM_BUTTON) && /* KOC - 10/18/95 */
1170 (!motion_mouse_enablable) && /* Hack for */
1171 (data->key != W_RBUTTON)) /* continuous_steer */
1172 return;
1173 #endif
1174
1175 if (data->Window == infow)
1176 {
1177 int x, y;
1178
1179 if (findMouseInWin(&x, &y, w))
1180 { /* local window */
1181 data->Window = w;
1182 data->x = x;
1183 data->y = y;
1184 }
1185 else if (findMouseInWin(&x, &y, mapw))
1186 { /* galactic window */
1187 data->Window = mapw;
1188 data->x = x;
1189 data->y = y;
1190 }
1191 }
1192
1193 if (data->key == W_RBUTTON)
1194 {
1195 course = getcourse(data->Window, data->x, data->y);
1196 set_course(course);
1197 }
1198 else if (data->key == W_LBUTTON)
1199 {
1200 course = getcourse(data->Window, data->x, data->y);
1201 sendTorpReq(course);
1202 }
1203 else if (data->key == W_MBUTTON)
1204 {
1205 course = getcourse(data->Window, data->x, data->y);
1206 sendPhaserReq(course);
1207 }
1208
1209 #ifdef NODEF /* SHIFTED_MOUSE - no defaults if not set */
1210 else if (data->key == W_RBUTTON2)
1211 {
1212 set_speed(me->p_ship.s_maxspeed / 2);
1213 localflags &= ~(PFREFIT);
1214 }
1215 else if (data->key == W_LBUTTON2)
1216 {
1217 set_speed(99); /* Max speed... */
1218 localflags &= ~(PFREFIT);
1219 }
1220 else if (data->key == W_MBUTTON2)
1221 {
1222 detmine();
1223 }
1224 else if (data->key == W_RBUTTON3)
1225 {
1226 if (!infomapped)
1227 {
1228 inform(data->Window, data->x, data->y, 'i');
1229 opened_info = keepInfo * server_ups / 5;
1230 }
1231 else
1232 {
1233 destroyInfo();
1234 opened_info = -2;
1235 }
1236 }
1237 else if (data->key == W_LBUTTON3)
1238 {
1239 shield_tog();
1240 }
1241 else if (data->key == W_MBUTTON3)
1242 {
1243 cloak();
1244 }
1245 else if (data->key == W_RBUTTON4)
1246 {
1247 lockPlanetOrBase(data->Window, data->x, data->y);
1248 }
1249 else if (data->key == W_LBUTTON4)
1250 {
1251 struct obtype *gettarget(W_Window ww, int x, int y, int targtype),
1252 *target;
1253
1254 if (me->p_flags & (PFTRACT | PFPRESS))
1255 sendTractorReq(0, me->p_no);
1256 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
1257 me->p_tractor = target->o_num;
1258 sendTractorReq(1, target->o_num);
1259 }
1260 else if (data->key == W_MBUTTON4)
1261 {
1262 struct obtype *gettarget(W_Window ww, int x, int y, int targtype),
1263 *target;
1264
1265 if (me->p_flags & (PFTRACT | PFPRESS))
1266 sendRepressReq(0, me->p_no);
1267 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
1268 me->p_tractor = target->o_num;
1269 sendRepressReq(1, target->o_num);
1270 }
1271 #endif
1272 }
1273
getcourse(W_Window ww,int x,int y)1274 int getcourse(W_Window ww, int x, int y)
1275 {
1276 if (ww == mapw)
1277 {
1278 int me_x, me_y;
1279
1280 me_x = me->p_x * GWINSIDE / GWIDTH;
1281 me_y = me->p_y * GWINSIDE / GWIDTH;
1282 return ((unsigned char) nint((atan2((double) (x - me_x),
1283 (double) (me_y - y)) / 3.14159 * 128.) + 0.5));
1284 }
1285 else
1286 return ((unsigned char) nint((atan2((double) (x - TWINSIDE / 2),
1287 (double) (TWINSIDE / 2 - y))
1288 / 3.14159 * 128.) + 0.5));
1289 }
1290
detmine(void)1291 static void detmine(void)
1292 {
1293 register int i;
1294
1295 for (i = 0; i < MAXTORP; i++)
1296 {
1297 if (torps[i + (me->p_no * MAXTORP)].t_status == TMOVE ||
1298 torps[i + (me->p_no * MAXTORP)].t_status == TSTRAIGHT)
1299 {
1300 sendDetMineReq(i + (me->p_no * MAXTORP));
1301
1302 #ifdef SHORT_PACKETS
1303 if (recv_short)
1304 break; /* Let the server det for me
1305 *
1306 */
1307 #endif
1308 }
1309 }
1310 }
1311
lockPlanetOrBase(W_Window ww,int x,int y)1312 void lockPlanetOrBase(W_Window ww, int x, int y)
1313 /* special version of gettarget, 6/1/93 LAB */
1314 {
1315 register int i;
1316 register struct player *j;
1317 register struct planet *k;
1318 int g_x, g_y;
1319 double dist, closedist;
1320 register int targtyp, targnum;
1321
1322 if (ww == mapw)
1323 {
1324 g_x = x * GWIDTH / GWINSIDE;
1325 g_y = y * GWIDTH / GWINSIDE;
1326 }
1327 else
1328 {
1329 g_x = me->p_x + ((x - TWINSIDE / 2) * SCALE);
1330 g_y = me->p_y + ((y - TWINSIDE / 2) * SCALE);
1331 }
1332 closedist = GWIDTH;
1333
1334 for (i = 0, k = &planets[i]; i < MAXPLANETS; i++, k++)
1335 {
1336 dist = hypot((double) (g_x - k->pl_x), (double) (g_y - k->pl_y));
1337 if (dist < closedist)
1338 {
1339 targtyp = PLANETTYPE;
1340 targnum = i;
1341 closedist = dist;
1342 }
1343 }
1344
1345 for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++)
1346 {
1347 if (j->p_status != PALIVE)
1348 continue;
1349 if (j->p_flags & PFCLOAK)
1350 continue;
1351 if (j == me)
1352 continue;
1353 if ((j->p_ship.s_type == STARBASE) && (j->p_team == me->p_team))
1354 {
1355 dist = hypot((double) (g_x - j->p_x), (double) (g_y - j->p_y));
1356 if (dist < closedist)
1357 {
1358 targtyp = PLAYERTYPE;
1359 targnum = i;
1360 closedist = dist;
1361 }
1362 }
1363 }
1364
1365 if (targtyp == PLAYERTYPE)
1366 {
1367 sendPlaylockReq(targnum);
1368 me->p_playerl = targnum;
1369 }
1370 else
1371 {
1372 sendPlanlockReq(targnum);
1373 me->p_planet = targnum;
1374 }
1375
1376 }
1377
1378
emptyKey(void)1379 static void emptyKey(void)
1380 {
1381 fprintf(stderr, "input.c: emptyKey %d\n", key);
1382 W_Beep();
1383 }
1384
1385
macro_on(void)1386 void macro_on(void)
1387 {
1388 warning("In Macro Mode");
1389 MacroMode = 1;
1390 MacroNum = -1;
1391 }
1392
1393
doMacro(W_Event * data)1394 void doMacro(W_Event * data)
1395 {
1396 struct obtype *gettarget(W_Window ww, int x, int y, int targtype), *target;
1397 int targettype;
1398 enum dist_type i;
1399
1400 #ifdef NBT
1401 int c;
1402 char who;
1403 int found = 0;
1404
1405 #endif
1406
1407 warning(" "); /* We are here now, so turn
1408 * * off macro mode */
1409 MacroMode = 0;
1410
1411
1412 #ifdef NBT
1413 if (data->key == '?')
1414 {
1415 showMacroWin();
1416 return;
1417 }
1418
1419
1420 /* user defined macros *OVERRIDE* receiver configurable distresses. */
1421
1422 if (UseNewMacro)
1423 {
1424 /* sorry guys, I only program in kludge - jn 6/3/93 */
1425
1426 if (MacroNum > -1)
1427 { /* macro identified, who to?
1428 *
1429 */
1430 if (MacroNum >= MAX_MACRO)
1431 fprintf(stderr, "Unknown Macro Num! There is a macro bug!!\n");
1432
1433 if (!pmacro(MacroNum, data->key, data))
1434 W_Beep();
1435
1436 MacroNum = -1;
1437 return;
1438 }
1439 }
1440
1441
1442 for (c = 0; c < macrocnt; ++c)
1443 {
1444 if (macro[c].key == data->key)
1445 {
1446 if (!UseNewMacro)
1447 {
1448 if (rejectMacro && macro[c].type != NBTM)
1449 warning("NEWMACROs not allowed at this server!!");
1450 else
1451 pnbtmacro(c);
1452
1453 return;
1454 }
1455
1456
1457 /* Use New Macro */
1458
1459 switch (macro[c].type)
1460 {
1461 case NBTM:
1462
1463 pnbtmacro(c);
1464 return;
1465 break;
1466
1467 case NEWM:
1468
1469 warning("Send macro to which player?");
1470 MacroNum = c;
1471 MacroMode = 1; /* Need another key */
1472 return;
1473 break;
1474
1475 case NEWMMOUSE:
1476 {
1477 /* first translate into who, then send */
1478 switch (macro[c].who)
1479 {
1480 struct player *j;
1481 struct planet *l;
1482
1483 case MACRO_FRIEND:
1484 case MACRO_ENEMY:
1485 case MACRO_PLAYER:
1486
1487 targettype = TARG_PLAYER;
1488 if (macro[c].who == MACRO_ENEMY)
1489 targettype |= TARG_ENEMY;
1490 else if (macro[c].who == MACRO_FRIEND)
1491 targettype |= TARG_FRIEND;
1492
1493 target = gettarget(data->Window, data->x, data->y,
1494 TARG_PLAYER | TARG_CLOAK);
1495 if (target->o_type == PLAYERTYPE)
1496 {
1497 j = &players[target->o_num];
1498 if (j->p_flags & PFCLOAK)
1499 maskrecip = 1;
1500 who = j->p_mapchars[1];
1501 }
1502 else
1503 {
1504 who = me->p_mapchars[1];
1505 warning("Can only send a message to a player");
1506 }
1507 break;
1508
1509 case MACRO_TEAM:
1510 target = gettarget(data->Window, data->x, data->y,
1511 TARG_PLAYER | TARG_PLANET);
1512 if (target->o_type == PLANETTYPE)
1513 {
1514 l = &planets[target->o_num];
1515 who = teamlet[l->pl_owner];
1516 }
1517 else if (target->o_type == PLAYERTYPE)
1518 {
1519 j = &players[target->o_num];
1520 who = j->p_mapchars[0];
1521 }
1522 else
1523 {
1524 who = me->p_mapchars[1];
1525 warning("Player or planet only please");
1526 }
1527 break;
1528
1529 default:
1530 who = me->p_mapchars[1];
1531 break;
1532 }
1533
1534 if (!pmacro(c, who, data))
1535 W_Beep();
1536
1537 return;
1538 break;
1539 }
1540
1541 #ifdef MULTILINE_MACROS
1542 case NEWMULTIM:
1543
1544 if (!pmacro(c, macro[c].who, data))
1545 W_Beep();
1546
1547 found = 1;
1548 break; /* Loop again */
1549 #endif
1550
1551 case NEWMSPEC:
1552
1553 if (!pmacro(c, macro[c].who, data))
1554 W_Beep();
1555 return;
1556 break;
1557
1558 default:
1559 fprintf(stderr, "Unknown Macro Type! Jeff's a twink!!\n");
1560 warning("Unknown macro type (eg There is a macro bug)");
1561 return;
1562 break;
1563 }
1564 }
1565 }
1566
1567 if (found)
1568 return;
1569
1570 #ifdef DIST_KEY_NAME
1571 /* scan for distress call here */
1572
1573 for (i = take; distmacro[i].name; i++)
1574 {
1575 if (distmacro[i].c == data->key)
1576 {
1577 emergency(i, data);
1578 return;
1579 }
1580 }
1581 #endif
1582 warning("Unknown macro");
1583 W_Beep();
1584 #endif
1585 }
1586
Key32(void)1587 static void Key32(void)
1588 {
1589 /* ' ' = clear special windows */
1590 W_UnmapWindow(planetw);
1591 W_UnmapWindow(rankw);
1592 if (infomapped)
1593 destroyInfo();
1594 W_UnmapWindow(helpWin);
1595
1596 #ifdef NBT
1597 W_UnmapWindow(macroWin);
1598 #endif
1599
1600 #ifdef XTREKRC_HELP
1601 if (defWin)
1602 W_UnmapWindow(defWin);
1603 #endif
1604
1605 W_UnmapWindow(war);
1606 if (optionWin)
1607 optiondone();
1608 if (udpWin)
1609 udpdone();
1610 }
1611
Key33(void)1612 static void Key33(void)
1613 {
1614 set_speed(11);
1615 }
1616
Key34(W_Event * data)1617 static void Key34(W_Event * data)
1618 {
1619 int ok = W_FullScreenToggle(baseWin);
1620 switch (ok) {
1621 case -1:
1622 warning("Full screen mode was not built in this program.");
1623 break;
1624 case 0:
1625 warning("Full screen mode toggled.");
1626 break;
1627 case 1:
1628 warning("Full screen mode not available here.");
1629 break;
1630 }
1631 }
1632
Key35(void)1633 static void Key35(void)
1634 {
1635 set_speed(me->p_ship.s_maxspeed / 2);
1636 }
1637
Key36(void)1638 static void Key36(void)
1639 {
1640 sendTractorReq(0, me->p_no);
1641 }
1642
Key37(void)1643 static void Key37(void)
1644 {
1645 set_speed(99); /* Max speed... */
1646 }
1647
Key38(void)1648 static void Key38(void)
1649 {
1650 char mbuf[80];
1651
1652 if (strlen(defaultsFile) > 0)
1653 {
1654 sprintf(mbuf, "Re-reading %s", defaultsFile);
1655
1656 warning(mbuf);
1657 initDefaults(defaultsFile);
1658 resetdefaults();
1659 initkeymap();
1660 }
1661 else
1662 {
1663 warning("no default file found");
1664 }
1665 }
1666
Key39(void)1667 static void Key39(void)
1668 {
1669 sendUdpReq(COMM_UPDATE);
1670 }
1671
Key40(void)1672 static void Key40(void)
1673 {
1674 set_speed(10);
1675 }
1676
Key41(W_Event * data)1677 static void Key41(W_Event * data)
1678 {
1679 set_speed(10);
1680 }
1681
Key42(void)1682 static void Key42(void)
1683 {
1684 sendPractrReq();
1685 }
1686
Key43(void)1687 static void Key43(void)
1688 {
1689 /* UDP: pop up UDP control window */
1690 if (udpWin != NULL && W_IsMapped(udpWin))
1691 udpdone();
1692 else
1693 {
1694 char buf[80];
1695
1696 udpwindow();
1697 sprintf(buf, "UDP client version %.1f",
1698 (float) UDPVERSION / 10.0);
1699 warning(buf);
1700 }
1701 }
1702
Key44(void)1703 static void Key44(void)
1704 {
1705 if (W_IsMapped(pStats))
1706 {
1707 W_UnmapWindow(pStats);
1708 }
1709 else
1710 {
1711 W_MapWindow(pStats);
1712 redrawPStats();
1713 }
1714 }
1715
Key45(void)1716 static void Key45(void)
1717 {
1718 #ifdef SHORT_PACKETS
1719 sendShortReq(SPK_SALL);
1720 #endif
1721 }
1722
Key46(void)1723 static void Key46(void)
1724 {
1725 if (netstatWin != NULL && W_IsMapped(netstatWin))
1726 nsdone();
1727 else
1728 nswindow();
1729 }
1730
Key47(void)1731 static void Key47(void)
1732 {
1733 sortPlayers = !sortPlayers;
1734 RedrawPlayerList();
1735 }
1736
Key48(void)1737 static void Key48(void)
1738 {
1739 set_speed(0);
1740 }
1741
Key49(void)1742 static void Key49(void)
1743 {
1744 set_speed(1);
1745 }
1746
Key50(void)1747 static void Key50(void)
1748 {
1749 set_speed(2);
1750 }
1751
Key51(void)1752 static void Key51(void)
1753 {
1754 set_speed(3);
1755 }
1756
Key52(void)1757 static void Key52(void)
1758 {
1759 set_speed(4);
1760 }
1761
Key53(void)1762 static void Key53(void)
1763 {
1764 set_speed(5);
1765 }
1766
Key54(void)1767 static void Key54(void)
1768 {
1769 set_speed(6);
1770 }
1771
Key55(void)1772 static void Key55(void)
1773 {
1774 set_speed(7);
1775 }
1776
Key56(void)1777 static void Key56(void)
1778 {
1779 set_speed(8);
1780 }
1781
Key57(void)1782 static void Key57(void)
1783 {
1784 set_speed(9);
1785 }
1786
Key58(void)1787 static void Key58(void)
1788 {
1789 logmess = !logmess;
1790 if (logmess)
1791 warning("Message logging is ON");
1792 else
1793 warning("Message logging is OFF");
1794 }
1795
Key59(W_Event * data)1796 static void Key59(W_Event * data)
1797 {
1798 lockPlanetOrBase(data->Window, data->x, data->y);
1799 }
1800
1801 /* < */
Key60(void)1802 static void Key60(void)
1803 {
1804 set_speed(me->p_speed - 1);
1805 }
1806
Key61(void)1807 static void Key61(void)
1808 {
1809 /* UDP: request for full update */
1810 sendUdpReq(COMM_UPDATE);
1811 }
1812
1813 /* > */
Key62(void)1814 static void Key62(void)
1815 {
1816 set_speed(me->p_speed + 1);
1817 }
1818
Key63(void)1819 static void Key63(void)
1820 {
1821 if (W_IsMapped(phaserwin))
1822 phaserWindow = 1;
1823 if (!W_IsMapped(reviewWin))
1824 {
1825 if (W_IsMapped(messwa))
1826 {
1827 W_UnmapWindow(messwa);
1828 W_UnmapWindow(phaserwin);
1829 W_UnmapWindow(messwt);
1830 W_UnmapWindow(messwi);
1831 W_UnmapWindow(messwk);
1832 }
1833 else
1834 {
1835 W_MapWindow(reviewWin);
1836 }
1837 }
1838 else
1839 {
1840 W_UnmapWindow(reviewWin);
1841 W_MapWindow(messwa);
1842 W_MapWindow(messwt);
1843 W_MapWindow(messwi);
1844 W_MapWindow(messwk);
1845 if (phaserWindow)
1846 W_MapWindow(phaserwin);
1847 if (W_IsMapped(statwin))
1848 {
1849 W_UnmapWindow(statwin);
1850 W_MapWindow(statwin);
1851 }
1852 }
1853 if (optionWin)
1854 {
1855 optionredrawtarget(reviewWin);
1856 optionredrawtarget(messwa);
1857 optionredrawtarget(phaserwin);
1858 optionredrawtarget(messwt);
1859 optionredrawtarget(messwi);
1860 optionredrawtarget(messwk);
1861 }
1862 }
1863
Key64(void)1864 static void Key64(void)
1865 {
1866 set_speed(12);
1867 }
1868
Key65(W_Event * data)1869 static void Key65(W_Event * data)
1870 {
1871 /* W_ShowBitmaps(); */
1872 emptyKey();
1873 }
1874
Key66(void)1875 static void Key66(void)
1876 {
1877 showgalactic++;
1878 if (showgalactic > 4)
1879 showgalactic = 0;
1880
1881 redrawall = 2;
1882 }
1883
Key67(void)1884 static void Key67(void)
1885 {
1886 sendCoupReq();
1887 W_CameraSnap(w);
1888 }
1889
Key68(void)1890 static void Key68(void)
1891 {
1892 detmine();
1893
1894 #ifdef AUTOKEY
1895 if (autoKey)
1896 autoKeyAllOff(); /* xx */
1897 #endif
1898 }
1899
1900 /* E */
Key69(W_Event * data)1901 static void Key69(W_Event * data)
1902 {
1903 emergency(generic, data);
1904 }
1905
1906 /* F */
Key70(W_Event * data)1907 static void Key70(W_Event * data)
1908 {
1909 emergency(carrying, data);
1910 }
1911
Key71(W_Event * data)1912 static void Key71(W_Event * data)
1913 {
1914 emptyKey();
1915 }
1916
Key72(W_Event * data)1917 static void Key72(W_Event * data)
1918 {
1919 emptyKey();
1920 }
1921
Key73(W_Event * data)1922 static void Key73(W_Event * data)
1923 {
1924 /* I = get extended information */
1925 if (!infomapped)
1926 {
1927 inform(data->Window, data->x, data->y, key);
1928 opened_info = keepInfo * server_ups / 5;
1929 }
1930 else
1931 {
1932 destroyInfo();
1933 opened_info = -2;
1934 }
1935 }
1936
Key74(W_Event * data)1937 static void Key74(W_Event * data)
1938 {
1939 emptyKey();
1940 }
1941
Key75(void)1942 static void Key75(void)
1943 {
1944 /* testing feature, disabled ... display picture of a human on galactic */
1945 /* W_GalacticBgd(GREET_PIX); */
1946 }
1947
Key76(void)1948 static void Key76(void)
1949 {
1950 if (W_IsMapped(playerw))
1951 {
1952 W_UnmapWindow(playerw);
1953 }
1954 else
1955 {
1956 W_MapWindow(playerw);
1957 }
1958 }
1959
Key77(W_Event * data)1960 static void Key77(W_Event * data)
1961 {
1962 #ifdef TOOLS
1963 showToolsWin();
1964 #else
1965 emptyKey();
1966 #endif
1967 }
1968
Key78(void)1969 static void Key78(void)
1970 {
1971 /* N = Toggle Name mode */
1972 namemode = !namemode;
1973 if (optionWin)
1974 optionredrawoption(&namemode);
1975 }
1976
Key79(void)1977 static void Key79(void)
1978 {
1979 if (optionWin != NULL && W_IsMapped(optionWin))
1980 optiondone();
1981 else
1982 optionwindow();
1983 }
1984
Key80(void)1985 static void Key80(void)
1986 {
1987 if (W_IsMapped(planetw))
1988 {
1989 W_UnmapWindow(planetw);
1990 }
1991 else
1992 {
1993 W_MapWindow(planetw);
1994 }
1995 }
1996
Key81(void)1997 static void Key81(void)
1998 {
1999 #ifdef SOUND
2000 Play_Sound(SELF_DESTRUCT_SOUND);
2001 #endif
2002 sendQuitReq();
2003 }
2004
Key82(void)2005 static void Key82(void)
2006 {
2007 sendRepairReq(1);
2008 }
2009
Key83(void)2010 static void Key83(void)
2011 {
2012 if (W_IsMapped(statwin))
2013 {
2014 W_UnmapWindow(statwin);
2015 }
2016 else
2017 {
2018 W_MapWindow(statwin);
2019 }
2020 }
2021
Key84(W_Event * data)2022 static void Key84(W_Event * data)
2023 {
2024 if (me->p_flags & (PFTRACT | PFPRESS))
2025 {
2026 sendTractorReq(0, me->p_no);
2027 return;
2028 }
2029 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
2030 me->p_tractor = target->o_num;
2031 if (key == 'T')
2032 {
2033 sendTractorReq(1, target->o_num);
2034 }
2035 else
2036 {
2037 sendRepressReq(1, target->o_num);
2038 }
2039 }
2040
Key85(void)2041 static void Key85(void)
2042 {
2043 if (W_IsMapped(rankw))
2044 {
2045 W_UnmapWindow(rankw);
2046 }
2047 else
2048 {
2049 W_MapWindow(rankw);
2050 }
2051 }
2052
2053 /* I really should get paid for this... */
Key86(void)2054 static void Key86(void)
2055 {
2056 showlocal++;
2057 if (showlocal > 4)
2058 showlocal = 0;
2059 }
2060
Key87(W_Event * data)2061 static void Key87(W_Event * data)
2062 {
2063 emptyKey();
2064 }
2065
Key88(void)2066 static void Key88(void)
2067 {
2068 macro_on();
2069 }
2070
Key89(W_Event * data)2071 static void Key89(W_Event * data)
2072 {
2073 emptyKey();
2074 }
2075
Key90(W_Event * data)2076 static void Key90(W_Event * data)
2077 {
2078 emptyKey();
2079 }
2080
Key91(void)2081 static void Key91(void)
2082 {
2083 shield_down();
2084 }
2085
Key92(void)2086 static void Key92(void)
2087 {
2088 if (netstat)
2089 {
2090 if (lMeter != NULL && W_IsMapped(lMeter))
2091 W_UnmapWindow(lMeter);
2092 else
2093 W_MapWindow(lMeter);
2094 }
2095 else
2096 {
2097 warning("Network stats are not being collected!");
2098 }
2099 }
2100
Key93(void)2101 static void Key93(void)
2102 {
2103 shield_up();
2104 }
2105
Key94(W_Event * data)2106 static void Key94(W_Event * data)
2107 {
2108 if (me->p_flags & (PFTRACT | PFPRESS))
2109 sendRepressReq(0, me->p_no);
2110 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
2111 me->p_tractor = target->o_num;
2112 sendRepressReq(1, target->o_num);
2113 }
2114
Key95(W_Event * data)2115 static void Key95(W_Event * data)
2116 {
2117 if (me->p_flags & (PFTRACT | PFPRESS))
2118 sendTractorReq(0, me->p_no);
2119 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
2120 me->p_tractor = target->o_num;
2121 sendTractorReq(1, target->o_num);
2122 }
2123
Key96(void)2124 static void Key96(void)
2125 {
2126 #ifdef SHORT_PACKETS
2127 if (spWin != NULL && W_IsMapped(spWin))
2128 spdone();
2129 else
2130 spwindow();
2131 #endif
2132 }
2133
Key98(void)2134 static void Key98(void)
2135 {
2136 #ifdef AUTOKEY
2137 if (autoKey && !(localflags & PFREFIT))
2138 autoKeyBombReqOn();
2139 else
2140 bomb_planet();
2141 #else
2142 bomb_planet();
2143 #endif /* AUTOKEY */
2144 }
2145
Key99(void)2146 static void Key99(void)
2147 {
2148 cloak();
2149 }
2150
Key100(void)2151 static void Key100(void)
2152 {
2153 static unsigned long lastdet = 0;
2154 unsigned long curtime;
2155
2156 #ifdef AUTOKEY
2157 if (autoKey)
2158 autoKeyDetReqOn();
2159 else
2160 sendDetonateReq();
2161 #else
2162 /* want to limit these to one per update */
2163 curtime = mstime();
2164 if (curtime >= lastdet + 100) /* Allow one per 100 ms */
2165 {
2166 sendDetonateReq();
2167 lastdet = curtime;
2168 }
2169 #endif /* AUTOKEY */
2170 detCircle = 1;
2171 }
2172
Key101(void)2173 static void Key101(void)
2174 {
2175 if (me->p_flags & PFDOCKOK)
2176 sendDockingReq(0);
2177 else
2178 sendDockingReq(1);
2179 }
2180
Key102(W_Event * data)2181 static void Key102(W_Event * data)
2182 {
2183 unsigned char course;
2184
2185 /* f = launch plasma torpedos */
2186 #ifdef AUTOKEY
2187 if (autoKey)
2188 autoKeyPlasmaReqOn();
2189 else
2190 {
2191 course = getcourse(data->Window, data->x, data->y);
2192 sendPlasmaReq(course);
2193 }
2194 #else
2195 course = getcourse(data->Window, data->x, data->y);
2196 sendPlasmaReq(course);
2197 #endif /* AUTOKEY */
2198 }
2199
Key103(W_Event * data)2200 static void Key103(W_Event * data)
2201 {
2202 emptyKey();
2203 }
2204
Key104(void)2205 static void Key104(void)
2206 {
2207 /* h = Map help window */
2208 if (W_IsMapped(helpWin))
2209 {
2210 W_UnmapWindow(helpWin);
2211 }
2212 else
2213 {
2214 fillhelp();
2215 W_MapWindow(helpWin);
2216 }
2217 if (optionWin)
2218 optionredrawtarget(helpWin);
2219 }
2220
Key105(W_Event * data)2221 static void Key105(W_Event * data)
2222 {
2223 if (!infomapped)
2224 {
2225 inform(data->Window, data->x, data->y, key);
2226 opened_info = keepInfo * server_ups / 5;
2227 }
2228 else
2229 {
2230 destroyInfo();
2231 opened_info = -2;
2232 }
2233 }
2234
Key106(W_Event * data)2235 static void Key106(W_Event * data)
2236 {
2237 emptyKey();
2238 }
2239
Key107(W_Event * data)2240 static void Key107(W_Event * data)
2241 {
2242 unsigned char course;
2243
2244 /* Observers can't move. Also incorrectly removes the lock flag even though
2245 you are still locked */
2246 if (me->p_flags & PFOBSERV) {
2247 warning("Course change ignored while observing!");
2248 return;
2249 }
2250
2251 course = getcourse(data->Window, data->x, data->y);
2252 set_course(course);
2253 me->p_flags &= ~(PFPLOCK | PFPLLOCK);
2254 }
2255
Key108(W_Event * data)2256 static void Key108(W_Event * data)
2257 {
2258 target = gettarget(data->Window, data->x, data->y,
2259 TARG_PLAYER | TARG_PLANET);
2260 if (target->o_type == PLAYERTYPE)
2261 {
2262 sendPlaylockReq(target->o_num);
2263 me->p_playerl = target->o_num;
2264 }
2265 else
2266 { /* It's a planet */
2267 sendPlanlockReq(target->o_num);
2268 me->p_planet = target->o_num;
2269 }
2270 }
2271
Key109(void)2272 void Key109(void)
2273 {
2274 #ifdef SOUND
2275 Play_Sound(MESSAGE_SOUND);
2276 #endif
2277 message_on();
2278 }
2279
Key110(W_Event * data)2280 static void Key110(W_Event * data)
2281 {
2282 emptyKey();
2283 }
2284
Key111(void)2285 static void Key111(void)
2286 {
2287 #ifdef AUTOKEY
2288 if (autoKey)
2289 autoKeyOrbitReqOn();
2290 else
2291 sendOrbitReq(1);
2292 #else
2293 sendOrbitReq(1);
2294 #endif /* AUTOKEY */
2295 }
2296
Key112(W_Event * data)2297 static void Key112(W_Event * data)
2298 {
2299 unsigned char course;
2300
2301 #ifdef AUTOKEY
2302 if (autoKey)
2303 autoKeyPhaserReqOn();
2304 else
2305 {
2306 course = getcourse(data->Window, data->x, data->y);
2307 sendPhaserReq(course);
2308 }
2309 #else
2310 course = getcourse(data->Window, data->x, data->y);
2311 sendPhaserReq(course);
2312 #endif /* AUTOKEY */
2313 }
2314
Key113(void)2315 static void Key113(void)
2316 {
2317 #ifdef SOUND
2318 Play_Sound(SELF_DESTRUCT_SOUND);
2319 #endif
2320
2321 fastQuit = 1;
2322 sendQuitReq();
2323 }
2324
2325 /* r */
Key114(void)2326 static void Key114(void)
2327 {
2328 localflags |= PFREFIT;
2329 warning("s=scout, d=destroyer, c=cruiser, b=battleship, a=assault, g=galaxy, o=starbase/outpost");
2330 }
2331
Key115(void)2332 static void Key115(void)
2333 {
2334 shield_tog();
2335 }
2336
Key116(W_Event * data)2337 static void Key116(W_Event * data)
2338 {
2339 unsigned char course;
2340
2341 #ifdef AUTOKEY
2342 if (autoKey)
2343 autoKeyTorpReqOn();
2344 else
2345 {
2346 course = getcourse(data->Window, data->x, data->y);
2347 sendTorpReq(course);
2348 }
2349 #else
2350 course = getcourse(data->Window, data->x, data->y);
2351 sendTorpReq(course);
2352 #endif /* AUTOKEY */
2353 }
2354
Key117(void)2355 static void Key117(void)
2356 {
2357 shield_tog();
2358 }
2359
Key118(W_Event * data)2360 static void Key118(W_Event * data)
2361 {
2362 emptyKey();
2363 }
2364
Key119(void)2365 static void Key119(void)
2366 {
2367 /* w = map war stuff */
2368 if (W_IsMapped(war))
2369 W_UnmapWindow(war);
2370 else
2371 warwindow();
2372 }
2373
Key120(void)2374 static void Key120(void)
2375 {
2376 #ifdef AUTOKEY
2377 if (autoKey)
2378 autoKeyBeamDownReqOn();
2379 else
2380 #endif
2381 beam_down();
2382 }
2383
Key121(W_Event * data)2384 static void Key121(W_Event * data)
2385 {
2386 if (me->p_flags & (PFTRACT | PFPRESS))
2387 {
2388 sendTractorReq(0, me->p_no);
2389 return;
2390 }
2391 target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
2392 me->p_tractor = target->o_num;
2393 if (key == 'T')
2394 {
2395 sendTractorReq(1, target->o_num);
2396 }
2397 else
2398 {
2399 sendRepressReq(1, target->o_num);
2400 }
2401 }
2402
Key122(void)2403 static void Key122(void)
2404 {
2405 #ifdef AUTOKEY
2406 if (autoKey)
2407 autoKeyBeamUpReqOn();
2408 else
2409 #endif
2410 beam_up();
2411 }
2412
Key123(void)2413 static void Key123(void)
2414 {
2415 cloak_on();
2416 }
2417
Key124(void)2418 static void Key124(void)
2419 {
2420 #ifdef SHORT_PACKETS
2421 sendShortReq(SPK_ALL);
2422 #endif
2423 }
2424
Key125(void)2425 static void Key125(void)
2426 {
2427 cloak_off();
2428 }
2429
2430 /* ~ */
Key126(W_Event * data)2431 static void Key126(W_Event * data) {
2432
2433 #ifdef SOUND
2434 if ((soundWin != NULL) && W_IsMapped(soundWin))
2435 sounddone();
2436 else
2437 soundwindow();
2438 #else
2439 emptyKey();
2440 #endif
2441 }
2442
Key127(W_Event * data)2443 static void Key127(W_Event * data)
2444 {
2445 emptyKey();
2446 }
2447
2448 /* ^T */
Key180(W_Event * data)2449 static void Key180(W_Event * data)
2450 {
2451 emergency(take, data);
2452 }
2453
2454 /* ^t */
Key212(W_Event * data)2455 static void Key212(W_Event * data)
2456 {
2457 emergency(take, data);
2458 }
2459
2460 /* ^o */
Key207(W_Event * data)2461 static void Key207(W_Event * data)
2462 {
2463 emergency(ogg, data);
2464 }
2465
2466 /* ^b */
Key194(W_Event * data)2467 static void Key194(W_Event * data)
2468 {
2469 emergency(bomb, data);
2470 }
2471
2472 /* ^c */
Key195(W_Event * data)2473 static void Key195(W_Event * data)
2474 {
2475 emergency(space_control, data);
2476 }
2477
2478 /* ^1 */
Key145(W_Event * data)2479 static void Key145(W_Event * data)
2480 {
2481 emergency(save_planet, data);
2482 }
2483
2484 /* ^2 */
Key146(W_Event * data)2485 static void Key146(W_Event * data)
2486 {
2487 emergency(base_ogg, data);
2488 }
2489
2490 /* ^3 */
Key147(W_Event * data)2491 static void Key147(W_Event * data)
2492 {
2493 emergency(help1, data);
2494 }
2495
2496 /* ^4 */
Key148(W_Event * data)2497 static void Key148(W_Event * data)
2498 {
2499 emergency(help2, data);
2500 }
2501
2502 /* ^e */
Key197(W_Event * data)2503 static void Key197(W_Event * data)
2504 {
2505 emergency(escorting, data);
2506 }
2507
2508 /* ^p */
Key208(W_Event * data)2509 static void Key208(W_Event * data)
2510 {
2511 emergency(ogging, data);
2512 }
2513
2514 /* ^m */
Key205(W_Event * data)2515 static void Key205(W_Event * data)
2516 {
2517 emergency(bombing, data);
2518 }
2519
2520 /* ^l */
Key204(W_Event * data)2521 static void Key204(W_Event * data)
2522 {
2523 emergency(controlling, data);
2524 }
2525
2526
2527 /* ^O */
Key175(W_Event * data)2528 static void Key175(W_Event * data)
2529 {
2530 emergency(ogging, data);
2531 }
2532
2533 /* ^B */
Key162(W_Event * data)2534 static void Key162(W_Event * data)
2535 {
2536 emergency(bombing, data);
2537 }
2538
2539 /* ^C */
Key163(W_Event * data)2540 static void Key163(W_Event * data)
2541 {
2542 emergency(controlling, data);
2543 }
2544
2545 /* ^5 */
Key149(W_Event * data)2546 static void Key149(W_Event * data)
2547 {
2548 emergency(asw, data);
2549 }
2550
2551 /* ^6 */
Key150(W_Event * data)2552 static void Key150(W_Event * data)
2553 {
2554 emergency(asbomb, data);
2555 }
2556
2557 /* ^7 */
Key151(W_Event * data)2558 static void Key151(W_Event * data)
2559 {
2560 emergency(doing1, data);
2561 }
2562
2563 /* ^8 */
Key152(W_Event * data)2564 static void Key152(W_Event * data)
2565 {
2566 emergency(doing2, data);
2567 }
2568
2569 /* ^f */
Key198(W_Event * data)2570 static void Key198(W_Event * data)
2571 {
2572 emergency(free_beer, data);
2573 }
2574
2575 /* ^n */
Key206(W_Event * data)2576 static void Key206(W_Event * data)
2577 {
2578 emergency(no_gas, data);
2579 }
2580
2581 /* ^h */
Key200(W_Event * data)2582 static void Key200(W_Event * data)
2583 {
2584 emergency(crippled, data);
2585 }
2586
2587 /* ^9 */
Key153(W_Event * data)2588 static void Key153(W_Event * data)
2589 {
2590 emergency(pickup, data);
2591 }
2592
2593 /* ^0 */
Key144(W_Event * data)2594 static void Key144(W_Event * data)
2595 {
2596 emergency(pop, data);
2597 }
2598
2599 /* ^@ */
Key160(W_Event * data)2600 static void Key160(W_Event * data)
2601 {
2602 emergency(other1, data);
2603 }
2604
2605 /* ^# */
Key131(W_Event * data)2606 static void Key131(W_Event * data)
2607 {
2608 emergency(other2, data);
2609 }
2610