1 #include "osd_keyboard.h"
2 #include "hard_pce.h"
3 #include "sound.h"
4
5 #if defined(NETPLAY_DEBUG)
6 #include <sys/timeb.h>
7 #endif
8
9 Uint16 read_input (Uint16 port);
10
11 #ifdef ALLEGRO
12
13 Uint16 input1 (void), input2 (void), input3 (void), input4 (void),
14 input5 (void);
15
16 input_config config[16] = {
17 {
18 {input1, input2, input3, input4, input5},
19 {KEYBOARD1, NONE, NONE, NONE, NONE},
20 {0, 0, 0, 0, 0},
21 {0, 0, 0, 0, 0},
22 {0, 0, 0, 0, 0},
23 {0, 0, 0, 0, 0},
24 {
25 {KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_SPACE, KEY_ALT, KEY_TAB,
26 KEY_ENTER, KEY_C, KEY_X},
27 {},
28 {},
29 {},
30 {}
31 }
32 }
33 };
34
35
36 // info about the input config
37 #elif SDL
38
39 Uint8 *key;
40 Int16 joy[J_MAX];
41
42 input_config config[16] = {
43 { // Config 0
44 {
45 { 0, 0, 0, 0, 0, 0, { SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT,
46 SDLK_SPACE, SDLK_LALT, SDLK_TAB, SDLK_RETURN, SDLK_c, SDLK_x,
47 -1, -1, -1, -1, -1, -1, -1, -1 } },
48 { 0, 0, 0, 0, 0, 0, { 0 } },
49 { 0, 0, 0, 0, 0, 0, { 0 } },
50 { 0, 0, 0, 0, 0, 0, { 0 } },
51 { 0, 0, 0, 0, 0, 0, { 0 } }
52 }
53 }
54 };
55
56 // info about the input config
57 #endif
58
59 #if defined(ENABLE_NETPLAY)
60
61 //! socket set to check for activity on server socket (on client side)
62 static SDLNet_SocketSet client_socket_set;
63
64 //! client side socket for sending and receiving packets with the server
65 static UDPsocket client_socket;
66
67 //! incoming packet storage
68 static UDPpacket *incoming_packet;
69
70 //! outgoing packet storage
71 static UDPpacket *outgoing_packet;
72
73 //! address of the server to connect to
74 static IPaddress server_address;
75
76 //! Send identification packet(s) until we're sure the server is aware of our needs
77 static void send_identification (UChar *);
78
79 //! Send packet for telling the server what is the status of the current input reading
80 static void send_local_status (UChar *);
81
82 //! Wait for digest information from server using the lan protocol
83 static void wait_lan_digest_status (UChar *);
84
85 //! Wait for digest information from server using the internet protocol
86 static void wait_internet_digest_status (UChar *);
87
88
89 #endif // ENABLE_NETPLAY
90
91 UChar current_config;
92
93 // the number of the current config
94 char tmp_buf[100];
95
96 #define JOY_A 0x01
97 #define JOY_B 0x02
98 #define JOY_SELECT 0x04
99 #define JOY_RUN 0x08
100 #define JOY_UP 0x10
101 #define JOY_RIGHT 0x20
102 #define JOY_DOWN 0x40
103 #define JOY_LEFT 0x80
104
105 extern int UPeriod;
106
107
108 /* For joypad */
109 #ifndef SDL
110
111 #if !defined(FREEBSD)
112 struct js_event e;
113 #endif
114
115 js_status joypad[5];
116
117 #else
118
119 SDL_Joystick *joypad[5];
120
121 #endif
122
123 /* for keyboard */
124 #if defined(ALLEGRO)
125 UInt16
read_input(UInt16 port)126 read_input (UInt16 port)r
127 {
128 UInt16 tmp = 0;
129
130 if (key[config[current_config].joy_mapping[port][J_DOWN]])
131 tmp |= JOY_DOWN;
132 else if (key[config[current_config].joy_mapping[port][J_UP]])
133 tmp |= JOY_UP;
134
135 if (key[config[current_config].joy_mapping[port][J_LEFT]])
136 tmp |= JOY_LEFT;
137 else if (key[config[current_config].joy_mapping[port][J_RIGHT]])
138 tmp |= JOY_RIGHT;
139
140 if (key[config[current_config].joy_mapping[port][J_II]])
141 {
142 if (!config[current_config].autoII[port])
143 tmp |= JOY_A;
144 else
145 {
146 config[current_config].firedII[port] =
147 !config[current_config].firedII[port];
148 if (!config[current_config].firedII[port])
149 tmp |= JOY_A;
150 }
151 }
152
153 if (key[config[current_config].joy_mapping[port][J_I]])
154 {
155 if (!config[current_config].autoI[port])
156 tmp |= JOY_B;
157 else
158 {
159 config[current_config].firedI[port] =
160 !config[current_config].firedI[port];
161 if (!config[current_config].firedI[port])
162 tmp |= JOY_B;
163 }
164 }
165
166 if (key[config[current_config].joy_mapping[port][J_SELECT]])
167 tmp |= JOY_SELECT;
168
169 if (key[config[current_config].joy_mapping[port][J_RUN]])
170 tmp |= JOY_RUN;
171
172 if (key[config[current_config].joy_mapping[port][J_AUTOI]])
173 {
174 if (!key_delay)
175 {
176 config[current_config].autoI[port] =
177 !config[current_config].autoI[port];
178 key_delay = 10;
179 }
180 }
181
182 if (key[config[current_config].joy_mapping[port][J_AUTOII]])
183 {
184 if (!key_delay)
185 {
186 config[current_config].autoII[port] =
187 !config[current_config].autoII[port];
188 key_delay = 10;
189 }
190 }
191
192 return tmp;
193 }
194
195 #elif SDL
196
197 UInt16
read_input(UInt16 port)198 read_input (UInt16 port)
199 {
200 static char autoI_delay = 0, autoII_delay = 0;
201 UInt16 tmp;
202
203 key = SDL_GetKeyState (NULL);
204
205 for (tmp = J_PAD_START; tmp < J_MAX; tmp++)
206 joy[tmp] = 0;
207
208 tmp = 0;
209
210 if (config[current_config].individual_config[port].joydev)
211 {
212 SDL_Joystick * current_joypad = joypad[config[current_config].individual_config[port].joydev-1];
213
214 joy[J_PXAXIS] =
215 SDL_JoystickGetAxis (current_joypad,
216 config[current_config].individual_config[port].
217 joy_mapping[J_PXAXIS]);
218 joy[J_PYAXIS] =
219 SDL_JoystickGetAxis (current_joypad,
220 config[current_config].individual_config[port].
221 joy_mapping[J_PYAXIS]);
222 joy[J_PRUN] =
223 SDL_JoystickGetButton (current_joypad,
224 config[current_config].individual_config[port].
225 joy_mapping[J_PRUN]);
226 joy[J_PSELECT] =
227 SDL_JoystickGetButton (current_joypad,
228 config[current_config].individual_config[port].
229 joy_mapping[J_PSELECT]);
230 joy[J_PI] =
231 SDL_JoystickGetButton (current_joypad,
232 config[current_config].individual_config[port].
233 joy_mapping[J_PI]);
234 joy[J_PII] =
235 SDL_JoystickGetButton (current_joypad,
236 config[current_config].individual_config[port].
237 joy_mapping[J_PII]);
238 joy[J_PAUTOI] =
239 SDL_JoystickGetButton (current_joypad,
240 config[current_config].individual_config[port].
241 joy_mapping[J_PAUTOI]);
242 joy[J_PAUTOII] =
243 SDL_JoystickGetButton (current_joypad,
244 config[current_config].individual_config[port].
245 joy_mapping[J_PAUTOII]);
246 }
247
248 if (key[config[current_config].individual_config[port].joy_mapping[J_UP]]
249 || (joy[J_PYAXIS] < -16384))
250 tmp |= JOY_UP;
251 else if (key[config[current_config].individual_config[port].joy_mapping[J_DOWN]]
252 || (joy[J_PYAXIS] > 16383))
253 tmp |= JOY_DOWN;
254
255 if (key[config[current_config].individual_config[port].joy_mapping[J_LEFT]]
256 || (joy[J_PXAXIS] < -16384))
257 tmp |= JOY_LEFT;
258 else if (key[config[current_config].individual_config[port].joy_mapping[J_RIGHT]]
259 || (joy[J_PXAXIS] > 16383))
260 tmp |= JOY_RIGHT;
261
262 if (key[config[current_config].individual_config[port].joy_mapping[J_II]] || joy[J_PII])
263 {
264 if (!config[current_config].individual_config[port].autoII)
265 tmp |= JOY_B;
266 else
267 {
268 config[current_config].individual_config[port].firedII =
269 !config[current_config].individual_config[port].firedII;
270 if (!config[current_config].individual_config[port].firedII)
271 tmp |= JOY_B;
272 }
273 }
274
275 if (key[config[current_config].individual_config[port].joy_mapping[J_I]] || joy[J_PI])
276 {
277 if (!config[current_config].individual_config[port].autoI)
278 tmp |= JOY_A;
279 else
280 {
281 config[current_config].individual_config[port].firedI =
282 !config[current_config].individual_config[port].firedI;
283 if (!config[current_config].individual_config[port].firedI)
284 tmp |= JOY_A;
285 }
286 }
287
288 if (key[config[current_config].individual_config[port].joy_mapping[J_SELECT]]
289 || joy[J_PSELECT])
290 tmp |= JOY_SELECT;
291
292 if (key[config[current_config].individual_config[port].joy_mapping[J_RUN]] || joy[J_PRUN])
293 tmp |= JOY_RUN;
294
295 if (key[config[current_config].individual_config[port].joy_mapping[J_AUTOI]] || joy[J_PAUTOI])
296 {
297 if (!autoI_delay)
298 {
299 config[current_config].individual_config[port].autoI =
300 !config[current_config].individual_config[port].autoI;
301 autoI_delay = 20;
302 }
303 }
304
305 if (key[config[current_config].individual_config[port].joy_mapping[J_AUTOII]]
306 || joy[J_PAUTOII])
307 {
308 if (!autoII_delay)
309 {
310 config[current_config].individual_config[port].autoII =
311 !config[current_config].individual_config[port].autoII;
312 autoII_delay = 20;
313 }
314 }
315
316 if (autoI_delay)
317 autoI_delay--;
318
319 if (autoII_delay)
320 autoII_delay--;
321
322 return tmp;
323 }
324
325 #endif // SDL
326
327
328 #if defined(ALLEGRO)
329
330 /* for nothing */
331 UInt16
noinput()332 noinput ()
333 {
334 return 0;
335 }
336
337
338 UInt16
input1(void)339 input1 (void)
340 {
341 return read_input (0);
342 }
343
344 UInt16
input2(void)345 input2 (void)
346 {
347 return read_input (1);
348 }
349
350 UInt16
input3(void)351 input3 (void)
352 {
353 return read_input (2);
354 }
355
356 UInt16
input4(void)357 input4 (void)
358 {
359 return read_input (3);
360 }
361
362 UInt16
input5(void)363 input5 (void)
364 {
365 return read_input (4);
366 }
367
368
369 /* for joypad */
370 void
poll_joypad(int port)371 poll_joypad (int port)
372 {
373 #if !defined(FREEBSD)
374 while (read ((int) fd[port], &e, sizeof (e)) > 0)
375 {
376 if (e.type & JS_EVENT_BUTTON)
377 joypad[port].button[e.number] = e.value;
378 else if (e.type & JS_EVENT_AXIS)
379 joypad[port].axis[e.number] = e.value;
380 }
381 #endif
382 }
383
384 #else
385
386 void
sdl_config_joypad_axis(short which,joymap axis,UInt16 * bad_axes,UInt16 num_axes)387 sdl_config_joypad_axis (short which, joymap axis, UInt16 * bad_axes,
388 UInt16 num_axes)
389 {
390 unsigned char t;
391 boolean done = FALSE;
392
393 while (1)
394 {
395 if (read (fileno (stdin), &t, 1) == -1)
396 break;
397 }
398
399 while (!done)
400 {
401 time_t stime, ntime;
402 int axes;
403
404 if (read (fileno (stdin), &t, 1) == -1)
405 {
406 if (errno != EAGAIN)
407 break;
408 }
409 else
410 break;
411
412 SDL_JoystickUpdate ();
413
414 for (axes = num_axes - 1; axes >= 0; axes--)
415 {
416 if (bad_axes[axes])
417 continue;
418
419 if (abs (SDL_JoystickGetAxis (joypad[which], axes)) > 16384)
420 {
421 printf
422 (" -- Activity reported on axis %d; Please release axis . . .\n",
423 axes);
424
425 config[current_config].individual_config[which].joy_mapping[axis] = axes;
426
427 done = 1;
428
429 stime = time (NULL);
430
431 while (abs (SDL_JoystickGetAxis (joypad[which], axes)) > 16384)
432 {
433 SDL_JoystickUpdate ();
434 SDL_Delay (50);
435 ntime = time (NULL);
436
437 if ((ntime - stime) > 3)
438 {
439 bad_axes[axes] = 1;
440 done = 0;
441 printf
442 (" ** Activity still reported on axis after 3 seconds, marking as invalid\n\n"
443 " Please try another axis now . . .\n");
444 break;
445 }
446 }
447 printf ("\n");
448 }
449 }
450 }
451
452 while (1)
453 {
454 if (read (fileno (stdin), &t, 1) == -1)
455 break;
456 }
457 }
458
459
460 void
sdl_config_joypad_button(short which,joymap button,UInt16 * bad_buttons,UInt16 num_buttons)461 sdl_config_joypad_button (short which, joymap button, UInt16 * bad_buttons,
462 UInt16 num_buttons)
463 {
464 unsigned char t;
465 boolean done = FALSE;
466
467 while (1)
468 {
469 if (read (fileno (stdin), &t, 1) == -1)
470 break;
471 }
472
473 while (!done)
474 {
475 time_t stime, ntime;
476 int buttons;
477
478 if (read (fileno (stdin), &t, 1) == -1)
479 {
480 if (errno != EAGAIN)
481 break;
482 }
483 else
484 break;
485
486 SDL_JoystickUpdate ();
487
488 for (buttons = num_buttons - 1; buttons >= 0; buttons--)
489 {
490 if (bad_buttons[buttons])
491 continue;
492
493 if (SDL_JoystickGetButton (joypad[which], buttons))
494 {
495 printf
496 (" -- Button %d is pressed; Please release button . . .\n",
497 buttons);
498
499 config[current_config].individual_config[which].joy_mapping[button] = buttons;
500
501 done = TRUE;
502
503 stime = time (NULL);
504
505 while (SDL_JoystickGetButton (joypad[which], buttons))
506 {
507 SDL_JoystickUpdate ();
508 SDL_Delay (50);
509 ntime = time (NULL);
510
511 if ((ntime - stime) > 3)
512 {
513 bad_buttons[buttons] = 1;
514 done = FALSE;
515
516 printf
517 (" ** Button %d still claiming to be pressed after 3 seconds, marked as invalid\n\n"
518 " Please try another button now . . .\n",
519 buttons);
520 break;
521 }
522 }
523 printf ("\n");
524 }
525 }
526 }
527
528 while (1)
529 {
530 if (read (fileno (stdin), &t, 1) == -1)
531 break;
532 }
533 }
534
535
536 void
sdl_config_joypad(short which)537 sdl_config_joypad (short which)
538 {
539 int sa;
540 UInt16 *bad_vals, n;
541
542 printf (" ^ We need to configure this joypad ^\n"
543 " Press [ENTER] when ready to begin, [ENTER] can also be used to skip configuration steps.\n");
544 getchar ();
545
546 #if !defined(WIN32)
547 sa = fcntl (fileno (stdin), F_GETFL);
548 fcntl (fileno (stdin), F_SETFL, O_NONBLOCK);
549 #endif
550
551 n = SDL_JoystickNumAxes (joypad[which]);
552 bad_vals = (UInt16 *) calloc (sizeof (UInt16), n);
553
554 printf (" - Press axis to use as x-plane (left/right)\n");
555 sdl_config_joypad_axis (which, J_PXAXIS, bad_vals, n);
556
557 printf (" - Press axis to use as y-plane (up/down)\n");
558 sdl_config_joypad_axis (which, J_PYAXIS, bad_vals, n);
559
560 free (bad_vals);
561
562 n = SDL_JoystickNumButtons (joypad[which]);
563 bad_vals = (UInt16 *) calloc (sizeof (UInt16), n);
564
565 printf (" - Press button to use for 'RUN'\n");
566 sdl_config_joypad_button (which, J_PRUN, bad_vals, n);
567
568 printf (" - Press button to use for 'SELECT'\n");
569 sdl_config_joypad_button (which, J_PSELECT, bad_vals, n);
570
571 printf
572 (" - Press button to use for 'I' (right-most button on pce pad)\n");
573 sdl_config_joypad_button (which, J_PI, bad_vals, n);
574
575 printf (" - Press button to use for autofire toggle on 'I'\n");
576 sdl_config_joypad_button (which, J_PAUTOI, bad_vals, n);
577
578 printf
579 (" - Press button to use for 'II' (left-most button on pce pad)\n");
580 sdl_config_joypad_button (which, J_PII, bad_vals, n);
581
582 printf (" - Press button to use for autofire toggle on 'II'\n");
583 sdl_config_joypad_button (which, J_PAUTOII, bad_vals, n);
584
585 free (bad_vals);
586
587 printf (" Player %d\n"
588 " *------------------------------------*\n"
589 " | %2d %2d %2d |\n"
590 " | __ Turbo Turbo |\n"
591 " | || __ __ |\n"
592 " | |====| %2d (%2d) (%2d) |\n"
593 " | || [%2d] [%2d] ~~ ~~ |\n"
594 " | ~~ Select Run II I |\n"
595 " *------------------------------------*\n\n", which + 1,
596 config[current_config].individual_config[which].joy_mapping[J_PYAXIS],
597 config[current_config].individual_config[which].joy_mapping[J_PAUTOII],
598 config[current_config].individual_config[which].joy_mapping[J_PAUTOI],
599 config[current_config].individual_config[which].joy_mapping[J_PXAXIS],
600 config[current_config].individual_config[which].joy_mapping[J_PII],
601 config[current_config].individual_config[which].joy_mapping[J_PI],
602 config[current_config].individual_config[which].joy_mapping[J_PSELECT],
603 config[current_config].individual_config[which].joy_mapping[J_PRUN]);
604
605 #if !defined(WIN32)
606 fcntl (fileno (stdin), F_SETFL, sa);
607 #endif
608 }
609
610
611 void
sdl_init_joypads(void)612 sdl_init_joypads (void)
613 {
614 int n;
615 int joypad_number = SDL_NumJoysticks();
616
617 printf("Found %d joypad%s\n", joypad_number, joypad_number > 1 ? "s" : "");
618
619 for (n = 0; n < joypad_number; n++)
620 {
621 // if (config[current_config].individual_config[n].joydev == 0)
622 // {
623 // joypad[n] = NULL;
624 // continue;
625 // }
626
627 if ((joypad[n] = SDL_JoystickOpen(n)) == NULL)
628 {
629 printf ("SDL could not open system joystick device %d (%s)\n", n, SDL_GetError ());
630 continue;
631 }
632
633 // printf("joypad[%d] = %p\n", n, joypad[n]);
634
635 printf (" * PCE joypad %d: %s, %d axes, %d buttons\n", n + 1,
636 SDL_JoystickName (n),
637 SDL_JoystickNumAxes (joypad[n]),
638 SDL_JoystickNumButtons (joypad[n]));
639
640 // if (option.configure_joypads)
641 // sdl_config_joypad (n);
642 }
643 }
644
645 #endif // SDL
646
647
648 #ifndef SDL
649
650 UInt16
read_joypad(int port)651 read_joypad (int port)
652 {
653 UInt16 tmp = 0;
654
655
656 poll_joypad (port);
657
658 if (joypad[port].axis[0] < 0)
659 tmp |= JOY_LEFT;
660 else if (joypad[port].axis[0] > 0)
661 tmp |= JOY_RIGHT;
662
663 if (joypad[port].axis[1] < 0)
664 tmp |= JOY_UP;
665 else if (joypad[port].axis[1] > 0)
666 tmp |= JOY_DOWN;
667
668 if (joypad[port].button[config[current_config].joy_mapping[port][J_PRUN]])
669 tmp |= JOY_RUN;
670
671 if (joypad[port].
672 button[config[current_config].joy_mapping[port][J_PSELECT]])
673 tmp |= JOY_SELECT;
674
675 // Set Autofire I to Autofire II button status
676 config[current_config].autoI[port] =
677 joypad[port].button[config[current_config].joy_mapping[port][J_PAUTOI]];
678
679 // Set Autofire II to Autofire II button status
680 config[current_config].autoII[port] =
681 joypad[port].button[config[current_config].joy_mapping[port][J_PAUTOII]];
682
683 // Button I, fixed Autofire
684 if (joypad[port].button[config[current_config].joy_mapping[port][J_PI]])
685 {
686 if (config[current_config].autoI[port])
687 {
688 config[current_config].firedI[port] =
689 !config[current_config].firedI[port];
690 if (!config[current_config].firedI[port])
691 tmp |= JOY_A;
692 }
693 else
694 tmp |= JOY_A;
695 }
696
697 // Button II, fixed Autofire
698 if (joypad[port].button[config[current_config].joy_mapping[port][J_PII]])
699 {
700 if (config[current_config].autoII[port])
701 {
702 config[current_config].firedII[port] =
703 !config[current_config].firedII[port];
704 if (!config[current_config].firedII[port])
705 tmp |= JOY_B;
706 }
707 else
708 tmp |= JOY_B;
709 }
710
711
712 return tmp;
713 }
714
715 UInt16
joypad1(void)716 joypad1 (void)
717 {
718 return read_joypad (0);
719 }
720
721 UInt16
joypad2(void)722 joypad2 (void)
723 {
724 return read_joypad (1);
725 }
726
727 UInt16
joypad3(void)728 joypad3 (void)
729 {
730 return read_joypad (2);
731 }
732
733 UInt16
joypad4(void)734 joypad4 (void)
735 {
736 return read_joypad (3);
737 }
738
739
740 /* for mouse */
741 UInt16
mouse1(void)742 mouse1 (void)
743 {
744 return 0;
745 }
746
747 UInt16
mouse2(void)748 mouse2 (void)
749 {
750 return 0;
751 }
752
753
754 /* for synaptic link */
755 UInt16
synaplink(void)756 synaplink (void)
757 {
758 return 0;
759 }
760
761
762 int
osd_keyboard(void)763 osd_keyboard (void)
764 {
765
766 // char tmp_joy;
767
768
769 while (key[KEY_PAUSE])
770 pause ();
771
772 if (key[KEY_ASTERISK])
773 {
774 UInt32 sav_timer = timer_60;
775 if (sound_driver == 1)
776 osd_snd_set_volume (0);
777 disass_menu ();
778 if (sound_driver == 1)
779 osd_snd_set_volume (gen_vol);
780 timer_60 = sav_timer;
781 key_delay = 10;
782
783 break;
784 }
785 if ((key[KEY_F4]) && (!key_delay))
786
787 {
788 UInt32 sav_timer = timer_60;
789 UChar error_code;
790 error_code = gui ();
791 key_delay = 10;
792 timer_60 = sav_timer;
793 if (error_code)
794 return 1;
795
796 break;
797 }
798 if ((key[KEY_ESC]) && (!key_delay))
799
800 {
801 UInt32 sav_timer = timer_60;
802
803 /*
804 old_vol=voice_get_volume(PCM_voice);
805 voice_set_volume(PCM_voice,0);
806 */
807 if (sound_driver == 1)
808 osd_snd_set_volume (0);
809
810 //menu(); //There will be the GUI
811 while (keypressed ())
812 readkey ();
813 select_rom ("*.pce");
814 while (keypressed ())
815 readkey ();
816 key_delay = 10;
817 timer_60 = sav_timer;
818 if (!strcmp ("TRUE EXIT", selected_rom))
819
820 {
821 cart_reload = 0;
822 return 1;
823 }
824
825 /*
826 voice_set_volume(PCM_voice,old_vol);
827 */
828 if (sound_driver == 1)
829 osd_snd_set_volume (gen_vol);
830 if (strcmp ("NO FILE", selected_rom))
831
832 {
833 cart_reload = 1;
834 strcpy (cart_name, selected_rom);
835 return 1;
836 }
837 }
838 if (key[KEY_F12])
839 return 1;
840 if (!key_delay)
841
842 {
843 if (key[KEY_F6])
844
845 {
846 UInt32 sav_timer = timer_60;
847
848 {
849
850 // AGetVoiceVolume(hVoice,&vol);
851 // ASetVoiceVolume(hVoice,0);
852 if (!silent)
853
854 {
855
856 /*
857 voice_stop(PCM_voice);
858 set_volume(1,1);
859 voice_set_volume(PCM_voice,1);
860 voice_start(PCM_voice);
861 */
862 if (sound_driver == 1)
863 osd_snd_set_volume (0);
864 }
865 }
866 if (!savegame ())
867
868 {
869 osd_gfx_set_message (MESSAGE[language][game_save]);
870 message_delay = 180;
871 }
872 if (!silent)
873
874 {
875 if (sound_driver == 1)
876 osd_snd_set_volume (gen_vol);
877 }
878 timer_60 = sav_timer;
879 };
880 if (key[KEY_F5])
881
882 {
883 UInt32 sav_timer = timer_60;
884 sprintf (tmp_buf, MESSAGE[language][screen_shot],
885 osd_gfx_savepict ());
886 osd_gfx_set_message (tmp_buf);
887 message_delay = 180;
888 key_delay = 10;
889 timer_60 = sav_timer;
890 };
891 if (key[KEY_F10])
892
893 {
894 synchro = !synchro;
895 osd_gfx_set_message (MESSAGE[language][full_speed + synchro]);
896 message_delay = 180;
897 key_delay = 10;
898 };
899 if (key[KEY_NUMLOCK])
900 {
901 if (dump_snd)
902 {
903 UInt32 dummy;
904 dummy = filesize (out_snd);
905 fseek (out_snd, 4, SEEK_SET);
906 fwrite (&dummy, 1, 4, out_snd);
907 dummy -= 0x2C;
908 fseek (out_snd, 0x28, SEEK_SET);
909 fwrite (&dummy, 1, 4, out_snd);
910 fclose (out_snd);
911 osd_gfx_set_message (MESSAGE[language][dump_off]);
912 }
913
914 else
915
916 {
917 unsigned short tmp = 0;
918 strcpy (tmp_buf, "SND0000.WAV");
919 while ((tmp < 0xFFFF)
920 && ((out_snd = fopen (tmp_buf, "rb")) != NULL))
921 {
922 fclose (out_snd);
923 sprintf (tmp_buf, "SND%04X.WAV", ++tmp);
924 }
925 out_snd = fopen (tmp_buf, "wb");
926 fwrite ("RIFF\145\330\073\0WAVEfmt ", 16, 1, out_snd);
927 putc (0x10, out_snd); // size
928 putc (0x00, out_snd);
929 putc (0x00, out_snd);
930 putc (0x00, out_snd);
931 putc (1, out_snd); // PCM data
932 putc (0, out_snd);
933 putc (1, out_snd); // mono
934 putc (0, out_snd);
935 putc (host.sound.freq, out_snd); // frequency
936 putc (host.sound.freq >> 8, out_snd);
937 putc (host.sound.freq >> 16, out_snd);
938 putc (host.sound.freq >> 24, out_snd);
939 putc (host.sound.freq, out_snd); // frequency
940 putc (host.sound.freq >> 8, out_snd);
941 putc (host.sound.freq >> 16, out_snd);
942 putc (host.sound.freq >> 24, out_snd);
943 putc (1, out_snd);
944 putc (0, out_snd);
945 putc (8, out_snd); // 8 bits
946 putc (0, out_snd);
947 fwrite ("data\377\377\377\377", 1, 9, out_snd);
948 osd_gfx_set_message (MESSAGE[language][dump_on]);
949 }
950 dump_snd = !dump_snd;
951 key_delay = 10;
952 message_delay = 180;
953 }
954 if (key[KEY_PLUS_PAD])
955
956 {
957 if (UPeriod < 15)
958
959 {
960 UPeriod++;
961 sprintf (tmp_buf, MESSAGE[language][frame_skip], UPeriod);
962 osd_gfx_set_message (tmp_buf);
963 message_delay = 180;
964 };
965 key_delay = 10;
966 };
967 if (key[KEY_MINUS_PAD])
968
969 {
970 if (UPeriod)
971
972 {
973 UPeriod--;
974 if (!UPeriod)
975 osd_gfx_set_message (MESSAGE[language][all_frame]);
976
977 else
978
979 {
980 sprintf (tmp_buf, MESSAGE[language][frame_skip], UPeriod);
981 osd_gfx_set_message (tmp_buf);
982 };
983 message_delay = 180;
984 };
985 key_delay = 10;
986 };
987 if (key[KEY_1])
988
989 {
990 SPONSwitch = !SPONSwitch;
991 key_delay = 10;
992 }
993 if (key[KEY_2])
994
995 {
996 BGONSwitch = !BGONSwitch;
997 key_delay = 10;
998 }
999 }
1000 if (key[KEY_F1])
1001
1002 {
1003 UInt32 sav_timer = timer_60;
1004 if (sound_driver == 1)
1005 osd_snd_set_volume (0);
1006 searchbyte ();
1007 if (sound_driver == 1)
1008 osd_snd_set_volume (gen_vol);
1009 timer_60 = sav_timer;
1010 return 0;
1011 }
1012 if (key[KEY_F2])
1013
1014 {
1015 UInt32 sav_timer = timer_60;
1016 if (sound_driver == 1)
1017 osd_snd_set_volume (0);
1018 pokebyte ();
1019 if (sound_driver == 1)
1020 osd_snd_set_volume (gen_vol);
1021 timer_60 = sav_timer;
1022 return 0;
1023 }
1024 if (key[KEY_F7])
1025
1026 {
1027 UInt32 sav_timer = timer_60;
1028 if (!loadgame ())
1029
1030 {
1031 osd_gfx_set_message (MESSAGE[language][game_load]);
1032 message_delay = 180;
1033 }
1034 timer_60 = sav_timer;
1035 };
1036 if (key[KEY_F3])
1037
1038 {
1039 UInt32 sav_timer = timer_60;
1040 if (sound_driver == 1)
1041 osd_snd_set_volume (0);
1042 freeze_value ();
1043 if (sound_driver == 1)
1044 osd_snd_set_volume (gen_vol);
1045 timer_60 = sav_timer;
1046 return 0;
1047 }
1048 if (key[KEY_TILDE])
1049
1050 {
1051 char *tmp = (char *) alloca (100);
1052 sprintf (tmp, "FRAME DELTA = %d",
1053 frame - HCD_frame_at_beginning_of_track);
1054 osd_gfx_set_message (tmp);
1055 message_delay = 240;
1056 }
1057 if (key[KEY_3])
1058
1059 //cd_port_1800 = 0xD0;
1060 io.cd_port_1800 &= ~0x40;
1061 if (key[KEY_4])
1062 Wr6502 (0x2066, Rd6502 (0x2066) | 32);
1063 if (key[KEY_5])
1064 io.cd_port_1800 = 0xD8;
1065 if (key[KEY_6])
1066 Wr6502 (0x22D6, 1);
1067 if (key[KEY_8])
1068 Wr6502 (0x20D8, 128);
1069
1070 //Wr6502(0x20D8,Rd6502(0x20D8) | 128);
1071 if (key[KEY_MINUS])
1072
1073 {
1074 if (gen_vol)
1075 gen_vol--;
1076 if (sound_driver == 1)
1077
1078 {
1079 osd_snd_set_volume (gen_vol);
1080 sprintf (tmp_buf, MESSAGE[language][volume_set_to], gen_vol);
1081 osd_gfx_set_message (tmp_buf);
1082 message_delay = 60;
1083 }
1084 }
1085 if (key[KEY_EQUALS])
1086
1087 {
1088 if (gen_vol < 255)
1089 gen_vol++;
1090 if (sound_driver == 1)
1091
1092 {
1093 osd_snd_set_volume (gen_vol);
1094 sprintf (tmp_buf, MESSAGE[language][volume_set_to], gen_vol);
1095 osd_gfx_set_message (tmp_buf);
1096 message_delay = 60;
1097 }
1098 }
1099
1100 if (key[KEY_0])
1101
1102 {
1103 if (host.sound.freq < 44100)
1104 host.sound.freq += 50;
1105 if (sound_driver == 1)
1106
1107 {
1108 voice_set_frequency (PCM_stream->voice, host.sound.freq);
1109 sprintf (tmp_buf, MESSAGE[language][freq_set_to], host.sound.freq);
1110 osd_gfx_set_message (tmp_buf);
1111 message_delay = 60;
1112 }
1113 }
1114 if (key[KEY_9])
1115
1116 {
1117 if (host.sound.freq > 11025)
1118 host.sound.freq -= 50;
1119 if (sound_driver == 1)
1120
1121 {
1122 voice_set_frequency (PCM_stream->voice, host.sound.freq);
1123 sprintf (tmp_buf, MESSAGE[language][freq_set_to], host.sound.freq);
1124 osd_gfx_set_message (tmp_buf);
1125 message_delay = 60;
1126 }
1127 }
1128
1129 io.JOY[0] = read_input (0);
1130 io.JOY[1] = read_input (1);
1131 io.JOY[2] = read_input (2);
1132 io.JOY[3] = read_input (3);
1133 io.JOY[4] = read_input (4);
1134 return 0;
1135 }
1136
1137 #elif SDL
1138
1139 int
osd_keyboard(void)1140 osd_keyboard (void)
1141 {
1142 // char tmp_joy;
1143
1144 SDL_Event event;
1145
1146 #warning "need for pause support"
1147 /*
1148 * while (key[KEY_PAUSE])
1149 * pause ();
1150 */
1151
1152 while (SDL_PollEvent (&event))
1153 {
1154
1155 switch (event.type)
1156 {
1157 case SDL_KEYDOWN:
1158 switch (event.key.keysym.sym)
1159 {
1160
1161 case SDLK_ASTERISK:
1162 {
1163 UInt32 sav_timer = timer_60;
1164 if (sound_driver == 1)
1165 osd_snd_set_volume (0);
1166 disass_menu ();
1167 if (sound_driver == 1)
1168 osd_snd_set_volume (gen_vol);
1169 timer_60 = sav_timer;
1170 key_delay = 10;
1171 break;
1172 }
1173
1174 case SDLK_F4:
1175 {
1176 if (key[SDLK_LSHIFT])
1177 {
1178 io.psg_channel_disabled[3] = !io.psg_channel_disabled[3];
1179 }
1180 else if (key[SDLK_RSHIFT])
1181 {
1182 if (dump_snd)
1183 {
1184 stop_dump_audio ();
1185 dump_snd = 0;
1186 }
1187 else
1188 {
1189 dump_snd = start_dump_audio ();
1190 }
1191 }
1192 else
1193 {
1194 if (video_dump_flag || dump_snd)
1195 {
1196 stop_dump_video ();
1197 stop_dump_audio ();
1198 video_dump_flag = 0;
1199 dump_snd = 0;
1200 }
1201 else
1202 {
1203 if (start_dump_video () && start_dump_audio ())
1204 {
1205 video_dump_flag = 1;
1206 dump_snd = 1;
1207 }
1208 else
1209 {
1210 stop_dump_video ();
1211 stop_dump_audio ();
1212 }
1213 }
1214 }
1215 break;
1216 }
1217
1218 case SDLK_F9:
1219 SDL_ShowCursor (ToggleFullScreen ());
1220 break;
1221
1222 case SDLK_F12:
1223 case SDLK_ESCAPE:
1224 return 1;
1225
1226 case SDLK_F6:
1227 {
1228 if (key[SDLK_LSHIFT])
1229 {
1230 io.psg_channel_disabled[5] = !io.psg_channel_disabled[5];
1231 }
1232 else
1233 {
1234
1235
1236
1237 UInt32 sav_timer = timer_60;
1238 {
1239 // AGetVoiceVolume(hVoice,&vol);
1240 // ASetVoiceVolume(hVoice,0);
1241 if (!silent)
1242 {
1243 /*
1244 voice_stop(PCM_voice);
1245 set_volume(1,1);
1246 voice_set_volume(PCM_voice,1);
1247 voice_start(PCM_voice);
1248 */
1249 if (sound_driver == 1)
1250 osd_snd_set_volume (0);
1251 }
1252 }
1253 if (!savegame ())
1254
1255 {
1256 osd_gfx_set_message (MESSAGE[language][game_save]);
1257 message_delay = 180;
1258 }
1259 if (!silent)
1260
1261 {
1262 if (sound_driver == 1)
1263 osd_snd_set_volume (gen_vol);
1264 }
1265 timer_60 = sav_timer;
1266 }
1267 break;
1268 }
1269
1270 case SDLK_F5:
1271
1272 {
1273 if (key[SDLK_LSHIFT])
1274 {
1275 io.psg_channel_disabled[4] = !io.psg_channel_disabled[4];
1276 }
1277 else
1278 {
1279 UInt32 sav_timer = timer_60;
1280 sprintf (tmp_buf,
1281 MESSAGE[language][screen_shot],
1282 osd_gfx_savepict ());
1283 osd_gfx_set_message (tmp_buf);
1284 message_delay = 180;
1285 key_delay = 10;
1286 timer_60 = sav_timer;
1287 }
1288 break;
1289 }
1290 case SDLK_F10:
1291 {
1292 synchro = !synchro;
1293 osd_gfx_set_message (MESSAGE[language][full_speed + synchro]);
1294 message_delay = 180;
1295 key_delay = 10;
1296 break;
1297 }
1298
1299 case SDLK_NUMLOCK:
1300 {
1301 if (dump_snd)
1302
1303 {
1304 UInt32 dummy;
1305 dummy = filesize (out_snd);
1306 fseek (out_snd, 4, SEEK_SET);
1307 fwrite (&dummy, 1, 4, out_snd);
1308 dummy -= 0x2C;
1309 fseek (out_snd, 0x28, SEEK_SET);
1310 fwrite (&dummy, 1, 4, out_snd);
1311 fclose (out_snd);
1312 osd_gfx_set_message (MESSAGE[language][dump_off]);
1313 }
1314
1315 else
1316
1317 {
1318 unsigned short tmp = 0;
1319 strcpy (tmp_buf, "snd0000.wav");
1320 while ((tmp < 0xFFFF)
1321 && ((out_snd = fopen (tmp_buf, "rb")) != NULL))
1322 {
1323 sprintf (tmp_buf, "snd%04x.wav", ++tmp);
1324 fclose (out_snd);
1325 }
1326 out_snd = fopen (tmp_buf, "wb");
1327 fwrite ("RIFF\145\330\073\0WAVEfmt ", 16, 1, out_snd);
1328 putc (0x10, out_snd); // size
1329 putc (0x00, out_snd);
1330 putc (0x00, out_snd);
1331 putc (0x00, out_snd);
1332 putc (1, out_snd); // PCM data
1333 putc (0, out_snd);
1334 putc (1, out_snd); // mono
1335 putc (0, out_snd);
1336 putc (host.sound.freq, out_snd); // frequency
1337 putc (host.sound.freq >> 8, out_snd);
1338 putc (host.sound.freq >> 16, out_snd);
1339 putc (host.sound.freq >> 24, out_snd);
1340 putc (host.sound.freq, out_snd); // frequency
1341 putc (host.sound.freq >> 8, out_snd);
1342 putc (host.sound.freq >> 16, out_snd);
1343 putc (host.sound.freq >> 24, out_snd);
1344 putc (1, out_snd);
1345 putc (0, out_snd);
1346 putc (8, out_snd); // 8 bits
1347 putc (0, out_snd);
1348 fwrite ("data\377\377\377\377", 1, 9, out_snd);
1349 osd_gfx_set_message (MESSAGE[language][dump_on]);
1350 }
1351 dump_snd = !dump_snd;
1352 key_delay = 10;
1353 message_delay = 180;
1354 break;
1355 }
1356
1357 case SDLK_KP_PLUS:
1358 {
1359 if (UPeriod < 15)
1360 {
1361 UPeriod++;
1362 sprintf (tmp_buf, MESSAGE[language][frame_skip], UPeriod);
1363 osd_gfx_set_message (tmp_buf);
1364 message_delay = 180;
1365 };
1366 key_delay = 10;
1367 break;
1368 }
1369
1370 case SDLK_KP_MINUS:
1371 {
1372 if (UPeriod)
1373 {
1374 UPeriod--;
1375 if (!UPeriod)
1376 {
1377 osd_gfx_set_message (MESSAGE[language][all_frame]);
1378 }
1379 else
1380 {
1381 sprintf (tmp_buf,
1382 MESSAGE[language][frame_skip], UPeriod);
1383 osd_gfx_set_message (tmp_buf);
1384 };
1385 message_delay = 180;
1386 };
1387 key_delay = 10;
1388 }
1389 break;
1390
1391 case SDLK_1:
1392
1393 {
1394 if (key[SDLK_LSHIFT])
1395 {
1396 io.psg_channel_disabled[0] = !io.psg_channel_disabled[0];
1397 }
1398 else
1399 {
1400 SPONSwitch = !SPONSwitch;
1401 key_delay = 10;
1402 }
1403 break;
1404 }
1405
1406 case SDLK_2:
1407 {
1408 if (key[SDLK_LSHIFT])
1409 {
1410 io.psg_channel_disabled[1] = !io.psg_channel_disabled[1];
1411 }
1412 else
1413 {
1414 BGONSwitch = !BGONSwitch;
1415 key_delay = 10;
1416 }
1417 break;
1418 }
1419
1420 case SDLK_F1:
1421 {
1422 if (key[SDLK_LSHIFT])
1423 {
1424 io.psg_channel_disabled[0] = !io.psg_channel_disabled[0];
1425 }
1426 else
1427 {
1428 UInt32 sav_timer = timer_60;
1429 if (sound_driver == 1)
1430 osd_snd_set_volume (0);
1431 searchbyte ();
1432 if (sound_driver == 1)
1433 osd_snd_set_volume (gen_vol);
1434 timer_60 = sav_timer;
1435 return 0;
1436 }
1437 break;
1438 }
1439
1440 case SDLK_F2:
1441 {
1442 if (key[SDLK_LSHIFT])
1443 {
1444 io.psg_channel_disabled[1] = !io.psg_channel_disabled[1];
1445 }
1446 else
1447 {
1448 UInt32 sav_timer = timer_60;
1449 if (sound_driver == 1)
1450 osd_snd_set_volume (0);
1451 pokebyte ();
1452 if (sound_driver == 1)
1453 osd_snd_set_volume (gen_vol);
1454 timer_60 = sav_timer;
1455 return 0;
1456 }
1457 break;
1458 }
1459
1460 case SDLK_F7:
1461 {
1462 UInt32 sav_timer = timer_60;
1463 if (!loadgame ())
1464
1465 {
1466 osd_gfx_set_message (MESSAGE[language][game_load]);
1467 message_delay = 180;
1468 }
1469 timer_60 = sav_timer;
1470 break;
1471 }
1472
1473 case SDLK_F3:
1474 {
1475 if (key[SDLK_LSHIFT])
1476 {
1477 io.psg_channel_disabled[2] = !io.psg_channel_disabled[2];
1478 }
1479 else
1480 {
1481 UInt32 sav_timer = timer_60;
1482 if (sound_driver == 1)
1483 osd_snd_set_volume (0);
1484 freeze_value ();
1485 if (sound_driver == 1)
1486 osd_snd_set_volume (gen_vol);
1487 timer_60 = sav_timer;
1488 return 0;
1489 }
1490 break;
1491 }
1492
1493 case SDLK_BACKQUOTE: /* TILDE */
1494 {
1495 char *tmp = (char *) alloca (100);
1496 sprintf (tmp, "FRAME DELTA = %d",
1497 frame - HCD_frame_at_beginning_of_track);
1498 osd_gfx_set_message (tmp);
1499 message_delay = 240;
1500 break;
1501 }
1502
1503 case SDLK_3:
1504 if (key[SDLK_LSHIFT])
1505 {
1506 io.psg_channel_disabled[2] = !io.psg_channel_disabled[2];
1507 }
1508 else
1509 {
1510 //cd_port_1800 = 0xD0;
1511 io.cd_port_1800 &= ~0x40;
1512 }
1513 break;
1514
1515 case SDLK_4:
1516 if (key[SDLK_LSHIFT])
1517 {
1518 io.psg_channel_disabled[3] = !io.psg_channel_disabled[3];
1519 }
1520 /*
1521 else
1522 {
1523 Wr6502 (0x2066, Rd6502 (0x2066) | 32);
1524 }
1525 */
1526 break;
1527 case SDLK_5:
1528 if (key[SDLK_LSHIFT])
1529 {
1530 io.psg_channel_disabled[4] = !io.psg_channel_disabled[4];
1531 }
1532 else
1533 {
1534 io.cd_port_1800 = 0xD8;
1535 }
1536 break;
1537 case SDLK_6:
1538 if (key[SDLK_LSHIFT])
1539 {
1540 io.psg_channel_disabled[5] = !io.psg_channel_disabled[5];
1541 }
1542 /*
1543 else
1544 {
1545 Wr6502 (0x22D6, 1);
1546 }
1547 */
1548 break;
1549
1550 /*
1551 case SDLK_8:
1552 Wr6502 (0x20D8, 128);
1553 break;
1554 */
1555
1556 case SDLK_MINUS:
1557 {
1558 if (gen_vol)
1559 gen_vol--;
1560 if (sound_driver == 1)
1561
1562 {
1563 osd_snd_set_volume (gen_vol);
1564 sprintf (tmp_buf,
1565 MESSAGE[language][volume_set_to], gen_vol);
1566 osd_gfx_set_message (tmp_buf);
1567 message_delay = 60;
1568 }
1569
1570 break;
1571 }
1572 case SDLK_EQUALS:
1573 {
1574 if (gen_vol < 255)
1575 gen_vol++;
1576 if (sound_driver == 1)
1577
1578 {
1579 osd_snd_set_volume (gen_vol);
1580 sprintf (tmp_buf,
1581 MESSAGE[language][volume_set_to], gen_vol);
1582 osd_gfx_set_message (tmp_buf);
1583 message_delay = 60;
1584 }
1585
1586 break;
1587 }
1588
1589 default:
1590 /* ignore key */
1591 break;
1592 }
1593 break;
1594
1595 case SDL_QUIT:
1596 return 1;
1597 }
1598 }
1599
1600 //! Read events from joypad
1601 SDL_PumpEvents ();
1602
1603 #if defined(ENABLE_NETPLAY)
1604
1605 if (option.want_netplay)
1606 {
1607
1608 UChar local_input[5];
1609 int input_index;
1610
1611 for (input_index = 0; input_index < 5; input_index++)
1612 {
1613 local_input[input_index] = read_input (input_index);
1614 }
1615
1616 if (option.want_netplay == LAN_PROTOCOL)
1617 {
1618 wait_lan_digest_status (local_input);
1619 }
1620 else
1621 {
1622 /* option.want_netplay == INTERNET_PROTOCOL */
1623 wait_internet_digest_status (local_input);
1624 }
1625 return 0;
1626 }
1627
1628 #endif // ENABLE_NETPLAY
1629
1630 io.JOY[0] = read_input (0);
1631 io.JOY[1] = read_input (1);
1632 io.JOY[2] = read_input (2);
1633 io.JOY[3] = read_input (3);
1634 io.JOY[4] = read_input (4);
1635
1636 return 0;
1637 }
1638
1639
1640 int
osd_init_input(void)1641 osd_init_input (void)
1642 {
1643 if (SDL_InitSubSystem (SDL_INIT_JOYSTICK))
1644 {
1645 return -1;
1646 }
1647
1648 sdl_init_joypads ();
1649
1650 return 0;
1651 }
1652
1653 void
osd_shutdown_input()1654 osd_shutdown_input ()
1655 {
1656 }
1657
1658 #if defined(ENABLE_NETPLAY)
1659
1660 //! initialise netplay, returns 0 if ok
1661 int
osd_init_netplay()1662 osd_init_netplay()
1663 {
1664 if (option.want_netplay)
1665 {
1666 if (init_network () != 0)
1667 {
1668 return -1;
1669 }
1670 Log ("Netplay subsystem initialized\n");
1671
1672 /* TODO: Add configurable port number */
1673 /* TODO: Add support for ip address directly */
1674 if (SDLNet_ResolveHost
1675 (&server_address, option.server_hostname, DEFAULT_SERVER_PORT) != 0)
1676 {
1677 Log ("Couldn't resolve server address (%s)\n",
1678 option.server_hostname);
1679 return -1;
1680 }
1681
1682 /* Allocate client socket */
1683 client_socket = SDLNet_UDP_Open (0);
1684
1685 if (client_socket == NULL)
1686 {
1687 Log ("Couldn't open client socket\n");
1688 return -1;
1689 }
1690
1691 /* Allocate incoming packet storage */
1692 incoming_packet = SDLNet_AllocPacket (SERVER_PACKET_SIZE);
1693
1694 if (incoming_packet == NULL)
1695 {
1696 Log
1697 ("Couldn't allocate incoming packet storage (not enough memory ?)\n");
1698 SDLNet_UDP_Close (client_socket);
1699 return -1;
1700 }
1701
1702 /* Allocate outgoing packet storage */
1703 outgoing_packet = SDLNet_AllocPacket (CLIENT_PACKET_SIZE);
1704
1705 if (outgoing_packet == NULL)
1706 {
1707 Log
1708 ("Couldn't allocate outgoing packet storage (not enough memory ?)\n");
1709 SDLNet_UDP_Close (client_socket);
1710 SDLNet_FreePacket (incoming_packet);
1711 return -1;
1712 }
1713
1714 /* Allocate a single socket set */
1715 client_socket_set = SDLNet_AllocSocketSet (1);
1716
1717 if (client_socket_set == NULL)
1718 {
1719 Log
1720 ("Couldn't allocate socket set storage (not enough memory ?)\n");
1721 SDLNet_UDP_Close (client_socket);
1722 SDLNet_FreePacket (incoming_packet);
1723 SDLNet_FreePacket (outgoing_packet);
1724 return -1;
1725 }
1726
1727 /* Add the client socket to the set used to passively wait */
1728 if (SDLNet_UDP_AddSocket (client_socket_set, client_socket) != 1)
1729 {
1730 Log ("Error when adding socket to socket set.\n");
1731 SDLNet_UDP_Close (client_socket);
1732 SDLNet_FreePacket (incoming_packet);
1733 SDLNet_FreePacket (outgoing_packet);
1734 SDLNet_FreeSocketSet (client_socket_set);
1735 return -1;
1736 }
1737
1738 send_identification (option.local_input_mapping);
1739
1740 }
1741
1742 return 0;
1743
1744 }
1745
1746 void
osd_shutdown_netplay()1747 osd_shutdown_netplay()
1748 {
1749
1750 if (option.want_netplay)
1751 {
1752 SDLNet_UDP_Close (client_socket);
1753 SDLNet_FreePacket (incoming_packet);
1754 SDLNet_FreePacket (outgoing_packet);
1755 SDLNet_FreeSocketSet (client_socket_set);
1756 }
1757
1758 }
1759
1760
1761 #if defined(NETPLAY_DEBUG)
1762
1763 /*!
1764 * Print a string adding an accurate timestamp
1765 * \param format the printf style format string
1766 * \param ... the extra parameters for the printf
1767 */
1768 void
netplay_debug_printf(char * format,...)1769 netplay_debug_printf (char *format, ...)
1770 {
1771 FILE *log_file;
1772 char buf[256];
1773 char time_buffer[256];
1774 struct timeb time_structure;
1775
1776 va_list ap;
1777 va_start (ap, format);
1778 vsprintf (buf, format, ap);
1779 va_end (ap);
1780
1781 ftime (&time_structure);
1782
1783 #if !defined(WIN32)
1784 ctime_r (&time_structure.time, time_buffer);
1785 #endif
1786
1787 if (strlen (time_buffer) > 0)
1788 {
1789 /* If this buffer is not empty, remove the last character (which is normally a newline) */
1790 time_buffer[strlen (time_buffer) - 1] = 0;
1791 }
1792
1793 fprintf (stderr, "%s:%3u ", time_buffer, time_structure.millitm);
1794 fprintf (stderr, buf);
1795 fprintf (stderr, "\n");
1796
1797 fflush (stderr);
1798
1799 return;
1800 }
1801
1802 #endif
1803
1804 /*!
1805 * Read an incoming packet and stores it for future computations
1806 * \return non null if we could read a packet
1807 * \return 0 if we didn't read a packet (we then set the len to 0 to prevent matching)
1808 */
1809 int
read_incoming_client_packet()1810 read_incoming_client_packet ()
1811 {
1812 switch (SDLNet_UDP_Recv (client_socket, incoming_packet))
1813 {
1814 case 0:
1815 incoming_packet->len = 0;
1816 return 0;
1817 case 1:
1818 #if defined(NETPLAY_DEBUG)
1819 netplay_debug_printf ("Stored a packet from server.");
1820 #endif
1821 return 1;
1822 default:
1823 Log ("Internal warning: impossible case (%s:%s)\n", __FILE__, __LINE__);
1824 incoming_packet->len = 0;
1825 return 0;
1826 }
1827 return 0;
1828 }
1829
1830 /*!
1831 * Check validity of the identification acknowledge packet stored in 'incoming_packet' and extract
1832 * the number of allocated slots if the packet is valid
1833 * \return 0 in case of invalid packet reception
1834 * \return else, number of allocated slots
1835 */
1836 int
count_allocated_slots()1837 count_allocated_slots ()
1838 {
1839
1840 int allocated_slots;
1841
1842 if (incoming_packet->len != PACKET_IDENTIFICATION_ACKNOWLEDGE_LENGTH)
1843 {
1844 /* Discarding packet of invalid length */
1845 #if defined(NETPLAY_DEBUG)
1846 Log
1847 ("Invalid packet received when in identification acknowledge phase (received length: %d, expected length: %d)\n",
1848 incoming_packet->len, PACKET_IDENTIFICATION_ACKNOWLEDGE_LENGTH);
1849 #endif
1850 return 0;
1851 }
1852
1853 if (incoming_packet->data[PACKET_IDENTIFIER] !=
1854 PACKET_IDENTIFICATION_ACKNOWLEDGE_ID)
1855 {
1856 /* Discarding packet with invalid identifier */
1857 #if defined(NETPLAY_DEBUG)
1858 Log
1859 ("Invalid packet received when in identification acknowledge phase (received ID: 0x%02x, expected ID: 0x%02x)\n",
1860 incoming_packet->data[PACKET_IDENTIFIER],
1861 PACKET_IDENTIFICATION_ACKNOWLEDGE_ID);
1862 #endif
1863 return 0;
1864 }
1865
1866 /* TODO : Add checksum verification */
1867
1868 allocated_slots =
1869 incoming_packet->
1870 data[PACKET_IDENTIFICATION_ACKNOWLEDGE_NUMBER_ALLOCATED_SLOTS];
1871
1872 #if defined(NETPLAY_DEBUG)
1873 Log ("Received identification acknowledge with %d allocated slot(s)\n",
1874 allocated_slots);
1875 #endif
1876
1877 if ((allocated_slots < 1) || (allocated_slots > 5))
1878 {
1879 Log ("Invalid number of allocated slots : %d\n", allocated_slots);
1880 return 0;
1881 }
1882
1883 /* We're finished with the acknowledge packet, let's clear it */
1884 bzero (incoming_packet->data, SERVER_PACKET_SIZE);
1885
1886 return allocated_slots;
1887
1888 }
1889
1890 /*!
1891 * Wait for identification acknowledge packet or timeout
1892 * \return 0 in case of time out or invalid packet reception
1893 * \return non null in case of acknowledge packet reception with the number of allocated slots
1894 */
1895 int
wait_identification_acknowledge_packet()1896 wait_identification_acknowledge_packet ()
1897 {
1898
1899 int number_ready_socket;
1900
1901 #if defined(NETPLAY_DEBUG)
1902 Log ("Waiting for acknowledge packet\n");
1903 #endif
1904
1905 /* Wait for activity on the socket */
1906 number_ready_socket =
1907 SDLNet_CheckSockets (client_socket_set, CLIENT_SOCKET_TIMEOUT);
1908
1909 #if defined(NETPLAY_DEBUG)
1910 Log ("Finished waiting, number of socket ready = %d\n",
1911 number_ready_socket);
1912 #endif
1913
1914 switch (number_ready_socket)
1915 {
1916 case -1:
1917 Log ("Unknown error when waiting for activity on socket\n");
1918 return 0;
1919 case 0:
1920 /* No activity */
1921 break;
1922 case 1:
1923
1924 #if defined(NETPLAY_DEBUG)
1925 Log ("Grabbed a packet\n");
1926 #endif
1927
1928 /* A single socket is ready */
1929 if (read_incoming_client_packet ())
1930 {
1931 return count_allocated_slots ();
1932 }
1933 return 0;
1934 break;
1935 }
1936
1937 return 0;
1938 }
1939
1940 /*!
1941 * Send a single packet to warn the server of our need in terms of slots
1942 */
1943 void
send_identification_packet(UChar * local_input_mapping)1944 send_identification_packet (UChar * local_input_mapping)
1945 {
1946 UChar number_requested_slots;
1947 int input_index;
1948 int number_destination;
1949
1950 number_requested_slots = 0;
1951
1952 /* Set the server address */
1953 outgoing_packet->address = server_address;
1954
1955 /* Set the identifier */
1956 outgoing_packet->data[PACKET_IDENTIFIER] = PACKET_IDENTIFICATION_ID;
1957
1958 /* Computes the number of requested slots to fit our needs */
1959 for (input_index = 0; input_index < 5; input_index++)
1960 {
1961 if (local_input_mapping[input_index] != 0xFF)
1962 {
1963 number_requested_slots++;
1964 }
1965 }
1966
1967 Log ("Asking for %d slots to server\n", number_requested_slots);
1968
1969 /* Set the number of requested slots */
1970 outgoing_packet->data[PACKET_IDENTIFICATION_NUMBER_REQUESTED_SLOTS] =
1971 number_requested_slots;
1972
1973 /* Set the mapping to local input devices */
1974 for (input_index = 0;
1975 input_index < PACKET_IDENTIFICATION_INPUT_DEVICE_NUMBER; input_index++)
1976 {
1977 outgoing_packet->data[PACKET_IDENTIFICATION_INPUT_DEVICE_INDEX +
1978 input_index] = local_input_mapping[input_index];
1979 }
1980
1981 /* Set checksum value */
1982 outgoing_packet->data[PACKET_IDENTIFICATION_CHECKSUM] =
1983 compute_checksum (outgoing_packet->data, PACKET_IDENTIFIER,
1984 PACKET_IDENTIFICATION_CHECKSUM);
1985
1986 /* Set the length of the packet */
1987 outgoing_packet->len = PACKET_IDENTIFICATION_LENGTH;
1988
1989 number_destination = SDLNet_UDP_Send (client_socket, -1, outgoing_packet);
1990
1991 if (number_destination != 1)
1992 {
1993 Log ("Couldn't send the status packet to client\n");
1994 }
1995
1996 }
1997
1998 /*!
1999 * Ensures identification is done properly
2000 * \param local_input_mapping mapping between the remote (global) and local input
2001 */
2002 void
send_identification(UChar * local_input_mapping)2003 send_identification (UChar * local_input_mapping)
2004 {
2005 /* TODO : add checking for number of acknowledged slots against requested one */
2006 do
2007 {
2008 send_identification_packet (local_input_mapping);
2009 }
2010 while (wait_identification_acknowledge_packet () == 0);
2011 }
2012
2013 /*!
2014 * Send a packet for explaining what is the current local status
2015 */
2016 void
send_local_status(UChar * local_input)2017 send_local_status (UChar * local_input)
2018 {
2019 int input_index;
2020 int number_destination;
2021
2022 /* Set the server address */
2023 outgoing_packet->address = server_address;
2024
2025 /* Set the identifier */
2026 outgoing_packet->data[PACKET_IDENTIFIER] = PACKET_STATUS_ID;
2027
2028 /* Set the frame number request */
2029 SDLNet_Write32 (frame, outgoing_packet->data + PACKET_STATUS_FRAME_NUMBER);
2030
2031 /* Set the local input values */
2032 for (input_index = 0; input_index < PACKET_STATUS_INPUT_DEVICE_NUMBER;
2033 input_index++)
2034 {
2035 outgoing_packet->data[PACKET_STATUS_INPUT_DEVICE_INDEX + input_index] =
2036 local_input[input_index];
2037 }
2038
2039 /* Set checksum value */
2040 outgoing_packet->data[PACKET_STATUS_CHECKSUM] =
2041 compute_checksum (outgoing_packet->data, PACKET_IDENTIFIER,
2042 PACKET_STATUS_CHECKSUM);
2043
2044 /* Set the length of the packet */
2045 outgoing_packet->len = PACKET_STATUS_LENGTH;
2046
2047 number_destination = SDLNet_UDP_Send (client_socket, -1, outgoing_packet);
2048
2049 if (number_destination != 1)
2050 {
2051 #if defined(NETPLAY_DEBUG)
2052 netplay_debug_printf ("Couldn't send the status packet to server.");
2053 #endif
2054 Log ("Couldn't send the status packet to server\n");
2055 }
2056
2057 }
2058
2059 /*!
2060 * Grab the digest packet for the current frame. Update the value of io.JOY
2061 * \return 0 in case of invalid packet
2062 * \return non null if the packet has been correctly processed
2063 */
2064 int
handle_digest_packet()2065 handle_digest_packet ()
2066 {
2067
2068 int allocated_slots;
2069 int input_index;
2070
2071 if (incoming_packet->len != PACKET_STATUS_LENGTH)
2072 {
2073 /* Discarding packet of invalid length */
2074 #if defined(NETPLAY_DEBUG)
2075 Log
2076 ("Invalid packet received when in digest phase (received length: %d, expected length: %d)\n",
2077 incoming_packet->len, PACKET_STATUS_LENGTH);
2078 #endif
2079 return 0;
2080 }
2081
2082 if (incoming_packet->data[PACKET_IDENTIFIER] != PACKET_DIGEST_ID)
2083 {
2084 /* Discarding packet with invalid identifier */
2085 #if defined(NETPLAY_DEBUG)
2086 Log
2087 ("Invalid packet received when in digest phase (received ID: 0x%02x, expected ID: 0x%02x)\n",
2088 incoming_packet->data[PACKET_IDENTIFIER], PACKET_DIGEST_ID);
2089 #endif
2090 return 0;
2091 }
2092
2093 if (frame !=
2094 SDLNet_Read32 (incoming_packet->data + PACKET_STATUS_FRAME_NUMBER))
2095 {
2096 #if defined(NETPLAY_DEBUG)
2097 Log
2098 ("Packet for incorrect frame (received digest for frame : %d, expected : %d)\n",
2099 SDLNet_Read32 (incoming_packet->data + PACKET_STATUS_FRAME_NUMBER),
2100 frame);
2101 #endif
2102 return 0;
2103 }
2104
2105 /* Verify checksum */
2106 if (incoming_packet->data[PACKET_STATUS_CHECKSUM] !=
2107 compute_checksum (incoming_packet->data, PACKET_IDENTIFIER,
2108 PACKET_STATUS_CHECKSUM))
2109 {
2110 #if defined(NETPLAY_DEBUG)
2111 netplay_debug_printf
2112 ("Incorrect checksum in received packet (received checksum : %d, expected : %d)",
2113 incoming_packet->data[PACKET_STATUS_CHECKSUM],
2114 compute_checksum (incoming_packet->data, PACKET_IDENTIFIER,
2115 PACKET_STATUS_CHECKSUM));
2116 Log
2117 ("Incorrect checksum in received packet (received checksum : %d, expected : %d)\n",
2118 incoming_packet->data[PACKET_STATUS_CHECKSUM],
2119 compute_checksum (incoming_packet->data, PACKET_IDENTIFIER,
2120 PACKET_STATUS_CHECKSUM));
2121 #endif
2122 return 0;
2123 }
2124
2125 for (input_index = 0; input_index < PACKET_STATUS_INPUT_DEVICE_NUMBER;
2126 input_index++)
2127 {
2128 io.JOY[input_index] =
2129 incoming_packet->data[PACKET_STATUS_INPUT_DEVICE_INDEX + input_index];
2130 }
2131
2132 return 1;
2133
2134 }
2135
2136 /*!
2137 * Wait for digest packet or timeout
2138 * \return 0 in case of timeout or invalid packet
2139 * \return non null if correct packet was received
2140 */
2141 int
wait_digest_packet()2142 wait_digest_packet ()
2143 {
2144 int number_ready_socket;
2145
2146 #if defined(NETPLAY_DEBUG)
2147 netplay_debug_printf ("Waiting for digest packet.");
2148 #endif
2149
2150 /* Else, wait for activity on the socket */
2151 number_ready_socket =
2152 SDLNet_CheckSockets (client_socket_set, CLIENT_SOCKET_TIMEOUT);
2153
2154 #if defined(NETPLAY_DEBUG)
2155 netplay_debug_printf ("Finished waiting, number of socket ready = %d.",
2156 number_ready_socket);
2157 #endif
2158
2159 switch (number_ready_socket)
2160 {
2161 case -1:
2162 Log ("Unknown error when waiting for activity on socket\n");
2163 #if defined(NETPLAY_DEBUG)
2164 netplay_debug_printf
2165 ("ERROR: Unknown error while waiting for socket activity.");
2166 #endif
2167 return 0;
2168 case 0:
2169 /* No activity */
2170 return 0;
2171 case 1:
2172
2173 #if defined(NETPLAY_DEBUG)
2174 Log ("Grabbed a packet\n");
2175 netplay_debug_printf ("There's now a packet waiting to be processed.");
2176 #endif
2177
2178 /* A single socket is ready */
2179 if (read_incoming_client_packet ())
2180 {
2181 return handle_digest_packet ();
2182 }
2183
2184 #if defined(NETPLAY_DEBUG)
2185 netplay_debug_printf
2186 ("ERROR: A packet was said to be waiting while there's none.");
2187 #endif
2188
2189 return 0;
2190 break;
2191 }
2192
2193 #if defined(NETPLAY_DEBUG)
2194 netplay_debug_printf
2195 ("ERROR: After waiting more than one socket was ready !");
2196 #endif
2197
2198 return 0;
2199 }
2200
2201 /*!
2202 * Wait for the digest packet using the lan protocol.
2203 * Updates io.JOY
2204 */
2205 void
wait_lan_digest_status(UChar * local_input)2206 wait_lan_digest_status (UChar * local_input)
2207 {
2208
2209 #if defined(NETPLAY_DEBUG)
2210 netplay_debug_printf ("Entering loop for waiting digest for frame %d.",
2211 frame);
2212 #endif
2213
2214 do
2215 {
2216 #if defined(NETPLAY_DEBUG)
2217 netplay_debug_printf
2218 ("Going to send a local status / digest request packet.");
2219 #endif
2220 send_local_status (local_input);
2221 #if defined(NETPLAY_DEBUG)
2222 netplay_debug_printf ("Sent a local status / digest request packet.");
2223 #endif
2224 }
2225 while (wait_digest_packet () == 0);
2226 }
2227
2228 /*!
2229 * Send a packet to server by specifying the frame number. It allows to send a packet with ou without
2230 * a request in internet mode.
2231 * \param local_input the local input status
2232 * \param frame_number the frame number value in the packet
2233 */
2234 void
send_internet_local_status(UChar * local_input,UInt32 frame_number)2235 send_internet_local_status (UChar * local_input, UInt32 frame_number)
2236 {
2237 int input_index;
2238 int number_destination;
2239
2240 /* Set the server address */
2241 outgoing_packet->address = server_address;
2242
2243 /* Set the identifier */
2244 outgoing_packet->data[PACKET_IDENTIFIER] = PACKET_STATUS_ID;
2245
2246 /* Set the requested frame number */
2247 SDLNet_Write32 (frame_number,
2248 outgoing_packet->data + PACKET_STATUS_FRAME_NUMBER);
2249
2250 /* Set local input values */
2251 for (input_index = 0; input_index < PACKET_STATUS_INPUT_DEVICE_NUMBER;
2252 input_index++)
2253 {
2254 outgoing_packet->data[PACKET_STATUS_INPUT_DEVICE_INDEX + input_index] =
2255 local_input[input_index];
2256 }
2257
2258 /* Set checksum value */
2259 outgoing_packet->data[PACKET_STATUS_CHECKSUM] =
2260 compute_checksum (outgoing_packet->data, PACKET_IDENTIFIER,
2261 PACKET_STATUS_CHECKSUM);
2262
2263 /* Set the length of the packet */
2264 outgoing_packet->len = PACKET_STATUS_LENGTH;
2265
2266 number_destination = SDLNet_UDP_Send (client_socket, -1, outgoing_packet);
2267
2268 if (number_destination != 1)
2269 {
2270 #if defined(NETPLAY_DEBUG)
2271 netplay_debug_printf ("Couldn't send the status packet to client.");
2272 #endif
2273 Log ("Couldn't send the status packet to client\n");
2274 }
2275
2276 }
2277
2278 /*!
2279 * Lookup the digest for the current frame status. It then updates io.JOY if found.
2280 * \return non null value if io.JOY was updated thanks to the current incoming packet content
2281 * \return null else
2282 */
2283 int
search_digest_packet()2284 search_digest_packet ()
2285 {
2286 int number_digest;
2287 UInt32 start_frame_number;
2288
2289 /* Look up the number of digest available in the incoming packet */
2290 number_digest = incoming_packet->data[PACKET_INTERNET_DIGEST_NUMBER_DIGEST];
2291
2292 #if defined(NETPLAY_DEBUG)
2293 if (number_digest > PACKET_INTERNET_DIGEST_DIGEST_NUMBER)
2294 {
2295 Log ("Abnormal number of digest in the incoming packet (%d)\n",
2296 number_digest);
2297 }
2298
2299 #endif
2300
2301 start_frame_number =
2302 SDLNet_Read32 (incoming_packet->data +
2303 PACKET_INTERNET_DIGEST_FRAME_NUMBER);
2304
2305 #if defined(NETPLAY_DEBUG)
2306 netplay_debug_printf
2307 ("We're looking frame %d and we have frames %d-%d handy\n", frame,
2308 start_frame_number, start_frame_number + number_digest - 1);
2309 #endif
2310
2311 if ((frame >= start_frame_number)
2312 && (frame < start_frame_number + number_digest))
2313 {
2314 /* We found the frame info we need */
2315 memcpy (io.JOY,
2316 incoming_packet->data + PACKET_INTERNET_DIGEST_DIGEST_INDEX +
2317 DIGEST_SIZE * (frame - start_frame_number), DIGEST_SIZE);
2318
2319 return 1;
2320 }
2321
2322 return 0;
2323 }
2324
2325 /*!
2326 * Check that the packet is valid, the exploitation of result in it is done in the search_digest_packet procedure. The number of
2327 * digest value of this packet is nullified on error.
2328 */
2329 void
handle_internet_digest_packet()2330 handle_internet_digest_packet ()
2331 {
2332
2333 int number_digest;
2334
2335 #if defined(NETPLAY_DEBUG)
2336 Log ("Received a packet for handling (length : %d), content follows :\n",
2337 incoming_packet->len);
2338
2339 {
2340 int packet_index;
2341
2342 for (packet_index = 0; packet_index < incoming_packet->len;
2343 packet_index++)
2344 {
2345 Log ("%02X ", incoming_packet->data[packet_index]);
2346 }
2347
2348 Log ("\n");
2349
2350 }
2351 #endif
2352
2353 if ((incoming_packet->len % PACKET_INTERNET_DIGEST_INCREMENT_LENGTH !=
2354 PACKET_INTERNET_DIGEST_BASE_LENGTH %
2355 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH)
2356 && (incoming_packet->len >=
2357 PACKET_INTERNET_DIGEST_BASE_LENGTH +
2358 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH))
2359 {
2360 /* Discarding packet of invalid length */
2361 #if defined(NETPLAY_DEBUG)
2362 Log
2363 ("Invalid packet received when in internet digest phase (received length: %d)\n",
2364 incoming_packet->len);
2365 #endif
2366 incoming_packet->data[PACKET_INTERNET_DIGEST_NUMBER_DIGEST] = 0;
2367 return;
2368 }
2369
2370 if (incoming_packet->data[PACKET_IDENTIFIER] != PACKET_INTERNET_DIGEST_ID)
2371 {
2372 /* Discarding packet with invalid identifier */
2373 #if defined(NETPLAY_DEBUG)
2374 Log
2375 ("Invalid packet received when in internet digest phase (received ID: 0x%02x, expected ID: 0x%02x)\n",
2376 incoming_packet->data[PACKET_IDENTIFIER], PACKET_INTERNET_DIGEST_ID);
2377 #endif
2378 incoming_packet->data[PACKET_INTERNET_DIGEST_NUMBER_DIGEST] = 0;
2379 return;
2380 }
2381
2382 number_digest = incoming_packet->data[PACKET_INTERNET_DIGEST_NUMBER_DIGEST];
2383
2384 if (number_digest < 1)
2385 {
2386 #if defined(NETPLAY_DEBUG)
2387 Log
2388 ("Invalid packet received when in internet digest phase (received ID: 0x%02x, expected ID: 0x%02x)\n",
2389 incoming_packet->data[PACKET_IDENTIFIER], PACKET_INTERNET_DIGEST_ID);
2390 #endif
2391 incoming_packet->data[PACKET_INTERNET_DIGEST_NUMBER_DIGEST] = 0;
2392 return;
2393 }
2394
2395 /* TODO: maybe add a further check for the number of digest offered */
2396
2397 /* Verify checksum */
2398 if (incoming_packet->
2399 data[PACKET_INTERNET_DIGEST_BASE_LENGTH +
2400 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH * number_digest] !=
2401 compute_checksum (incoming_packet->data, PACKET_IDENTIFIER,
2402 PACKET_INTERNET_DIGEST_BASE_LENGTH +
2403 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH *
2404 number_digest))
2405 {
2406 #if defined(NETPLAY_DEBUG)
2407 netplay_debug_printf
2408 ("Incorrect checksum in received packet (received checksum : %d, expected : %d)",
2409 incoming_packet->data[PACKET_INTERNET_DIGEST_BASE_LENGTH +
2410 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH *
2411 number_digest],
2412 compute_checksum (incoming_packet->data, PACKET_IDENTIFIER,
2413 PACKET_INTERNET_DIGEST_BASE_LENGTH +
2414 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH *
2415 number_digest));
2416
2417 Log
2418 ("Incorrect checksum in received packet (received checksum : %d, expected : %d)\n",
2419 incoming_packet->data[PACKET_INTERNET_DIGEST_BASE_LENGTH +
2420 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH *
2421 number_digest],
2422 compute_checksum (incoming_packet->data, PACKET_IDENTIFIER,
2423 PACKET_INTERNET_DIGEST_BASE_LENGTH +
2424 PACKET_INTERNET_DIGEST_INCREMENT_LENGTH *
2425 number_digest));
2426
2427 #endif
2428 incoming_packet->data[PACKET_INTERNET_DIGEST_NUMBER_DIGEST] = 0;
2429 return;
2430 }
2431
2432 /* If we managed to get here, everything looks fine */
2433
2434 }
2435
2436 /*!
2437 * Removes all pending packets.
2438 */
2439 void
flush_waiting_packets()2440 flush_waiting_packets ()
2441 {
2442 /* TODO: a better implementation can be achieved with the vector reception stuff */
2443 while (SDLNet_UDP_Recv (client_socket, incoming_packet) !=
2444 0) /* Nothing on purpose */ ;
2445 }
2446
2447 /*!
2448 * Wait for an incoming packet or an internet protocol timeout
2449 */
2450 void
wait_internet_digest_packet()2451 wait_internet_digest_packet ()
2452 {
2453 int number_ready_socket;
2454
2455 #if defined(NETPLAY_DEBUG)
2456 netplay_debug_printf ("Waiting for digest packet for frame %d.", frame);
2457 #endif
2458
2459 /* Wait for activity on the socket */
2460 number_ready_socket =
2461 SDLNet_CheckSockets (client_socket_set, CLIENT_SOCKET_INTERNET_TIMEOUT);
2462
2463 #if defined(NETPLAY_DEBUG)
2464 netplay_debug_printf ("Finished waiting, number of socket ready = %d.",
2465 number_ready_socket);
2466 #endif
2467
2468 switch (number_ready_socket)
2469 {
2470 case -1:
2471 Log ("Unknown error when waiting for activity on socket\n");
2472 #if defined(NETPLAY_DEBUG)
2473 netplay_debug_printf
2474 ("ERROR: Unknown error while waiting for socket activity.");
2475 #endif
2476 return;
2477 case 0:
2478 /* No activity */
2479 return;
2480 case 1:
2481
2482 #if defined(NETPLAY_DEBUG)
2483 Log ("Grabbed a packet\n");
2484 netplay_debug_printf ("There's now a packet waiting to be processed.");
2485 #endif
2486
2487 /* A single socket is ready */
2488 if (read_incoming_client_packet ())
2489 {
2490 handle_internet_digest_packet ();
2491 /* We're not much interested in old packets, they only raise lag */
2492 /* TODO: check how sane I was when I wrote this */
2493 /* flush_waiting_packets(); */
2494 return;
2495 }
2496
2497 #if defined(NETPLAY_DEBUG)
2498 netplay_debug_printf
2499 ("ERROR: A packet was said to be waiting while there's none.");
2500 #endif
2501
2502 return;
2503 break;
2504 }
2505
2506 #if defined(NETPLAY_DEBUG)
2507 netplay_debug_printf
2508 ("ERROR: After waiting more than one socket was ready !");
2509 #endif
2510
2511 return;
2512
2513 }
2514
2515 /*!
2516 * Wait for the digest packet using the internet protocol.
2517 * Updates io.JOY
2518 */
2519 void
wait_internet_digest_status(UChar * local_input)2520 wait_internet_digest_status (UChar * local_input)
2521 {
2522
2523 #if defined(NETPLAY_DEBUG)
2524 netplay_debug_printf ("Going to send a pure local status packet.");
2525 #endif
2526
2527 send_internet_local_status (local_input, 0);
2528
2529 if (search_digest_packet () != 0)
2530 {
2531 /* The digest was found and io.JOY updated */
2532 #if defined(NETPLAY_DEBUG)
2533 netplay_debug_printf
2534 ("Found the digest info for frame %d in the previously stored packet",
2535 frame);
2536 #endif
2537 return;
2538 }
2539
2540 for (;;)
2541 {
2542 wait_internet_digest_packet ();
2543
2544 if (search_digest_packet () != 0)
2545 {
2546 /* The digest was found and io.JOY updated */
2547 #if defined(NETPLAY_DEBUG)
2548 netplay_debug_printf
2549 ("Found the digest info for frame %d in the freshly stored packet",
2550 frame);
2551 #endif
2552 return;
2553 }
2554
2555 #if defined(NETPLAY_DEBUG)
2556 netplay_debug_printf
2557 ("Going to send a local status / digest request packet for frame %d.",
2558 frame);
2559 #endif
2560 send_internet_local_status (local_input, frame);
2561
2562 }
2563 }
2564
2565 #endif // ENABLE_NETPLAY
2566
2567 #endif // if ALLEGRO elif SDL
2568