QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1378|回复: 10

xmame 网络对战问题

[复制链接]
发表于 2004-3-29 16:34:44 | 显示全部楼层 |阅读模式
我看到mame里面是可以网络对战的,而且xmame 的配置文件里面也有network的选项,但是怎么手册里面没有啊

怎么样能用xmame玩对战?

谢谢
发表于 2004-3-30 10:58:01 | 显示全部楼层
需要kaillera客户端
不KAILLERA 网站上似乎没有LINUX的客户端?!
回复

使用道具 举报

发表于 2004-4-1 14:53:46 | 显示全部楼层
改makefile就ok了以下是一个Makefile文件的范例

...
# 去掉这行的注释以使用联网游戏功能
# XMAME_NET = 1
...
...
# 去掉这行的注释以使用68000的x86汇编优化引擎(需要安装NASM)
# X86_ASM_68000 = 1
# 去掉这行的注释以使用DRC MIPS3引擎
# X86_MIPS3_DRC = 1

# gcc on x86
# 将这行注释掉
CFLAGS = -O -Wall -Wno-unused

# gcc on x86 with some optimizations
# 去掉以下两行的注释,以打开一些优化开关,如果你不是i686芯片,去掉"-mcpu=i686"
# CFLAGS = -O2 -Wall -Wno-unused -mcpu=i686 -fomit-frame-pointer \
# -fstrict-aliasing -fstrength-reduce -ffast-math
...
...
# 选择适合你的CPU类型,去掉前面的注释
# Valid x86 options that work with any version of gcc.
# CFLAGS += -march=i386
# CFLAGS += -march=i486
# CFLAGS += -march=i586
# CFLAGS += -march=i686
# CFLAGS += -march=pentium
# CFLAGS += -march=pentiumpro

# Valid x86 options that work only with newer versions of gcc.
# CFLAGS += -march=pentium-mmx
# CFLAGS += -march=pentium3
# CFLAGS += -march=pentium4
# CFLAGS += -march=k6
# CFLAGS += -march=k6-2
# CFLAGS += -march=k6-3
# CFLAGS += -march=athlon
# CFLAGS += -march=athlon-tbird
# CFLAGS += -march=athlon-xp
# CFLAGS += -march=athlon-mp
# CFLAGS += -march=athlon-4
...
...
# Linux
# Linux用户去掉这行的注释
ARCH = linux

# FreeBSD
# FreeBSD用户去掉这行的注释
# ARCH = freebsd
...
...
# On x86-based OSes, if supported, you can use standard joystick driver.
# Linux用户去掉这行的注释
# JOY_I386 = 1
...
...
# NetBSD/FreeBSD USB joystick support.
# FreeBSD用户去掉这行的注释
# JOY_USB = 1
...
...
# GNOME用户去掉这行的注释以支持esound输出
# SOUND_ESOUND = 1
# SOUND_ALSA = 1
# SOUND_ARTS_TEIRA = 1
# SOUND_ARTS_SMOTEK = 1
# 去掉这行的注释以支持SDL音频输出
# SOUND_SDL = 1
# SOUND_WAVEOUT = 1
...
...
###########################################################################
# Select your display method; choose only one.
###########################################################################
# 选择一种(只允许一种)显示方式,去掉注释符号
# Note: x11 is the only one supported on almost all platforms. For BeOS,
# use SDL.

# X11
# 编译x11版本(xmame.x11)请去掉下一行的注释。如果你的显卡有XV或DGA支持,这是最好的选择
DISPLAY_METHOD = x11

# SDL library
# 编译SDL版本(xmame.SDL)请去掉下一行的注释。要使用SDL游戏杆支持则必须使用这个版本
# DISPLAY_METHOD = SDL

# SVGALib, only supported under Linux
# 编译svgalib版本(xmame.svgalib)请去掉下一行的注释。
# DISPLAY_METHOD = svgalib

# GGI, only tested under Linux
# DISPLAY_METHOD = ggi

# OpenGL under X11
# 编译OpenGL版本(xmame.xgl)请去掉下一行的注释。
# DISPLAY_METHOD = xgl

# Glide under X11
# DISPLAY_METHOD = xfx

# Glide in console mode
# DISPLAY_METHOD = svgafx

# OpenStep bitmaps
# DISPLAY_METHOD = openstep

# Photon 2.x (QNX6), currently buggy, but working...
# DISPLAY_METHOD = photon2
...
...
# MIT-Shared Memory X Extensions
# 使能MIT风格共享内存扩展,不要注释她
X11_MITSHM = 1

# Use Xv extension for hardware scaling.
# 使能Xvideo扩展,不要注释她
X11_XV = 1

# Enable XFree86 DGA. This also causes "make install" to set the suid bit
# on the executable.
# 使能DGA扩展支持,如果你可能需要使用DGA方式(当XV不可用时)的话,去掉这行的注释
# X11_DGA = 1

# Work around a bug in the XFree86 tdfx driver that prevents the original
# mode from being restored when leaving DGA2 mode.
# 我没有3dfx卡,3fdx用户试试吧
# TDFX_DGA_WORKAROUND = 1

# The XIL library (Solaris 2.5.1 and higher)
# Solaris 9 Sparc 宣称这个库被废弃了。
# X11_XIL = 1
...
...
# Uncomment this to use XInput devices, e.g. additional mice as
# trackballs.
# 如果你要玩双打枪战游戏(Space Gun,etc),去掉这行注释,这使XMAME能够接受X-WINDOW下第二鼠标的输入
# XINPUT_DEVICES = 1
...
...
# The name of your sdl-config executable
# FreeBSD用户可能要把"sdl-config"改成"sdl11-config"
SDL_CONFIG = sdl-config
回复

使用道具 举报

发表于 2004-4-2 10:14:41 | 显示全部楼层
哦,研究挺透彻啊
知道NEOGEO.C里各个ROM文件后的SHA(XXXXXXXX)是什么东西么?
回复

使用道具 举报

发表于 2004-11-11 14:18:37 | 显示全部楼层
偶的打开了network支持,编译成XGL的时候却说network.c中有未定义的东西,是以
IPF_ 开头的....
怎么回事?
回复

使用道具 举报

发表于 2004-11-12 22:13:57 | 显示全部楼层
没人知道否?
回复

使用道具 举报

发表于 2004-11-12 22:51:50 | 显示全部楼层
xmame的新版里net支持好像broken了。
回复

使用道具 举报

发表于 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
回复

使用道具 举报

发表于 2004-11-13 13:50:14 | 显示全部楼层
好久不玩xmame了,我以前在linuxsir发过一张帖子是关于网络玩的,你搜索fog_proxy的发贴就能找到了.不过老实说,我当初玩也就是两个人连比较顺畅点,如果4个人的话经常会连不起来,也许老美的改法有参照价值,不过现在也懒的看了.
回复

使用道具 举报

发表于 2004-11-13 18:26:47 | 显示全部楼层
多谢。。
英雄无敌III 在哪儿有下的。。公社的那个下得太慢了。。。
回复

使用道具 举报

发表于 2004-11-20 23:14:53 | 显示全部楼层
不会吧,我下起来还不错~~:),下了两次了,(有次是不小心删了 )
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-2 14:24 , Processed in 0.048003 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表