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