1 /***************************************************************************
2 
3   network.c
4 
5  ***************************************************************************/
6 
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #ifdef MAME_NET
12 
13 #include "network.h"
14 #include "osdepend.h"
15 #include "mame.h"
16 #include "common.h"   /* Machine struct       */
17 #include "driver.h"   /* GameDriver struct    */
18 
19 
20 /* Uncomment to turn on printf code */
21 /* #define NET_DEBUG */
22 
23 #ifdef NET_DEBUG
24 #include <ctype.h>
25 
26 #define dprintf(x) printf x;
27 #else
28 #define dprintf(x)
29 #endif
30 
31 /* private funcs */
32 static int _real_net_sync( int first, char type );
33 static void net_packet_type_to_string( char type, char packet_type_str[] );
34 
35 static int vercmp(char *str_a, char *str_b);
36 
37 /* private vars */
38 static char netversion[] = "Rev7.3 ()"; /* RevX.Y X = Protocol version, Y = Tweak/Bug fix revision */
39 static char *mameversion = build_version; /* from mame.h and version.c */
40 static int is_active = 0;   /* Set to true if the net has been initialized */
41 static int in_game = 0;     /* Set to true if we are in a game */
42 static int is_client = 1;
43 static int num_clients = 0;
44 
45 /*******************************************************************
46  external functions
47  *******************************************************************/
48 
net_init()49 int net_init()
50 {
51     dprintf(("net_init() called\n"))
52     in_game = 0;
53 	/* TODO: move is_client setting into os-dependent settings?
54 	         should os-independent stuff know about this at all?
55 	*/
56 	if ( ( is_client = osd_net_init() ) == NET_ERROR )
57     {
58         dprintf(("osd_net_init() - FAILED\n"))
59 		return 1;
60     }
61 
62 	is_active = 1; /* we're using network */
63 
64 	/* if we're the client we can do the version checking now
65 	   server checks in net_add_player
66 	*/
67 	if ( is_client )
68 	{
69 		if ( net_vers_check( 0 ) )
70         {
71             dprintf(("net_version_check() - FAILED\n"))
72 			return 1;
73         }
74 	}
75 
76     dprintf(("net_init() - SUCCESS\n"))
77 	/* made it this far, must be ok */
78 	return 0;
79 }
80 
81 
net_exit(char type)82 int net_exit( char type )
83 {
84      dprintf(("net_exit() called\n"))
85 
86 	/* guard to make sure we're still active */
87 	if (!is_active)
88 		return 0;
89 
90 	/* what kind of exit are we experiencing */
91 	switch ( type )
92 	{
93 		/* if we initiate we'll need to send */
94 		case NET_QUIT_QUIT:
95 		case NET_QUIT_ABRT:
96 			net_sync( type );
97 			break;
98 
99 		/* if its peer initiated we just handle it w/o sending */
100 		case NET_QUIT_OKAY:
101 			break;
102 	}
103 
104 	is_active = 0;
105     dprintf(("net_exit() returning osd_net_exit()\n"))
106 	return osd_net_exit();
107 }
108 
net_game_init()109 int net_game_init()
110 {
111     dprintf(("net_game_init() called\n"))
112     if (osd_net_game_init() != 0)
113     {
114         dprintf(("net_game_init - FAILED\n"))
115         return 1;
116     }
117 
118     /* we can do the game checking now */
119 	if ( is_client )
120 	{
121 		if ( net_game_check( 0 ) )
122         {
123             dprintf(("net_game_check - FAILED\n"))
124 			return 1;
125         }
126         dprintf(("net_game_check - SUCCESS\n"))
127 	}
128     else
129     {
130         int i;
131 
132         for (i = 0; i < num_clients; i++)
133         {
134 		    if ( net_game_check( i ) )
135             {
136                 dprintf(("net_game_init player (%d) - FAILED\n", i))
137 			    return 1;
138             }
139             dprintf(("net_game_init player (%d) - SUCCESS\n", i))
140         }
141     }
142     in_game = is_active = 1;
143     dprintf(("net_game_init() return\n"))
144     return 0;
145 }
146 
net_game_exit()147 int net_game_exit()
148 {
149     in_game = 0;
150     dprintf(("net_game_exit called - returning osd_net_game_exit()\n"))
151     return osd_net_game_exit();
152 }
153 
154 /*
155 	do consistency check of mame/netmame support and prompt user for input on failure
156 */
net_vers_check(int player)157 int net_vers_check( int player )
158 {
159 	char szVerSelf[NET_MAX_DATA];
160 	char szVerPeer[NET_MAX_DATA];
161 	char cAck = 1; /* assuming false */
162 
163 	/* setup app and network support version info */
164 	memset( szVerSelf, 0, sizeof(szVerSelf) ); /* zero out array first */
165 	strcpy( szVerSelf, build_version );
166 	strcpy( (szVerSelf+25), netversion );
167 
168     dprintf(("net_vers_check()\n"))
169 
170 	/* do comparisons */
171 	if ( is_client )
172 	{
173 		net_send( 0, NET_INIT_VERS, szVerSelf, NET_MAX_DATA );
174 		net_recv( 0, NET_INIT_VERS, &cAck, 1 );
175 	}
176 	else /* server */
177 	{
178 		/* Clients send to us and we check versions */
179 		net_recv( player, NET_INIT_VERS, szVerPeer, NET_MAX_DATA );
180 
181 		/* Check the app version */
182 		if ( vercmp( szVerSelf, szVerPeer ) != 0 )
183 		{
184 			printf("Client %d does not match MAME version"
185 					"\nServer:%s"
186 					"\nClient:%s\n"
187 					, player, szVerSelf, szVerPeer );
188 		}
189 
190 		/* Check the network version */
191 		else if ( vercmp( (szVerSelf+25), (szVerPeer+25) ) != 0 )
192 		{
193 			printf("Client %d does not match network support version"
194 					"\nServer:%s"
195 					"\nClient:%s"
196 					, player, (szVerSelf+25), (szVerPeer+25) );
197 			/* TODO:some sort of prompt for return value...??? */
198 		}
199 
200 		/* else we are successful */
201 		else
202 			cAck = 0;
203 
204 		/* let client know results of version check */
205 		net_send( player, NET_INIT_VERS, &cAck, 1 );
206 	}
207 
208     dprintf(("net_vers_check() - %s\n", (cAck) ? "FAILED" : "SUCCESS"))
209 
210 	return cAck;
211 }
212 
213 
214 /*
215    *** rjr *** Compare versions; ignore dates (in parentheses)
216    So recompiling doesn't bring the world to a screeching halt!
217 */
vercmp(char * str_a,char * str_b)218 static int vercmp(char *str_a, char *str_b)
219 {
220 	char string_a[NET_MAX_DATA];
221 	char string_b[NET_MAX_DATA];
222 
223 	char *p;
224 
225 	strcpy(string_a, str_a);
226 	strcpy(string_b, str_b);
227 
228 	if (p = strchr(string_a, '('))
229 		*p = '\0';
230 
231 	if (p = strchr(string_b, '('))
232 		*p = '\0';
233 
234 	dprintf(("vercmp(%s,%s)\n", string_a, string_b))
235 
236 	return strcmp(string_a, string_b);
237 }
238 
239 
240 #ifdef NET_DEBUG
241 /* Dump a packet in hex and ascii */
array_to_string(int len,char * array)242 char * array_to_string(int len, char *array)
243 {
244     static char str[500] = "";
245     char temp[50];
246     char *ptr = array;
247     int  i;
248 
249     for (i = 0; i < len; i++, ptr++)
250     {
251         if (i)
252             strcat(str,",");
253         sprintf(temp,"%02x,'%c'", *ptr & 0xFF, (isalnum(*ptr)) ? *ptr : '.');
254         strcat(str, temp);
255     }
256     return str;
257 }
258 
259 #endif
260 /*
261 	do consistency check of game/roms and prompt user for input on failure
262 */
net_game_check(int player)263 int net_game_check( int player )
264 {
265 	char szVerSelf[NET_MAX_DATA];
266 	char szVerPeer[NET_MAX_DATA];
267 	char cAck = 1; /* assuming false */
268 
269     dprintf(("net_game_check (%d) as %s, Game('%s')\n",
270         player, (is_client) ? "Client" : "Server", Machine->gamedrv->name))
271 	/* Setup rom version info */
272 	strcpy( szVerSelf, Machine->gamedrv->name );
273 	/* TODO: strcpy checksum info? */
274 
275 	/* do comparisons */
276 	if ( is_client )
277 	{
278 		net_send( 0, NET_INIT_GAME, szVerSelf, strlen(szVerSelf));
279 		net_recv( 0, NET_INIT_GAME, &cAck, 1 );
280 	}
281 	else /* server */
282 	{
283         /* Clients send to us and we check versions */
284         memset(szVerPeer, '\0', sizeof(szVerPeer));
285         net_recv( player, NET_INIT_GAME, szVerPeer, NET_MAX_DATA);
286 
287         dprintf(("Server NET_INIT_GAME: %s\n", array_to_string(8, szVerPeer)))
288 		if ( strcmp( (szVerSelf), (szVerPeer)) != 0 )
289 		{
290 			printf("Client %d does not match rom name"
291 					"\nServer:%s"
292 					"\nClient:%s"
293 					, player, (szVerSelf), (szVerPeer) );
294 		}
295 
296 		/* else we are successful */
297 		else
298 			cAck = 0;
299 
300 		/* let client know results of version check */
301 		net_send( player, NET_INIT_GAME, &cAck, 1 );
302 	}
303     dprintf(("net_game_check (%d) - %s\n", player, (cAck) ? "FAILED" : "SUCCESS"))
304 	return cAck;
305 }
306 
net_sync(char type)307 int net_sync( char type )
308 {
309     dprintf(("net_sync() called\n"))
310 	switch ( type )
311 	{
312 		case NET_SYNC_INIT:
313 		case NET_SYNC_REDO:
314 			return _real_net_sync( is_client, type );
315 			break;
316 
317 		case NET_QUIT_QUIT:
318 		case NET_QUIT_ABRT:
319 			/* we still sync first if we've decided to exit */
320 			return _real_net_sync( 1, type );
321 			break;
322 
323 		default:
324 			printf("net_sync: asked to sync a type we don't recognize at this point\n");
325 	}
326 	return 1; /* error shouldn't reach this far */
327 }
328 
_real_net_sync(int first,char type)329 static int _real_net_sync( int first, char type )
330 {
331 	static NET_BYTE szMsg[] = "PeterAndMichael";
332 	static int size = 16;
333 
334     dprintf(("_real_net_sync() called as %d - first is %s\n",
335         (is_client) ? "Client" : "Server",
336         (first)     ? "TRUE"   : "FALSE"))
337 
338 	if ( is_client )
339 	{
340 		if ( first )
341 		{
342 			net_send( 0, type, szMsg, size );
343 			net_recv( 0, type, szMsg, NET_MAX_DATA );
344 		}
345 		else
346 		{
347 			net_recv( 0, type, szMsg, NET_MAX_DATA );
348 			net_send( 0, type, szMsg, size );
349 		}
350 	}
351 
352 	else
353 	{
354 		int i;
355 		if ( first )
356 		{
357 			for ( i=0; i < num_clients; i++)
358 			{
359 				net_send( 0, type, szMsg, size );
360 				net_recv( 0, type, szMsg, NET_MAX_DATA );
361 			}
362 		}
363 		else
364 		{
365 			for ( i=0; i < num_clients; i++)
366 			{
367 				net_recv( 0, type, szMsg, NET_MAX_DATA );
368 				net_send( 0, type, szMsg, size );
369 			}
370 		}
371 	}
372 
373 	/*  error checking? */
374     dprintf(("_real_net_sync() called\n"))
375 	return 0;
376 }
377 
net_analog_sync(unsigned char input_port_value[],int port,int analog_player_port[],int default_player)378 int net_analog_sync(unsigned char input_port_value[], int port,
379 					int analog_player_port[], int default_player)
380 {
381 	unsigned char junk[MAX_INPUT_PORTS]; /* used just for synchronizing - values don't matter */
382 
383     dprintf(("net_analog_sync() called\n"))
384 	if ( is_client )
385 	{
386 		if ( analog_player_port[port] == default_player ) /* we control this port */
387 		{
388 			/* we tell the server our input */
389 			net_send( 0, NET_SYNC_ANLG, &input_port_value[port], 1 );
390 			net_recv( 0, NET_SYNC_ANLG, &junk[port], 1 );
391 		}
392 		else
393 		{
394 			/* we receive the correct input from the server */
395 			net_send( 0, NET_SYNC_ANLG, &junk[port], 1 );
396 			net_recv( 0, NET_SYNC_ANLG, &input_port_value[port], 1 );
397 		}
398 	}
399 	else
400 	{
401 		if ( analog_player_port[port] == default_player ) /* we control this port */
402 		{
403 			/* we tell the client our input */
404 			net_recv( 0, NET_SYNC_ANLG, &junk[port], 1 );
405 			net_send( 0, NET_SYNC_ANLG, &input_port_value[port], 1 );
406 		}
407 		else
408 		{
409 			/* we receive the correct input from the client */
410 			net_recv( 0, NET_SYNC_ANLG, &input_port_value[port], 1 );
411 			net_send( 0, NET_SYNC_ANLG, &junk[port], 1 );
412 		}
413 	}
414     dprintf(("net_analog_sync() return\n"))
415 
416 	return 0;
417 }
418 
419 
net_input_sync(unsigned char input_port_value[],unsigned char input_port_default[],int num_ports)420 int net_input_sync( unsigned char input_port_value[], unsigned char input_port_default[], int num_ports )
421 {
422 	int port;
423 
424     dprintf(("net_input_sync() called\n"))
425 	if ( is_client )
426 	{
427 		/* mark default bits */
428 		for(port=0; port < num_ports; port++)
429 			input_port_value[port] ^= input_port_default[port];
430 
431 		/* send our changes to server for merging */
432 		net_send( 0, NET_SYNC_INPT, input_port_value, num_ports );
433 
434 		/* receive final merged input from server */
435 		net_recv( 0, NET_SYNC_INPT, input_port_value, num_ports );
436 	}
437 
438 	else /* server */
439 	{
440 		int client;
441 		static unsigned char changed_input_port_value[MAX_INPUT_PORTS];
442 		static unsigned char old_input_port_value[MAX_INPUT_PORTS]; /* used by server in case network dies */
443 
444 		/* save values incase network dies */
445 		memcpy(old_input_port_value, input_port_value, num_ports);
446 
447 		/* receive input from client and merge */
448 		for (client=0; client < num_clients; client++)
449 		{
450 			/* mark default bits */
451 			for(port=0; port < num_ports; port++)
452 				input_port_value[port] ^= input_port_default[port];
453 
454 			net_recv( client, NET_SYNC_INPT, changed_input_port_value, num_ports );
455 
456     		for( port=0; port < num_ports; port++ )
457 			{
458 				/* merge this clients changes */
459 				input_port_value[port] |= changed_input_port_value[port]; /* or local and remote changes */
460 				input_port_value[port] ^= input_port_default[port];       /* toggle changed bits */
461 			}
462 		}
463 
464 		/* now check if clients still exist */
465 		if ( is_active )
466 		{
467 			for (client=0; client < num_clients; client++)  /* send final input to client */
468 				net_send( client, NET_SYNC_INPT, input_port_value, num_ports );
469 		}
470 		else /* net connection is now down, restore our values */
471 		{
472 			memcpy(input_port_value, old_input_port_value, num_ports);
473 		}
474 	}
475     dprintf(("net_input_sync() return\n"))
476 
477 /* TODO: error checking */
478 	return 0;
479 }
480 
481 /* format packet and pass to os-specific sender */
net_send(int player,char type,unsigned char * msg,int size)482 int net_send( int player, char type, unsigned char *msg, int size )
483 {
484 	/* format packet */
485 	static unsigned char buf[NET_MAX_PACKET];
486 	int new_size = size + NET_MAX_HEADER;
487 	int error = 0;
488 #ifdef NET_DEBUG
489 	char packet_str[14];
490 	net_packet_type_to_string( type, packet_str );
491     if (type == NET_INIT_GAME && size > 1)
492     {
493         dprintf(("net_send: %s data(%s), len(%d)\n", packet_str, msg, size))
494     }
495     else
496         dprintf(("net_send: %s, size(%d)\n", packet_str, size ))
497 #endif
498 	memset( buf, '\0', NET_MAX_PACKET ); /* clear full buffer */
499 	memcpy( buf, &type, NET_MAX_HEAD_TYPE );
500 	memcpy( (buf + NET_MAX_HEAD_TYPE), &size, NET_MAX_HEAD_SIZE );
501 	memcpy( (buf + NET_MAX_HEADER), msg, size );
502 
503 	error = osd_net_send( player, buf, &new_size );
504 
505 	if ( new_size != size + (int)NET_MAX_HEADER )
506 	{
507 		printf( "net_send: detected error while attempting to send\n" );
508 		printf( "net_send:   newsize:%d size+header:%d\n",new_size,size+NET_MAX_HEADER );
509 		error = 1;
510 	}
511 
512 	return error;
513 }
514 
515 /* receive from os-specific sender and check packet format */
net_recv(int player,char type,unsigned char * msg,int size)516 int net_recv( int player, char type, unsigned char *msg, int size )
517 {
518 	/* decode packet and check against expected*/
519 	static unsigned char buf[NET_MAX_PACKET];
520 	int error;
521 	char new_type;
522 	int new_size;
523 
524 	/* clear buffer before receiving */
525 net_recv_again:
526 	error = 0;
527 	new_type = 0;
528 	new_size = size + NET_MAX_HEADER;
529 	memset( buf, 0, NET_MAX_PACKET );
530 	error = osd_net_recv( player, buf, &new_size );
531 
532 #ifdef NET_DEBUG
533     {
534         char packet_str[14];
535 	    net_packet_type_to_string( type, packet_str );
536         dprintf(("net_recv: %s, size(%d)\n", packet_str, new_size ))
537     }
538 #endif
539 
540     memcpy( &new_type, buf, NET_MAX_HEAD_TYPE );
541 
542 	/* also check packet type to see that we got what we wanted*/
543 	if ( new_type != type )
544 	{
545 		/* if we initiated a quit, we don't care about what we received */
546 		/* TODO: check type against a mask to see if we care instead of long if block... */
547 		if ( ( type == NET_QUIT_QUIT ) || ( type == NET_QUIT_ABRT ) || ( type == NET_QUIT_OKAY ) )
548 		{
549 			return 0; /* leave buffer alone */
550 		}
551 
552 		/* error condition, see if we can handle new_type and recover */
553 		error = 1;
554 		switch ( new_type )
555 		{
556 			/* check for reset */
557 			case NET_SYNC_INIT:
558 			case NET_SYNC_REDO:
559 				/* TODO: reset */
560 				return 0;
561 
562 			/* check for pause */
563 			case NET_SYNC_PAWS:
564 				/* TODO: wait for another paws */
565 				goto net_recv_again;
566 
567 			/* quit conditions */
568 			case NET_QUIT_QUIT:
569 			case NET_QUIT_ABRT:
570 			case NET_QUIT_OKAY:
571 				printf( "we've detected a quit or abort\n" );
572 				/* leave buffer alone - do not use merged buffer*/
573 				return net_remove_player( player );
574 
575 			/* this should never happen - but does */
576 			/*TODO: handle this instead of dropping player */
577 			case NET_0NOT_USED:
578 				printf( "bad data received - aborting player\n" );
579                 {
580                     char expected_packet_str[14];
581 		    		char received_packet_str[14];
582 	    			net_packet_type_to_string( type, expected_packet_str );
583     				net_packet_type_to_string( new_type, received_packet_str );
584                     dprintf(("net_recv: received packet:%s not expected:%s\n", received_packet_str, expected_packet_str ))
585                 }
586 				/* leave buffer alone - do not use merged buffer*/
587 				return net_remove_player( player );
588 
589 			default:
590 			{
591 				char expected_packet_str[14];
592 				char received_packet_str[14];
593 				net_packet_type_to_string( type, expected_packet_str );
594 				net_packet_type_to_string( new_type, received_packet_str );
595                 printf( "net_recv: received packet:%s not expected:%s\n", received_packet_str, expected_packet_str );
596 				/* leave buffer alone - do not use merged buffer*/
597 				return error;
598 			}
599 		}
600 	}
601 
602 	/* copy received buffer back into expected location */
603 	memcpy( msg, (buf+NET_MAX_HEADER), (new_size-NET_MAX_HEADER) );
604 
605 	return error;
606 
607 }
608 
net_add_player()609 int net_add_player()
610 {
611     dprintf(("net_add_player()\n"))
612 	/* TODO: make this also work for client for consistency */
613 
614 	/* check if osd adding a client failed */
615 	if ( ( num_clients = osd_net_add_player() ) < 0 )
616     {
617         dprintf(("osd_net_add_player() - FAILED\n"))
618 		return -1;
619     }
620 
621 	/* if it succeeded then we check the version */
622 	if ( net_vers_check( num_clients-1 ) )
623     {
624         dprintf(("net_vers_check() - FAILED\n"))
625 		return -1;
626     }
627 
628 	/* TODO: need to shift player info around (currently just sockets - eventually input assignments too ) */
629 	/* TODO: setup player names and such */
630     dprintf(("net_add_player() num_clients = %d\n", num_clients))
631 	return num_clients; /* we return the new total number of clients */
632 }
633 
net_remove_player(int player)634 int net_remove_player( int player )
635 {
636     dprintf(("net_remove_player(%d)\n", player ))
637 
638 	/* TODO: need to shift player info around (currently just sockets - eventually input assignments too ) */
639 	if ( is_client )
640 	{
641 		net_exit( NET_QUIT_OKAY );
642 		return 0;
643 	}
644 	else
645 	{
646 		int new_players = osd_net_remove_player( player );
647 		/* TODO: need to allow server to remain active */
648 		if ( new_players == 0 )
649 			net_exit( NET_QUIT_OKAY );
650 
651 		return new_players;
652 	}
653 }
654 
655 /* Only returns true if the net is initialized and we are playing a game */
net_active()656 int net_active()
657 {
658 #ifdef NET_DEBUG
659     static int last = 0;
660     static int iactive = 0;
661     static int igame = 0;
662 
663     if (iactive != is_active || igame != in_game)
664     {
665         iactive = is_active;
666         igame   = in_game;
667         last = (iactive && igame);
668         dprintf(("net_active() = %s is_active = %s, in_game = %s\n",
669             (last)    ? "TRUE" : "FALSE",
670             (iactive) ? "TRUE" : "FALSE",
671             (igame)   ? "TRUE" : "FALSE"))
672     }
673 #endif
674 	return (is_active && in_game);
675 }
676 
net_packet_type_to_string(char type,char packet_type_str[])677 static void net_packet_type_to_string( char type, char packet_type_str[] )
678 {
679 	switch ( type )
680 	{
681 		case NET_INIT_INIT:
682 			strcpy( packet_type_str, "NET_INIT_INIT" );
683 			break;
684 		case NET_INIT_VERS:
685 			strcpy( packet_type_str, "NET_INIT_VERS" );
686 			break;
687 		case NET_INIT_GAME:
688 			strcpy( packet_type_str, "NET_INIT_GAME" );
689 			break;
690 		case NET_SYNC_INIT:
691 			strcpy( packet_type_str, "NET_SYNC_INIT" );
692 			break;
693 		case NET_SYNC_INPT:
694 			strcpy( packet_type_str, "NET_SYNC_INPT" );
695 			break;
696 		case NET_SYNC_ANLG:
697 			strcpy( packet_type_str, "NET_SYNC_ANLG" );
698 			break;
699 		case NET_SYNC_USER:
700 			strcpy( packet_type_str, "NET_SYNC_USER" );
701 			break;
702 		case NET_SYNC_BOOM:
703 			strcpy( packet_type_str, "NET_SYNC_BOOM" );
704 			break;
705 		case NET_SYNC_REDO:
706 			strcpy( packet_type_str, "NET_SYNC_REDO" );
707 			break;
708 		case NET_QUIT_QUIT:
709 			strcpy( packet_type_str, "NET_QUIT_QUIT" );
710 			break;
711 		case NET_QUIT_ABRT:
712 			strcpy( packet_type_str, "NET_QUIT_ABRT" );
713 			break;
714 		case NET_QUIT_OKAY:
715 			strcpy( packet_type_str, "NET_QUIT_OKAY" );
716 			break;
717 		case NET_CHAT_INIT:
718 			strcpy( packet_type_str, "NET_CHAT_INIT" );
719 			break;
720 		case NET_CHAT_CHAT:
721 			strcpy( packet_type_str, "NET_CHAT_CHAT" );
722 			break;
723 		case NET_CHAT_QUIT:
724 			strcpy( packet_type_str, "NET_CHAT_QUIT" );
725 			break;
726 		case NET_0NOT_USED:
727 			strcpy( packet_type_str, "NET_0NOT_USED" );
728 			break;
729 		default:
730 			strcpy( packet_type_str, "UNRECOGNIZED!" );
731 			break;
732 	}
733 }
734 
net_chat_send(unsigned char * msg,int * size)735 int net_chat_send( unsigned char *msg, int *size )
736 {
737 	net_send( 0, NET_CHAT_CHAT, msg, *size );
738 	return 0;
739 }
740 
net_chat_recv(int player,unsigned char * msg,int * size)741 int net_chat_recv(int player, unsigned char *msg, int *size )
742 {
743 	net_recv( player, NET_CHAT_CHAT, msg, *size );
744 	return 0;
745 }
746 
747 #endif /* MAME_NET */
748