|
发表于 2004-11-13 00:25:35
|
显示全部楼层
意思是不能网络对战了??
那个0.87-0.88.diff
是用来干什么的??
是不是网络补丁啊,,怎么用?
我在邮件列表看老美说了一大阵子怎么支持网络。最后是一大块代码。。。
看得一头雾水。。。郁闷。
原文如下,供大虾参考:
xmame
<-- Chronological -->
Find
<-- Thread -->
[Xmame] mamenet lives! sorta
From: Steve Freeland
Subject: [Xmame] mamenet lives! sorta
Date: Fri, 07 Dec 2001 16:04:43 -0800
Here is a very preliminary patch against xmame 0.56.1 to enable
network multiplayer. Only the basics are implemented (see TODO in
doc/multiplayer-readme.txt) but it should be enough to play most games on a
LAN. I doubt you'd have much luck over the internet, and playing over
anything slower than a cable modem is definitely not going to be pleasant.
Still, it's a start. I would've given it some more work but I'm
sending it in now in case some of you want to play around with it over the
weekend -- I probably won't get back to it before Monday.
Enjoy, and good luck...
--
Steve 'Nephtes' Freeland | For Christmas this year I'd like to see Martha
[EMAIL PROTECTED] | Stewart compete on an episode of Junkyard Wars.
diff -cr xmame-0.56.1/doc/multiplayer-readme.txt
xmame-0.56.1-net/doc/multiplayer-readme.txt
*** xmame-0.56.1/doc/multiplayer-readme.txt Fri Nov 2 20:22:54 2001
--- xmame-0.56.1-net/doc/multiplayer-readme.txt Fri Dec 7 14:07:35 2001
***************
*** 1,3 ****
--- 1,90 ----
+ Multiplayer Network XMame N0.1 (Rewrite by Steve Freeland,
[EMAIL PROTECTED])
+ ------------------------------
+ mame version 0.56.1
+
+ Usage (for an n-player game):
+ -----
+ Start a master:
+ xmame.<display method> -master n <other options> <game name>
+ Start n - 1 slaves:
+ xmame.<display method> -slave <master hostname> <other options> <game name>
+ Currently there can only be one slave per machine, although a slave
+ can share a machine with the master.
+
+ Message format
+ --------------
+ Each UDP packet has a 4-byte header followed by a body.
+ The header has a 3-byte magic string "XNM" followed by a 1-byte message type.
+ The contents of the message body depends on the message type, and there may in fact
+ not be a body.
+
+ Message types: See enum net_msg_type in src/unix/network.c in case
+ ------------- this doc is out of date
+ JOIN: This is the first message the slaves send to the master for
+ handshaking. The body contains a string identifying the slave
+ (<hostname>/<pid>), the slave's MAME build version and net protocol
+ version, and the name of the game being played. If any of the latter
+ 3 do not match the master's information, the master will refuse the
+ join. The slave id string is currently only used for logging.
+
+ ACCEPT: This is the master's reply to the slave if the protocol
+ versions and game name match. The 1-byte body is the player number
+ assigned to the slave.
+
+ REFUSE: This is the master's reply to the slave if the protocol
+ versions and game name do not match. There is no body.
+
+ LOCAL_STATE: This message is sent by the slave to the master and
+ contains a sequence number (see Protocol below) and a byte
+ order-adjusted copy of the slave's current input_port_values[] array.
+ It is used by the master to compute the global state.
+
+ GLOBAL_STATE: Sent by the master to each of the slaves and contains,
+ like LOCAL_STATE, a sequence number and a byte order-adjusted copy of the
+ input_port_values[] array. The slave uses this to overwrite its own
+ local copy of input_port_values[].
+
+ QUIT: Sent when a client or the master exits and allows the remaining
+ participants to handle the exit gracefully without having wait for a timeout.
+
+ Protocol
+ --------
+ For frame n:
+ . Slaves all send input state for frame sequence number n to master.
+ . Master waits indefinitely for all slave inputs for frame n to
+ arrive.
+ . If the master receives a slave input for frame n - 1, that
+ slave may not have received the global state for frame n - 1
+ and the master must resend it.
+ . If the master receives a slave input for frame < n - 1, that
+ can only be due to out-of-order delivery (I think) and it
+ can be ignored.
+ . Master eventually receives all slave input state, merges them and
+ sends the global state back to slaves, then processes (eg,
+ proceeds with emulation until the next frame) the merged
+ input and goes back to waiting for local inputs for frame n + 1.
+ . Slaves wait a certain amount of time for the global input state
+ from the master.
+ . If the wait times out then the local input state for frame n
+ is resent.
+ . Slave may receive an old response (frame < n) due to out-of-
+ order delivery, which it ignores. If frame is n - 1 is
+ received that could be due to a premature resend.
+ . Slaves eventually all get the global state for frame n, then
+ process the merged input and proceed to the next frame.
+ . Lather, rinse, repeat.
+
+ TODO
+ ----
+ . Handle user interface invocation?
+ . More flexible port config?
+ . Adjust for high latency -- coarser sync frequency?
+ . Player n to player 1 input port remapping
+ . Talk to the core team about integrating the protocol-level stuff
+ into the platform-independant network.c
+
+ Old readme:
+ -----------
Multiplayer Network XMame 0.02
------------------------------
mame version 0.34b5
diff -cr xmame-0.56.1/src/driver.h xmame-0.56.1-net/src/driver.h
*** xmame-0.56.1/src/driver.h Fri Nov 2 20:22:51 2001
--- xmame-0.56.1-net/src/driver.h Wed Dec 5 19:56:42 2001
***************
*** 19,28 ****
#include "tilemap.h"
#include "profiler.h"
- #ifdef MAME_NET
- #include "network.h"
- #endif /* MAME_NET */
-
#define MAX_CPU 8 /* MAX_CPU is the maximum number of CPUs which cpuintrf.c */
/* can run at the same time. Currently, 8 is
enough. */
--- 19,24 ----
diff -cr xmame-0.56.1/src/inptport.c xmame-0.56.1-net/src/inptport.c
*** xmame-0.56.1/src/inptport.c Fri Nov 2 20:22:53 2001
--- xmame-0.56.1-net/src/inptport.c Wed Dec 5 21:17:56 2001
***************
*** 595,601 ****
int load_input_port_settings(void)
{
void *f;
! #ifdef MAME_NET
struct InputPort *in;
int port, player;
#endif /* MAME_NET */
--- 595,601 ----
int load_input_port_settings(void)
{
void *f;
! #ifdef OLD_MAME_NET
struct InputPort *in;
int port, player;
#endif /* MAME_NET */
***************
*** 605,611 ****
if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,0)) != 0)
{
! #ifndef MAME_NET
struct InputPort *in;
#endif
unsigned int total,savedtotal;
--- 605,611 ----
if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,0)) != 0)
{
! #ifndef OLD_MAME_NET
struct InputPort *in;
#endif
unsigned int total,savedtotal;
***************
*** 697,703 ****
for (i = 0; i < MAX_INPUT_PORTS; i++)
input_analog_init = 1;
}
! #ifdef MAME_NET
/* Find out what port is used by what player and swap regular inputs */
in = Machine->input_ports;
--- 697,703 ----
for (i = 0; i < MAX_INPUT_PORTS; i++)
input_analog_init = 1;
}
! #ifdef OLD_MAME_NET
/* Find out what port is used by what player and swap regular inputs */
in = Machine->input_ports;
***************
*** 813,819 ****
/* TODO: at this point the games should initialize peers to same as server */
! #endif /* MAME_NET */
update_input_ports();
--- 813,819 ----
/* TODO: at this point the games should initialize peers to same as server */
! #endif /* OLD_MAME_NET */
update_input_ports();
***************
*** 829,835 ****
void save_input_port_settings(void)
{
void *f;
! #ifdef MAME_NET
struct InputPort *in;
int port, player;
--- 829,835 ----
void save_input_port_settings(void)
{
void *f;
! #ifdef OLD_MAME_NET
struct InputPort *in;
int port, player;
***************
*** 946,960 ****
port++;
if (in->type == IPT_PORT) in++;
}
! #endif /* MAME_NET */
save_default_keys();
if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,1)) != 0)
{
! #ifndef MAME_NET
struct InputPort *in;
! #endif /* MAME_NET */
int total;
int i;
--- 946,960 ----
port++;
if (in->type == IPT_PORT) in++;
}
! #endif /* OLD_MAME_NET */
save_default_keys();
if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,1)) != 0)
{
! #ifndef OLD_MAME_NET
struct InputPort *in;
! #endif /* OLD_MAME_NET */
int total;
int i;
***************
*** 1305,1314 ****
readword(playback,&input_port_value[port]);
if (record)
writeword(record,input_port_value[port]);
! #ifdef MAME_NET
if ( net_active() && (default_player != NET_SPECTATOR) )
net_analog_sync((unsigned char *) input_port_value, port,
analog_player_port, default_player);
! #endif /* MAME_NET */
profiler_mark(PROFILER_END);
}
--- 1305,1314 ----
readword(playback,&input_port_value[port]);
if (record)
writeword(record,input_port_value[port]);
! #ifdef OLD_MAME_NET
if ( net_active() && (default_player != NET_SPECTATOR) )
net_analog_sync((unsigned char *) input_port_value, port,
analog_player_port, default_player);
! #endif /* OLD_MAME_NET */
profiler_mark(PROFILER_END);
}
***************
*** 1330,1338 ****
int joystick[MAX_JOYSTICKS*MAX_PLAYERS][4];
#endif
! #ifdef MAME_NET
int player;
! #endif /* MAME_NET */
profiler_mark(PROFILER_INPUT);
--- 1330,1338 ----
int joystick[MAX_JOYSTICKS*MAX_PLAYERS][4];
#endif
! #ifdef OLD_MAME_NET
int player;
! #endif /* OLD_MAME_NET */
profiler_mark(PROFILER_INPUT);
***************
*** 1438,1444 ****
input_port_value[port] =
(input_port_value[port] & ~in->mask) |
(in->default_value & in->mask);
#ifdef MAME_NET
! if ( net_active() )
input_port_defaults[port] =
input_port_value[port];
#endif /* MAME_NET */
}
--- 1438,1444 ----
input_port_value[port] =
(input_port_value[port] & ~in->mask) |
(in->default_value & in->mask);
#ifdef MAME_NET
! if ( osd_net_active() )
input_port_defaults[port] =
input_port_value[port];
#endif /* MAME_NET */
}
***************
*** 1451,1462 ****
in->type != IPT_END && in->type != IPT_PORT;
in++, ib++)
{
! #ifdef MAME_NET
player = 0;
if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player =
2;
else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player =
3;
! #endif /* MAME_NET */
if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING && /*
skip dipswitch definitions */
(in->type & ~IPF_MASK) != IPT_EXTENSION)
/* skip analog extension fields */
{
--- 1451,1462 ----
in->type != IPT_END && in->type != IPT_PORT;
in++, ib++)
{
! #ifdef OLD_MAME_NET
player = 0;
if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player =
2;
else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player =
3;
! #endif /* OLD_MAME_NET */
if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING && /*
skip dipswitch definitions */
(in->type & ~IPF_MASK) != IPT_EXTENSION)
/* skip analog extension fields */
{
***************
*** 1519,1525 ****
else if ((in->type & ~IPF_MASK) >=
IPT_JOYSTICK_UP &&
(in->type & ~IPF_MASK)
<= IPT_JOYSTICKLEFT_RIGHT)
{
! #ifndef MAME_NET
int joynum,joydir,mask,player;
--- 1519,1525 ----
else if ((in->type & ~IPF_MASK) >=
IPT_JOYSTICK_UP &&
(in->type & ~IPF_MASK)
<= IPT_JOYSTICKLEFT_RIGHT)
{
! #ifndef OLD_MAME_NET
int joynum,joydir,mask,player;
***************
*** 1529,1535 ****
else if ((in->type &
IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
#else
int joynum,joydir,mask;
! #endif /* !MAME_NET */
joynum = player *
MAX_JOYSTICKS +
((in->type &
~IPF_MASK) - IPT_JOYSTICK_UP) / 4;
joydir = ((in->type &
~IPF_MASK) - IPT_JOYSTICK_UP) % 4;
--- 1529,1535 ----
else if ((in->type &
IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
#else
int joynum,joydir,mask;
! #endif /* ! OLD_MAME_NET */
joynum = player *
MAX_JOYSTICKS +
((in->type &
~IPF_MASK) - IPT_JOYSTICK_UP) / 4;
joydir = ((in->type &
~IPF_MASK) - IPT_JOYSTICK_UP) % 4;
***************
*** 1648,1655 ****
writeword(record,input_port_value);
}
#ifdef MAME_NET
! if ( net_active() && (default_player != NET_SPECTATOR) )
! net_input_sync((unsigned char *) input_port_value, (unsigned char *)
input_port_defaults, MAX_INPUT_PORTS);
#endif /* MAME_NET */
profiler_mark(PROFILER_END);
--- 1648,1655 ----
writeword(record,input_port_value);
}
#ifdef MAME_NET
! if ( osd_net_active() )
! osd_net_sync(input_port_value, input_port_defaults);
#endif /* MAME_NET */
profiler_mark(PROFILER_END);
***************
*** 1758,1764 ****
READ16_HANDLER( input_port_18_word_r ) { return readinputport(1; }
READ16_HANDLER( input_port_19_word_r ) { return readinputport(19); }
! #ifdef MAME_NET
void set_default_player_controls(int player)
{
if (player == NET_SPECTATOR)
--- 1758,1764 ----
READ16_HANDLER( input_port_18_word_r ) { return readinputport(1; }
READ16_HANDLER( input_port_19_word_r ) { return readinputport(19); }
! #ifdef OLD_MAME_NET
void set_default_player_controls(int player)
{
if (player == NET_SPECTATOR)
***************
*** 1766,1772 ****
else
default_player = player - 1;
}
! #endif /* MAME_NET */
/***************************************************************************/
/* InputPort conversion */
--- 1766,1772 ----
else
default_player = player - 1;
}
! #endif /* OLD_MAME_NET */
/***************************************************************************/
/* InputPort conversion */
diff -cr xmame-0.56.1/src/mame.c xmame-0.56.1-net/src/mame.c
*** xmame-0.56.1/src/mame.c Fri Nov 2 20:22:51 2001
--- xmame-0.56.1-net/src/mame.c Wed Dec 5 19:57:18 2001
***************
*** 1253,1259 ****
#ifdef MAME_NET
/* disable high score when playing network game */
/* (this forces all networked machines to start from the same state!) */
! if (net_active()) return 0;
#endif /* MAME_NET */
return 1;
--- 1253,1259 ----
#ifdef MAME_NET
/* disable high score when playing network game */
/* (this forces all networked machines to start from the same state!) */
! if (osd_net_active()) return 0;
#endif /* MAME_NET */
return 1;
diff -cr xmame-0.56.1/src/network.h xmame-0.56.1-net/src/network.h
*** xmame-0.56.1/src/network.h Fri Nov 2 20:22:51 2001
--- xmame-0.56.1-net/src/network.h Wed Dec 5 20:10:26 2001
***************
*** 3,9 ****
network.h
***************************************************************************/
! #ifdef MAME_NET
#ifndef __NETWORK_H__
#define __NETWORK_H__
--- 3,9 ----
network.h
***************************************************************************/
! #ifdef OLD_MAME_NET
#ifndef __NETWORK_H__
#define __NETWORK_H__
***************
*** 201,204 ****
#endif /* __NETWORK_H__ */
! #endif /* MAME_NET */
--- 201,204 ----
#endif /* __NETWORK_H__ */
! #endif /* OLD_MAME_NET */
diff -cr xmame-0.56.1/src/osdepend.h xmame-0.56.1-net/src/osdepend.h
*** xmame-0.56.1/src/osdepend.h Fri Nov 2 20:22:53 2001
--- xmame-0.56.1-net/src/osdepend.h Thu Dec 6 15:41:21 2001
***************
*** 387,395 ****
#ifdef MAME_NET
/* network */
int osd_net_init(void);
int osd_net_send(int player, unsigned char buf[], int *size);
int osd_net_recv(int player, unsigned char buf[], int *size);
! int osd_net_sync(void);
int osd_net_input_sync(void);
int osd_net_exit(void);
int osd_net_add_player(void);
--- 387,397 ----
#ifdef MAME_NET
/* network */
int osd_net_init(void);
+ int osd_net_active(void);
int osd_net_send(int player, unsigned char buf[], int *size);
int osd_net_recv(int player, unsigned char buf[], int *size);
! void osd_net_sync(unsigned short input_port_values[MAX_INPUT_PORTS],
! unsigned short input_port_defaults[MAX_INPUT_PORTS]);
int osd_net_input_sync(void);
int osd_net_exit(void);
int osd_net_add_player(void);
diff -cr xmame-0.56.1/src/unix/network.c xmame-0.56.1-net/src/unix/network.c
*** xmame-0.56.1/src/unix/network.c Fri Nov 2 20:22:57 2001
--- xmame-0.56.1-net/src/unix/network.c Fri Dec 7 14:00:37 2001
***************
*** 1,14 ****
#include "xmame.h"
#ifdef MAME_NET
! enum {MASTER=1,SLAVE};
! enum {IDENTIFY, SYNC};
! #define NAME_LENGTH 256
! #define PORT_DATA 9000
!
! static int netkeymap = 0;
! static int players = 0;
! static char *mastername = NULL;
#endif
struct rc_option network_opts[] = {
--- 1,71 ----
#include "xmame.h"
+ #undef PROTOCOL_DEBUG
+
#ifdef MAME_NET
!
! #include <sys/types.h>
! #include <sys/socket.h>
! #include <netinet/in.h>
! #include <arpa/inet.h>
! #include <netdb.h>
! #ifdef svgalib
! #include <vgakeyboard.h>
! #endif
! #include "driver.h"
!
! enum net_role {
! NONE,
! MASTER,
! SLAVE
! };
!
! static enum net_role current_net_role = NONE;
!
! #define NET_MAX_PLAYERS 4
! #define MASTER_INPUT_PORT 9000
! #define SLAVE_INPUT_PORT 9001
! #define MAX_MSG_LEN 100
!
! enum net_msg_type {
! JOIN,
! ACCEPT,
! REFUSE,
! LOCAL_STATE,
! GLOBAL_STATE,
! QUIT
! };
!
! #define MSG_MAGIC_HEADER "XNM"
! #define PROTOCOL_VERSION "N0.1.0"
!
! struct net_msg_info {
! enum net_msg_type msg_type;
! unsigned sequence;
! unsigned char msg[MAX_MSG_LEN];
! unsigned char *data_start;
! int data_len;
! } scratch_msg_info, output_state_msg_info;
!
! static int input_remap = 0;
!
! /* For master only */
! static int original_player_count = 0;
! static int current_player_count = 0;
! struct net_slave_info {
! char name[MAX_MSG_LEN];
! unsigned active;
! struct sockaddr_in addr;
! unsigned expected_sequence;
! } slave_info[NET_MAX_PLAYERS - 1];
!
! /* For slave only */
! const char *master_hostname = NULL;
! static struct sockaddr_in output_addr;
! static struct sockaddr_in input_addr;
! static unsigned char player_number;
! static int input_map[MAX_INPUT_PORTS * 16];
!
#endif
struct rc_option network_opts[] = {
***************
*** 17,29 ****
{ "Network Related", NULL, rc_seperator, NULL,
NULL, 0, 0, NULL,
NULL },
! { "master", NULL, rc_int, &players,
NULL, 1, 4, NULL,
"Enable master mode. Set number of players" },
! { "slave", NULL, rc_string, &mastername,
NULL, 0, 0, NULL,
"Enable slave mode. Set master hostname" },
! { "netmapkey", NULL, rc_bool, &netkeymap,
"0", 0, 0, NULL,
"When enabled all players use the player 1 keys. For use with *real*
multiplayer games" },
#endif
--- 74,86 ----
{ "Network Related", NULL, rc_seperator, NULL,
NULL, 0, 0, NULL,
NULL },
! { "master", NULL, rc_int,
&original_player_count,
NULL, 1, 4, NULL,
"Enable master mode. Set number of players" },
! { "slave", NULL, rc_string, &master_hostname,
NULL, 0, 0, NULL,
"Enable slave mode. Set master hostname" },
! { "netmapkey", NULL, rc_bool, &input_remap,
"0", 0, 0, NULL,
"When enabled all players use the player 1 keys. For use with *real*
multiplayer games" },
#endif
***************
*** 33,87 ****
};
#ifdef MAME_NET
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #ifdef svgalib
- #include <vgakeyboard.h>
- #endif
- #include "driver.h"
! static int socks[4];
! static struct sockaddr_in names[4];
! static int player;
! static unsigned char keymap[128]; /* table to map network keys to player 1 */
! static int timeout = 60;
! static int init_master_socket(void)
{
! struct hostent *hp;
! char hname[NAME_LENGTH];
! fprintf(stderr_file, "XMame in network Master Mode\nWaiting for %d
players.\n", players-1);
! gethostname(hname, 256);
/* socket creation */
! if ((socks[0] = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
! {
! fprintf(stderr_file, "init master : Can't initialise socket\n");
return(OSD_NOT_OK);
}
! /* Assign domain and port number */
! memset(&names[0], 0, sizeof(names[0]));
! names[0].sin_family = AF_INET;
! names[0].sin_port = PORT_DATA;
!
! /* Assign IP address */
! if ((hp = gethostbyname(hname)) == NULL)
{
! fprintf(stderr_file, "init master : gethostbyname error\n");
return(OSD_NOT_OK);
}
- memcpy(&(names[0].sin_addr.s_addr), hp->h_addr, hp->h_length);
! /* bind socket */
! if (bind(socks[0], (struct sockaddr *)&names[0], sizeof(names[0])) == -1)
! {
! fprintf(stderr_file, "init master : Bind failure.\n");
! return(OSD_NOT_OK);
}
return(OSD_OK);
--- 90,135 ----
};
#ifdef MAME_NET
! static int output_socket;
! static int input_socket;
!
! unsigned current_frame_sequence = 0;
! static int init_master_sockets(void)
{
! struct sockaddr_in input_socket_addr;
! fprintf(stderr_file,
! "XMame in network Master Mode\n"
! "Waiting for %d more players.\n",
! original_player_count - 1);
/* socket creation */
! if ((input_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
! fprintf(stderr_file,
! "init master : Can't initialise socket (%s)\n",
! strerror(errno));
return(OSD_NOT_OK);
}
! /* bind socket */
! input_socket_addr.sin_family = AF_INET;
! input_socket_addr.sin_port = htons(MASTER_INPUT_PORT);
! input_socket_addr.sin_addr.s_addr = INADDR_ANY;
! if (bind(input_socket,
! (struct sockaddr *)&input_socket_addr,
! sizeof(input_socket_addr)) == -1)
{
! fprintf(stderr_file, "init master : Bind failure (%s)\n",
strerror(errno));
return(OSD_NOT_OK);
}
! if ((output_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
! fprintf(stderr_file,
! "Error: can't initialise output socket\n (%s)",
! strerror(errno));
! return(OSD_NOT_OK);
}
return(OSD_OK);
***************
*** 89,438 ****
static int init_slave_sockets(void)
{
! struct hostent *hp;
! char hname[NAME_LENGTH];
- fprintf(stderr_file, "Slave Mode; Registering to Master %s\n", mastername);
-
/* socket creation */
! if ((socks[1] = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
! {
! fprintf(stderr_file, "init slave : Can't initialise socket\n");
return(OSD_NOT_OK);
}
/* Assign domain and port number */
! memset(&names[1], 0, sizeof(names[1]));
! names[1].sin_family = AF_INET;
! names[1].sin_port = PORT_DATA;
/* Assign IP address */
! if ((hp = gethostbyname(mastername)) == NULL)
! {
fprintf(stderr_file, "init slave : gethostbyname error\n");
return(OSD_NOT_OK);
}
! memcpy(&(names[1].sin_addr.s_addr), hp->h_addr, hp->h_length);
!
! gethostname(hname, 256);
/* socket creation */
! if ((socks[0] = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
! {
! fprintf(stderr_file, "init slave : Can't initialise socket\n");
return(OSD_NOT_OK);
}
/* Assign domain and port number */
! memset(&names[0], 0, sizeof(names[0]));
! names[0].sin_family = AF_INET;
! names[0].sin_port = PORT_DATA+1;
!
! /* Assign IP address */
! if ((hp = gethostbyname(hname)) == NULL)
! {
! fprintf(stderr_file, "init slave : gethostbyname error\n");
! return(OSD_NOT_OK);
! }
! memcpy(&(names[0].sin_addr.s_addr), hp->h_addr, hp->h_length);
/* bind socket */
! if (bind(socks[0], (struct sockaddr *)&names[0], sizeof(names[0])) == -1)
! {
! fprintf(stderr_file, "init slave : Bind failure.\n");
return(OSD_NOT_OK);
}
return(OSD_OK);
}
! static int receive_msg(void *msg, int size)
! {
! unsigned int lg = 0;
! fd_set rfds;
! struct timeval tv;
!
! /* watch socks[0] to see if it has any input */
! FD_ZERO(&rfds);
! FD_SET(socks[0], &rfds);
!
! /* Wait up to timeout seconds. */
! tv.tv_sec = timeout;
! tv.tv_usec = 0;
! if (select(socks[0] + 1, &rfds, NULL, NULL, &tv)==0)
! {
! fprintf(stderr_file, "Error: timeout (%d secs) while receiving
message.\n", timeout);
! return OSD_NOT_OK;
! }
! if (recvfrom(socks[0], msg, size, 0, NULL, &lg) == -1)
! {
! fprintf(stderr_file, "Error: socket error receiving message.\n");
return OSD_NOT_OK;
! }
return OSD_OK;
}
! static int send_msg(void *msg, int size)
{
! int i;
!
! switch(netstate)
! {
! case MASTER:
! for(i=1;i<players;i++)
! {
! if (sendto(socks, msg, size, 0, (struct sockaddr
*)&names, sizeof(names)) == -1)
! {
! fprintf(stderr_file, "Error: socket error sending
message.\n");
! return OSD_NOT_OK;
! }
! }
! break;
! case SLAVE:
! if (sendto(socks[1], msg, size, 0, (struct sockaddr *)&names[1],
sizeof(names[1])) == -1)
! {
! fprintf(stderr_file, "Error: socket error sending message.\n");
! return OSD_NOT_OK;
! }
! break;
! }
! return OSD_OK;
}
! static int add_slave(char *host, int *sock, struct sockaddr_in *name)
{
! struct hostent *hp;
!
! /* socket creation */
! if ((*sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
! {
! fprintf(stderr_file, "Error: can't initialise socket\n");
! return(OSD_NOT_OK);
! }
!
! /* Assign domain and port number */
! memset(name, 0, sizeof(struct sockaddr_in));
! name->sin_family = AF_INET;
! name->sin_port = PORT_DATA+1;
!
! /* Assign IP address */
! if ((hp = gethostbyname(host)) == NULL)
! {
! fprintf(stderr_file, "Error: gethostbyname error\n");
! return(OSD_NOT_OK);
! }
! memcpy(&name->sin_addr.s_addr, hp->h_addr, hp->h_length);
! return(OSD_OK);
}
static int register_to_master(void)
{
! char hname[NAME_LENGTH];
! gethostname(hname, NAME_LENGTH);
! if (sendto(socks[1], hname, NAME_LENGTH, 0, (struct sockaddr *)&names[1],
sizeof(names[1])) == -1)
! {
! fprintf(stderr_file, "Error: socket error sending registration to
master");
! return OSD_NOT_OK;
}
! if (receive_msg(&player, sizeof(player)) != OSD_OK) return OSD_NOT_OK;
! fprintf(stderr_file, "Registered as player %d\n", player);
return OSD_OK;
}
! static int wait_registration(void)
{
! char hname[NAME_LENGTH]; /* slave host name */
! int i;
! for(i=1;i<players;i++)
! {
! player=i+1;
! if (receive_msg(hname, NAME_LENGTH) != OSD_OK)
! {
! fprintf(stderr_file, "Error: Can't receive registration from
player %d\n", player);
! return OSD_NOT_OK;
! }
! if (add_slave(hname, &socks, &names)!=OSD_OK) return OSD_NOT_OK;
! if (sendto(socks, &player, sizeof(player), 0, (struct sockaddr
*)&names, sizeof(names))==-1)
! {
! fprintf(stderr_file, "Error: socket error sending registration
to player %d\n", player);
! return OSD_NOT_OK;
! }
! fprintf(stderr_file, "%s registered successfully as player %d.\n",
hname, player);
}
! player = 1;
return OSD_OK;
}
! int default_key(const struct InputPort *in);
!
! static int net_map_key(int keycode, int playermask)
{
! struct InputPort *in = Machine->input_ports, *start = Machine->input_ports;
! int port, found, event = 0;
! if (in->type == IPT_END) return keycode; /* nothing to do */
! /* make sure the InputPort definition is correct */
! if (in->type != IPT_PORT)
! {
! if (errorlog) fprintf(errorlog,"Error in InputPort definition: expecting
PORT_START\n");
! return keycode;
}
! else start = ++in;
!
! found = 0;
! port = 0;
! while ((found ==0) && (in->type != IPT_END) && (port < MAX_INPUT_PORTS))
! {
! while (in->type != IPT_END && in->type != IPT_PORT)
! {
! if (default_key(in)==keycode)
! {
! event = in->type;
! found = 1;
! break;
! }
! in++;
! }
! if (found == 0)
! {
! port++;
! if (in->type == IPT_PORT) in++;
! }
}
! if (found == 0) return keycode;
!
! in = start;
! port = 0;
! while (in->type != IPT_END && port < MAX_INPUT_PORTS)
{
! while (in->type != IPT_END && in->type != IPT_PORT)
{
! if ((in->type & IPF_PLAYERMASK)== playermask)
! if ((in->type & (~IPF_MASK)) == (event & (~IPF_MASK)))
! {
! return default_key(in);
! }
! in++;
}
! port++;
! if (in->type == IPT_PORT) in++;
}
!
! return keycode;
}
static void build_keymap(void)
{
! int i, keycode, playermask = 0;
! switch(player)
! {
case 1:
! playermask = IPF_PLAYER1;
! break;
case 2:
! playermask = IPF_PLAYER2;
! break;
case 3:
! playermask = IPF_PLAYER3;
! break;
case 4:
! playermask = IPF_PLAYER4;
! break;
! }
!
! memset(keymap,0,128*sizeof(unsigned char));
! for(i=0;i<128;i++)
! {
! keymap[net_map_key(i, playermask)] = i;
! }
}
-
/*
! * get key tables from slaves
*/
! void osd_net_sync(void)
{
! int i,j;
! static char net_key[128];
!
! if (!key) return;
!
! if (netkeymap)
! {
! for(i=0; i<128; i++)
! {
! global_key = local_key[keymap];
! }
}
!
! switch(netstate)
! {
! case MASTER:
! if(!netkeymap) memcpy(global_key, local_key, 128*sizeof(unsigned char));
! for(i=1;i<players;i++)
! {
! if (receive_msg(net_key, 128*sizeof(unsigned char)) != OSD_OK)
! goto drop_to_single_player;
! for(j=0;j<=OSD_MAX_KEY;j++)
! global_key[j] |= net_key[j];
! }
! if (send_msg(global_key, 128*sizeof(unsigned char)) != OSD_OK)
! goto drop_to_single_player;
! break;
! case SLAVE:
! if (netkeymap)
! {
! if (send_msg(global_key, 128*sizeof(unsigned char)) != OSD_OK)
! goto drop_to_single_player;
}
! else
! {
! if (send_msg(local_key, 128*sizeof(unsigned char)) != OSD_OK)
! goto drop_to_single_player;
}
- if (receive_msg(global_key, 128*sizeof(unsigned char))!=OSD_OK)
- goto drop_to_single_player;
- break;
}
! /* after the first successfull sync it should be safe to lower the
! timeout to 5 seconds */
! timeout = 5;
! return;
! drop_to_single_player:
! fprintf(stderr_file, "Lost network connection, continuing in single player
mode\n");
! osd_net_close();
! netstate=0;
! key=local_key;
}
/*
* Close all opened sockets
*/
void osd_net_close(void)
{
! int i;
!
! switch(netstate)
{
! case MASTER:
! for(i=0;i<(players-1);i++) close(socks);
! break;
! case SLAVE:
! close(socks[0]);
! close(socks[1]);
! break;
}
}
--- 137,750 ----
static int init_slave_sockets(void)
{
! struct hostent *master_hostent;
/* socket creation */
! if ((output_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
! fprintf(stderr_file,
! "init slave : Can't initialise output socket (%s)\n",
! strerror(errno));
return(OSD_NOT_OK);
}
/* Assign domain and port number */
! output_addr.sin_family = AF_INET;
! output_addr.sin_port = htons(MASTER_INPUT_PORT);
/* Assign IP address */
! if ((master_hostent = gethostbyname(master_hostname)) == NULL) {
fprintf(stderr_file, "init slave : gethostbyname error\n");
return(OSD_NOT_OK);
}
! memcpy(&(output_addr.sin_addr.s_addr),
! master_hostent->h_addr,
! master_hostent->h_length);
/* socket creation */
! if ((input_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
! fprintf(stderr_file,
! "init slave : Can't initialise input socket (%s)\n",
! strerror(errno));
return(OSD_NOT_OK);
}
/* Assign domain and port number */
! input_addr.sin_family = AF_INET;
! input_addr.sin_port = htons(SLAVE_INPUT_PORT);
! input_addr.sin_addr.s_addr = INADDR_ANY;
/* bind socket */
! if (bind(input_socket, (struct sockaddr *)&input_addr, sizeof(input_addr))
== -1) {
! fprintf(stderr_file,
! "init slave : Input socket bind failure (%s).\n",
! strerror(errno));
return(OSD_NOT_OK);
}
return(OSD_OK);
}
! static int rcv_msg(int fd,
! struct net_msg_info *msg_info,
! struct sockaddr_in *source_addr,
! unsigned timeout)
! {
! socklen_t socklen = 0;
! fd_set scratch_fds;
! struct timeval timeout_tv = { timeout / 1000000, (timeout % 1000000) * 1000
};
! struct timeval *timeout_tv_p = NULL;
! int msg_len;
!
! if (timeout > 0) {
! timeout_tv_p = &timeout_tv;
! }
!
! if (source_addr != 0) {
! socklen = sizeof(*source_addr);
! }
!
! do {
! FD_ZERO(&scratch_fds);
! FD_SET(fd, &scratch_fds);
!
! if (select(fd + 1, &scratch_fds, NULL, NULL, timeout_tv_p) == 0) {
! fprintf(stderr_file,
! "Error: timeout (%d ms) while receiving message.\n",
! timeout);
! return OSD_NOT_OK;
! }
! msg_len = recvfrom(fd,
! msg_info->msg,
! sizeof(msg_info->msg),
! 0,
! source_addr,
! &socklen);
! if (msg_len < 0) {
! fprintf(stderr_file,
! "Error: socket error receiving message (%s).\n",
! strerror(errno));
return OSD_NOT_OK;
! }
! /* Packets without the magic header are discarded without error; they are
! assumed to be unrelated traffic */
! } while (msg_len < 4 || memcmp(msg_info->msg, MSG_MAGIC_HEADER, 3) != 0);
!
! msg_info->msg_type = msg_info->msg[3];
! switch (msg_info->msg_type) {
! case JOIN:
! case ACCEPT:
! case REFUSE:
! case QUIT:
! msg_info->data_start = msg_info->msg + 4;
! msg_info->data_len = msg_len - 4;
! break;
! case LOCAL_STATE:
! case GLOBAL_STATE:
! if (msg_len <= {
! fprintf(stderr_file,
! "Error: received truncated state packet (size %i).\n",
! msg_len);
! return OSD_NOT_OK;
! }
! msg_info->sequence = (unsigned)ntohl(*((long int *)(msg_info->msg + 4)));
! msg_info->data_start = msg_info->msg + 8;
! msg_info->data_len = msg_len - 8;
! break;
! }
return OSD_OK;
}
! void prime_msg(struct net_msg_info *msg_info)
{
! memcpy(msg_info->msg, MSG_MAGIC_HEADER, 3);
! msg_info->msg[3] = (unsigned char)msg_info->msg_type;
! switch (msg_info->msg_type) {
! case JOIN:
! case ACCEPT:
! case REFUSE:
! case QUIT:
! msg_info->data_start = msg_info->msg + 4;
! break;
! case LOCAL_STATE:
! case GLOBAL_STATE:
! (*(long int *)(msg_info->msg + 4)) = ntohl(msg_info->sequence);
! msg_info->data_start = msg_info->msg + 8;
! break;
! }
! msg_info->data_len = 0;
}
! int write_to_msg(struct net_msg_info *msg_info, const void *new_data, unsigned
new_data_len)
{
! if ((msg_info->data_start - msg_info->msg) + msg_info->data_len + new_data_len >
MAX_MSG_LEN)
! {
! fprintf(stderr_file, "Error: message overflow\n");
! return OSD_NOT_OK;
! }
! memcpy(msg_info->data_start + msg_info->data_len, new_data, new_data_len);
! msg_info->data_len += new_data_len;
! return OSD_OK;
! }
! static int send_msg(int sock_fd, struct net_msg_info *msg_info, struct sockaddr_in
*dest)
! {
! if (sendto(sock_fd,
! msg_info->msg,
! (msg_info->data_start - msg_info->msg) + msg_info->data_len,
! 0,
! (struct sockaddr *)dest,
! sizeof(*dest)) < 0)
! {
! fprintf(stderr_file, "Error: socket error sending message (%s).\n",
strerror(errno));
! return OSD_NOT_OK;
! }
! return OSD_OK;
}
static int register_to_master(void)
{
! char scratch[MAX_MSG_LEN];
! fprintf(stderr_file, "Slave Mode; Registering to Master %s\n",
master_hostname);
!
! gethostname(scratch, MAX_MSG_LEN);
!
! scratch_msg_info.msg_type = JOIN;
! prime_msg(&scratch_msg_info);
! write_to_msg(&scratch_msg_info, scratch, strlen(scratch));
! sprintf(scratch, "/%d", getpid());
! write_to_msg(&scratch_msg_info, scratch, strlen(scratch) + 1);
! write_to_msg(&scratch_msg_info, build_version, strlen(build_version) + 1);
! write_to_msg(&scratch_msg_info, PROTOCOL_VERSION, strlen(PROTOCOL_VERSION) +
1);
! write_to_msg(&scratch_msg_info,
! Machine->gamedrv->name,
! strlen(Machine->gamedrv->name) + 1);
!
! do {
! send_msg(output_socket, &scratch_msg_info, &output_addr);
! } while (rcv_msg(input_socket, &scratch_msg_info, NULL, 1000) != OSD_OK);
!
! if (scratch_msg_info.msg_type == REFUSE) {
! fprintf(stderr_file, "Master %s refused registration\n", master_hostname);
! if (scratch_msg_info.data_len > 0) {
! fprintf(stderr_file, "Reason given: %.50s\n",
scratch_msg_info.data_start);
! } else {
! fprintf(stderr_file, "No reason given\n");
! }
! return OSD_NOT_OK;
! }
! else if (scratch_msg_info.msg_type != ACCEPT) {
! fprintf(stderr_file,
! "Master %s returned bogus message type %d\n",
! master_hostname,
! scratch_msg_info.msg_type);
! return OSD_NOT_OK;
}
!
! player_number = scratch_msg_info.data_start[0];
!
! fprintf(stderr_file, "Registeration as player %d confirmed\n",
(unsigned)player_number);
return OSD_OK;
}
! static int await_slave_registrations(void)
{
! unsigned char i = 0;
! struct sockaddr_in source_addr;
! while (i < original_player_count - 1) {
! unsigned msg_data_left;
! unsigned char *msg_read_pointer;
! unsigned char scratch_msg_data[MAX_MSG_LEN];
!
! if (rcv_msg(input_socket, &scratch_msg_info, &source_addr, 0)) {
! fprintf(stderr_file,
! "Error: Registration from slave failed (%s)\n",
! strerror(errno));
! continue;
! }
! if (scratch_msg_info.msg_type != JOIN) {
! fprintf(stderr_file,
! "Error: Unexpected message type (%d) while awaiting
registrations\n",
! scratch_msg_info.msg_type);
! continue;
! }
!
! msg_data_left = scratch_msg_info.data_len;
! msg_read_pointer = scratch_msg_info.data_start;
!
! slave_info.addr.sin_family = AF_INET;
! slave_info.addr.sin_port = htons(SLAVE_INPUT_PORT);
! memcpy(&(slave_info.addr.sin_addr),
! &(source_addr.sin_addr),
! sizeof(slave_info.addr.sin_addr));
!
! strncpy(slave_info.name, msg_read_pointer, msg_data_left);
! msg_data_left -= (strlen(slave_info.name) + 1);
! msg_read_pointer += (strlen(slave_info.name) + 1);
!
! if (strncmp(msg_read_pointer, build_version, msg_data_left) != 0) {
! scratch_msg_info.msg_type = REFUSE;
! prime_msg(&scratch_msg_info);
! sprintf(scratch_msg_data,
! "Wrong build version; need %s not %.10s",
! build_version,
! msg_read_pointer);
! write_to_msg(&scratch_msg_info, scratch_msg_data,
strlen(scratch_msg_data));
! send_msg(output_socket, &scratch_msg_info, &(slave_info.addr));
! continue;
! }
! msg_data_left -= strlen(build_version) + 1;
! msg_read_pointer += strlen(build_version) + 1;
!
! if (strncmp(msg_read_pointer, PROTOCOL_VERSION, msg_data_left) != 0) {
! scratch_msg_info.msg_type = REFUSE;
! prime_msg(&scratch_msg_info);
! sprintf(scratch_msg_data,
! "Wrong protocol version; need %s not %.10s",
! PROTOCOL_VERSION,
! msg_read_pointer);
! write_to_msg(&scratch_msg_info, scratch_msg_data,
strlen(scratch_msg_data));
! send_msg(output_socket, &scratch_msg_info, &(slave_info.addr));
! continue;
! }
! msg_data_left -= strlen(PROTOCOL_VERSION) + 1;
! msg_read_pointer += strlen(PROTOCOL_VERSION) + 1;
!
! if (strncmp(msg_read_pointer, Machine->gamedrv->name, msg_data_left) != 0)
{
! scratch_msg_info.msg_type = REFUSE;
! prime_msg(&scratch_msg_info);
! sprintf(scratch_msg_data,
! "Wrong game; need %s not %.10s",
! Machine->gamedrv->name,
! msg_read_pointer);
! write_to_msg(&scratch_msg_info, scratch_msg_data,
strlen(scratch_msg_data));
! send_msg(output_socket, &scratch_msg_info, &(slave_info.addr));
! continue;
! }
!
! slave_info.active = 1;
! slave_info.expected_sequence = 0;
!
! scratch_msg_info.msg_type = ACCEPT;
! prime_msg(&scratch_msg_info);
! scratch_msg_data[0] = i + 2;
! write_to_msg(&scratch_msg_info, scratch_msg_data, 1);
!
! if (send_msg(output_socket,
! &scratch_msg_info,
! &(slave_info.addr)) != OSD_OK)
! {
! fprintf(stderr_file,
! "Error: socket error sending registration to slave %d (%s)\n",
! i,
! strerror(errno));
! return OSD_NOT_OK;
! }
! fprintf(stderr_file,
! "%s registeration accepted as player %d.\n",
! slave_info.name,
! i + 2);
! i += 1;
}
! current_player_count = original_player_count;
return OSD_OK;
}
! #if 0
! static int mapped_port_bit_for_port(int unmapped_port_index, int playermask)
{
! int candidate_port_group, candidate_port_index;
! int target_type;
! if (playermask == IPF_PLAYER1) return unmapped_port_index;
! if (Machine->input_ports[unmapped_port_index] & IPF_PLAYERMASK = playermask) {
! /* Map player n ports to player 1 */
! target_type =
! (Machine->input_ports[unmapped_port_index] & ~IPF_PLAYERMASK) &
IPF_PLAYER1;
}
! else if (Machine->input_ports[unmapped_port_index] & IPF_PLAYERMASK =
IPF_PLAYER1)
! /* Map player 1 ports to player n */
! target_type =
! (Machine->input_ports[unmapped_port_index] & ~IPF_PLAYERMASK) & playermask;
! } else {
! /* Other keys remain unchanged */
! return unmapped_port_index;
}
+
+ /* make sure the InputPort definition is correct */
+ if (in->type != IPT_PORT) {
+ if (errorlog) fprintf(errorlog,"Error in InputPort definition: expecting
+PORT_START\n");
+ return keycode;
+ }
+ else start = ++in;
! candidate_port_element = 0;
! candidate_port_group = 0;
! while (Machine->input_ports[candidate_port_index].type != IPT_END &&
! candidate_port_group < MAX_INPUT_PORTS)
{
! while (Machine->input_ports[candidate_port_index].type != IPT_END &&
! Machine->input_ports[candidate_port_index].type != IPT_PORT)
{
! if (Machine->input_ports[candidate_port_index].type == target_type) {
! return candidate_port_index;
! }
! candidate_port_index++;
}
! candidate_port_group++;
! if (Machine->input_ports[candidate_port_index].type == IPT_PORT)
candidate_port_index++;
}
!
! return unmapped_port_index;
}
+ #endif
static void build_keymap(void)
{
! int playermask;
! switch(player_number)
! {
case 1:
! playermask = IPF_PLAYER1;
! break;
case 2:
! playermask = IPF_PLAYER2;
! break;
case 3:
! playermask = IPF_PLAYER3;
! break;
case 4:
! playermask = IPF_PLAYER4;
! break;
! }
! /* for(unmapped_port_index = 0; unmapped_port_index < port_count;
unmapped_port_index++) {
! input_map[unmapped_port_index] = mapped_port_for_port(unmapped_port_index);
! } */
}
/*
! * get port state tables from slaves
*/
! static unsigned short scratch_slave_input_state[MAX_INPUT_PORTS];
!
! void osd_master_sync(unsigned short input_port_values[MAX_INPUT_PORTS],
! unsigned short input_port_defaults[MAX_INPUT_PORTS])
{
! unsigned i;
! unsigned slaves_reported = 0;
! unsigned char slave_index = (unsigned char)-1;
!
! struct sockaddr_in source_addr;
!
! /* Change the values into deviations from default values */
! for (i = 0; i < MAX_INPUT_PORTS; i++) {
! input_port_values ^= input_port_defaults;
}
!
! while (slaves_reported < current_player_count - 1) {
! if (rcv_msg(input_socket, &scratch_msg_info, &source_addr, 0) != OSD_OK)
! continue;
!
! for (i = 0; i < original_player_count - 1; i++) {
! if (slave_info.active &&
! memcmp(&(source_addr.sin_addr),
! &(slave_info.addr.sin_addr),
! sizeof(source_addr.sin_addr)) == 0)
! {
! slave_index = i;
! break;
! }
}
! if (slave_index == (unsigned char)-1) {
! fprintf(stderr_file, "Error : Received packet from unknown slave\n");
! continue;
! }
! if (scratch_msg_info.msg_type == QUIT) {
! fprintf(stderr_file, "Slave \"%s\" quit\n", slave_info[slave_index].name);
! current_player_count -= 1;
! if (current_player_count == 1) {
! current_net_role = NONE;
! break;
! }
! }
! if (scratch_msg_info.msg_type != LOCAL_STATE) {
! fprintf(stderr_file,
! "Error : Received unexpected message type (%d) from slave
\"%s\"\n",
! scratch_msg_info.msg_type,
! slave_info[slave_index].name);
! continue;
! }
!
! #ifdef PROTOCOL_DEBUG
! fprintf(stderr_file,
! "master : received state %d from slave \"%s\" (expecting %d)\n",
! scratch_msg_info.sequence,
! slave_info[slave_index].name,
! slave_info[slave_index].expected_sequence);
! #endif
! if (scratch_msg_info.sequence == slave_info[slave_index].expected_sequence) {
! slaves_reported += 1;
! memcpy(scratch_slave_input_state,
! scratch_msg_info.data_start,
! scratch_msg_info.data_len);
! for (i = 0; i < MAX_INPUT_PORTS; i++) {
! input_port_values |=
! (ntohs(scratch_slave_input_state) ^ input_port_defaults);
! }
! slave_info[slave_index].expected_sequence += 1;
! }
! else if (scratch_msg_info.sequence ==
slave_info[slave_index].expected_sequence - 1) {
! if (scratch_msg_info.sequence == current_frame_sequence) {
! /* Slave is sending states too fast? Ignore */
! } else {
! /* Slave missed previous state */
! #ifdef PROTOCOL_DEBUG
! fprintf(stderr_file,
! "master : Re-sending global state %d to slave \"%s\"\n",
! output_state_msg_info.sequence,
! slave_info[slave_index].name);
! #endif
! send_msg(output_socket,
! &output_state_msg_info,
! &slave_info[slave_index].addr);
! }
! } else {
! /* Lost packet? Ignore */
! }
! }
!
! /* At this point all slaves have reported their states */
! output_state_msg_info.msg_type = GLOBAL_STATE;
! output_state_msg_info.sequence = current_frame_sequence;
! prime_msg(&output_state_msg_info);
! for (i = 0; i < MAX_INPUT_PORTS; i++) {
! unsigned short scratch;
! /* Change the input port default deviations back into real values */
! input_port_values ^= input_port_defaults;
! scratch = htons(input_port_values);
! write_to_msg(&output_state_msg_info, &scratch, sizeof(scratch));
! }
! /* Send global state to all slaves */
! #ifdef PROTOCOL_DEBUG
! fprintf(stderr_file, "master : Sending global state %d\n",
current_frame_sequence);
! #endif
! for (i = 0; i < original_player_count - 1; i++) {
! if (slave_info.active) {
! send_msg(output_socket, &output_state_msg_info, &slave_info.addr);
}
}
! current_frame_sequence += 1;
! }
!
! void osd_slave_sync(unsigned short input_port_values[MAX_INPUT_PORTS],
! unsigned short input_port_defaults[MAX_INPUT_PORTS])
! {
! unsigned i;
!
! output_state_msg_info.msg_type = LOCAL_STATE;
! output_state_msg_info.sequence = current_frame_sequence;
! prime_msg(&output_state_msg_info);
! for (i = 0; i < MAX_INPUT_PORTS; i++) {
! unsigned short scratch = htons(input_port_values);
! write_to_msg(&output_state_msg_info, &scratch, sizeof(scratch));
! }
! while (1) {
! #ifdef PROTOCOL_DEBUG
! fprintf(stderr_file,
! "slave : sending state %d to master\n",
! output_state_msg_info.sequence);
! #endif
! send_msg(output_socket, &output_state_msg_info, &output_addr);
! /* Try a 12 ms timeout for now */
! if (rcv_msg(input_socket, &scratch_msg_info, NULL, 30) != OSD_OK)
! continue;
!
! if (scratch_msg_info.msg_type == QUIT) {
! fprintf(stderr_file, "Master disconnected! No more network input\n");
! current_net_role = NONE;
! return;
! }
! if (scratch_msg_info.msg_type != GLOBAL_STATE) {
! fprintf(stderr_file,
! "Error : Received wrong packet type (%d) from master\n",
! scratch_msg_info.msg_type);
! continue;
! }
!
! #ifdef PROTOCOL_DEBUG
! fprintf(stderr_file,
! "slave : received state %d from master (awaiting %d)\n",
! scratch_msg_info.sequence,
! current_frame_sequence);
! #endif
! if (scratch_msg_info.sequence == current_frame_sequence)
! break;
! }
!
! for (i = 0; i < MAX_INPUT_PORTS; i++) {
! input_port_values = ntohs(((unsigned short
*)(scratch_msg_info.data_start)));
! }
! current_frame_sequence += 1;
}
+ void osd_net_sync(unsigned short input_port_values[MAX_INPUT_PORTS],
+ unsigned short input_port_defaults[MAX_INPUT_PORTS])
+ {
+ switch(current_net_role) {
+ case MASTER:
+ osd_master_sync(input_port_values, input_port_defaults);
+ break;
+ case SLAVE:
+ osd_slave_sync(input_port_values, input_port_defaults);
+ break;
+ default:
+ /* wtf? */
+ break;
+ }
+ }
+
/*
* Close all opened sockets
*/
void osd_net_close(void)
{
! unsigned i, j;
! switch(current_net_role)
{
! case SLAVE:
! scratch_msg_info.msg_type = QUIT;
! prime_msg(&scratch_msg_info);
! for (i = 0; i < 4; i++) {
! send_msg(output_socket, &scratch_msg_info, &output_addr);
! usleep(50);
! }
! close(input_socket);
! close(output_socket);
! break;
! case MASTER:
! scratch_msg_info.msg_type = QUIT;
! prime_msg(&scratch_msg_info);
! for (i = 0; i < 4; i++) {
! for (j = 0; j < original_player_count - 1; j++) {
! if (slave_info[j].active) {
! send_msg(output_socket, &scratch_msg_info,
&(slave_info[j].addr));
! }
! }
! usleep(50);
! }
! close(input_socket);
! close(output_socket);
! break;
! case NONE:
! break;
}
}
***************
*** 443,469 ****
*/
int osd_net_init(void)
{
! netstate = 0;
!
! if (players) netstate = MASTER;
! if (mastername)
! {
! if(netstate==MASTER)
! {
fprintf(stderr_file, "error: can't be Slave and Master\n");
return OSD_NOT_OK;
}
! netstate = SLAVE;
}
! switch(netstate)
{
! case 0:
return OSD_OK;
case MASTER:
! if (init_master_socket() != OSD_OK)
return OSD_NOT_OK;
! if (wait_registration() != OSD_OK)
return OSD_NOT_OK;
break;
case SLAVE:
--- 755,780 ----
*/
int osd_net_init(void)
{
! if (original_player_count > 0) {
! current_net_role = MASTER;
! }
!
! if (master_hostname) {
! if (current_net_role == MASTER) {
fprintf(stderr_file, "error: can't be Slave and Master\n");
return OSD_NOT_OK;
}
! current_net_role = SLAVE;
}
! switch(current_net_role)
{
! case NONE:
return OSD_OK;
case MASTER:
! if (init_master_sockets() != OSD_OK)
return OSD_NOT_OK;
! if (await_slave_registrations() != OSD_OK)
return OSD_NOT_OK;
break;
case SLAVE:
***************
*** 471,482 ****
return OSD_NOT_OK;
if (register_to_master() != OSD_OK)
return OSD_NOT_OK;
break;
}
- if (netkeymap) build_keymap();
- /* mouse is not supported in network mode */
- use_mouse = FALSE;
return OSD_OK;
}
#endif /* MAME_NET */
--- 782,797 ----
return OSD_NOT_OK;
if (register_to_master() != OSD_OK)
return OSD_NOT_OK;
+ /* if (input_remap)
+ build_net_keymap(); */
break;
}
return OSD_OK;
+ }
+
+ int osd_net_active(void)
+ {
+ return (current_net_role != NONE);
}
#endif /* MAME_NET */
diff -cr xmame-0.56.1/src/usrintrf.c xmame-0.56.1-net/src/usrintrf.c
*** xmame-0.56.1/src/usrintrf.c Fri Nov 2 20:22:51 2001
--- xmame-0.56.1-net/src/usrintrf.c Wed Dec 5 19:56:22 2001
***************
*** 3575,3583 ****
while (!input_ui_pressed(IPT_UI_PAUSE))
{
- #ifdef MAME_NET
- osd_net_sync();
- #endif /* MAME_NET */
profiler_mark(PROFILER_VIDEO);
if (osd_skip_this_frame() == 0)
{
--- 3575,3580 ----
_______________________________________________
Xmame mailing list
[EMAIL PROTECTED]
http://toybox.twisted.org.uk/mailman/listinfo/xmame
[Xmame] mamenet lives! sorta, Steve Freeland
Re: [Xmame] mamenet lives! sorta, Lawrence Gold
Re: [Xmame] mamenet lives! sorta, Hoonis
Re: [Xmame] mamenet lives! sorta, Steve Freeland
Re: [Xmame] mamenet lives! sorta, Hoonis
Re: [Xmame] mamenet lives! sorta, Steve Freeland
Re: [Xmame] mamenet lives! sorta, Hoonis
Re: [Xmame] mamenet lives! sorta, Hoonis
Re: [Xmame] mamenet lives! sorta, Steve Freeland
Re: [Xmame] mamenet lives! sorta, theGREENzebra
Re: [Xmame] mamenet lives! sorta, Steve Freeland
<-- Chronological -->
<-- Thread -->
Reply via email to |
|