Adding the release of the DOOM IPX driver.
This commit is contained in:
parent
4eb368a960
commit
73424b6129
73
ipx/DOOMNET.C
Normal file
73
ipx/DOOMNET.C
Normal file
@ -0,0 +1,73 @@
|
||||
//#define DOOM2
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
|
||||
#include "doomnet.h"
|
||||
//#include "ipxstr.h"
|
||||
#include "ipx_frch.h" // FRENCH VERSION
|
||||
|
||||
doomcom_t doomcom;
|
||||
int vectorishooked;
|
||||
void interrupt (*olddoomvect) (void);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
=
|
||||
= LaunchDOOM
|
||||
=
|
||||
These fields in doomcom should be filled in before calling:
|
||||
|
||||
short numnodes; // console is allways node 0
|
||||
short ticdup; // 1 = no duplication, 2-5 = dup for
|
||||
slow nets
|
||||
short extratics; // 1 = send a backup tic in every
|
||||
packet
|
||||
|
||||
short consoleplayer; // 0-3 = player number
|
||||
short numplayers; // 1-4
|
||||
short angleoffset; // 1 = left, 0 = center, -1 = right
|
||||
short drone; // 1 = drone
|
||||
=============
|
||||
*/
|
||||
|
||||
void LaunchDOOM (void)
|
||||
{
|
||||
char *newargs[99];
|
||||
char adrstring[10];
|
||||
long flatadr;
|
||||
|
||||
// prepare for DOOM
|
||||
doomcom.id = DOOMCOM_ID;
|
||||
|
||||
// hook the interrupt vector
|
||||
olddoomvect = getvect (doomcom.intnum);
|
||||
setvect (doomcom.intnum,(void interrupt (*)(void))MK_FP(_CS,
|
||||
(int)NetISR));
|
||||
vectorishooked = 1;
|
||||
|
||||
// build the argument list for DOOM, adding a -net &doomcom
|
||||
memcpy (newargs, _argv, (_argc+1)*2);
|
||||
newargs[_argc] = "-net";
|
||||
flatadr = (long)_DS*16 + (unsigned)&doomcom;
|
||||
sprintf (adrstring,"%lu",flatadr);
|
||||
newargs[_argc+1] = adrstring;
|
||||
newargs[_argc+2] = NULL;
|
||||
|
||||
if (!access("doom2.exe",0))
|
||||
spawnv (P_WAIT, "doom2", newargs);
|
||||
else
|
||||
spawnv (P_WAIT, "doom", newargs);
|
||||
|
||||
#ifdef DOOM2
|
||||
printf (STR_RETURNED"\n");
|
||||
#else
|
||||
printf ("Returned from DOOM\n");
|
||||
#endif
|
||||
}
|
58
ipx/DOOMNET.H
Normal file
58
ipx/DOOMNET.H
Normal file
@ -0,0 +1,58 @@
|
||||
// doomnet.h
|
||||
|
||||
#define PEL_WRITE_ADR 0x3c8
|
||||
#define PEL_DATA 0x3c9
|
||||
|
||||
#define I_ColorBlack(r,g,b) {outp(PEL_WRITE_ADR,0);outp(PEL_DATA,r);outp(PEL_DATA,g);outp(PEL_DATA,b);};
|
||||
|
||||
|
||||
|
||||
#define MAXNETNODES 8 // max computers in a game
|
||||
#define MAXPLAYERS 4 // 4 players max + drones
|
||||
|
||||
|
||||
#define CMD_SEND 1
|
||||
#define CMD_GET 2
|
||||
|
||||
#define DOOMCOM_ID 0x12345678l
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long id;
|
||||
short intnum; // DOOM executes an int to send commands
|
||||
|
||||
// communication between DOOM and the driver
|
||||
short command; // CMD_SEND or CMD_GET
|
||||
short remotenode; // dest for send, set by get (-1 = no packet)
|
||||
short datalength; // bytes in doomdata to be sent / bytes read
|
||||
|
||||
// info common to all nodes
|
||||
short numnodes; // console is allways node 0
|
||||
short ticdup; // 1 = no duplication, 2-5 = dup for slow nets
|
||||
short extratics; // 1 = send a backup tic in every packet
|
||||
short deathmatch; // 1 = deathmatch
|
||||
short savegame; // -1 = new game, 0-5 = load savegame
|
||||
short episode; // 1-3
|
||||
short map; // 1-9
|
||||
short skill; // 1-5
|
||||
|
||||
// info specific to this node
|
||||
short consoleplayer; // 0-3 = player number
|
||||
short numplayers; // 1-4
|
||||
short angleoffset; // 1 = left, 0 = center, -1 = right
|
||||
short drone; // 1 = drone
|
||||
|
||||
// packet data to be sent
|
||||
char data[512];
|
||||
} doomcom_t;
|
||||
|
||||
|
||||
|
||||
extern doomcom_t doomcom;
|
||||
extern void interrupt (*olddoomvect) (void);
|
||||
extern int vectorishooked;
|
||||
|
||||
int CheckParm (char *check);
|
||||
void LaunchDOOM (void);
|
||||
void interrupt NetISR (void);
|
||||
|
294
ipx/IPXNET.C
Normal file
294
ipx/IPXNET.C
Normal file
@ -0,0 +1,294 @@
|
||||
// ipxnet.c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
#include <values.h>
|
||||
|
||||
#include "ipxnet.h"
|
||||
|
||||
/*
|
||||
==========================================================================
|
||||
===
|
||||
|
||||
IPX PACKET DRIVER
|
||||
|
||||
==========================================================================
|
||||
===
|
||||
*/
|
||||
|
||||
packet_t packets[NUMPACKETS];
|
||||
|
||||
nodeadr_t nodeadr[MAXNETNODES+1]; // first is local, last is broadcast
|
||||
|
||||
nodeadr_t remoteadr; // set by each GetPacket
|
||||
|
||||
localadr_t localadr; // set at startup
|
||||
|
||||
extern int socketid;
|
||||
|
||||
void far (*IPX)(void);
|
||||
|
||||
long localtime; // for time stamp in packets
|
||||
long remotetime;
|
||||
|
||||
//===========================================================================
|
||||
|
||||
int OpenSocket(short socketNumber)
|
||||
{
|
||||
_DX = socketNumber;
|
||||
_BX = 0;
|
||||
_AL = 0;
|
||||
IPX();
|
||||
if(_AL)
|
||||
Error ("OpenSocket: 0x%x", _AL);
|
||||
return _DX;
|
||||
}
|
||||
|
||||
|
||||
void CloseSocket(short socketNumber)
|
||||
{
|
||||
_DX = socketNumber;
|
||||
_BX = 1;
|
||||
IPX();
|
||||
}
|
||||
|
||||
void ListenForPacket(ECB *ecb)
|
||||
{
|
||||
_SI = FP_OFF(ecb);
|
||||
_ES = FP_SEG(ecb);
|
||||
_BX = 4;
|
||||
IPX();
|
||||
if(_AL)
|
||||
Error ("ListenForPacket: 0x%x", _AL);
|
||||
}
|
||||
|
||||
|
||||
void GetLocalAddress (void)
|
||||
{
|
||||
_SI = FP_OFF(&localadr);
|
||||
_ES = FP_SEG(&localadr);
|
||||
_BX = 9;
|
||||
IPX();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= InitNetwork
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
void InitNetwork (void)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
//
|
||||
// get IPX function address
|
||||
//
|
||||
_AX = 0x7a00;
|
||||
geninterrupt(0x2f);
|
||||
if(_AL != 0xff)
|
||||
Error ("IPX not detected\n");
|
||||
IPX = MK_FP(_ES, _DI);
|
||||
|
||||
|
||||
//
|
||||
// allocate a socket for sending and receiving
|
||||
//
|
||||
socketid = OpenSocket ( (socketid>>8) + ((socketid&255)<<8) );
|
||||
|
||||
GetLocalAddress();
|
||||
|
||||
//
|
||||
// set up several receiving ECBs
|
||||
//
|
||||
memset (packets,0,NUMPACKETS*sizeof(packet_t));
|
||||
|
||||
for (i=1 ; i<NUMPACKETS ; i++)
|
||||
{
|
||||
packets[i].ecb.ECBSocket = socketid;
|
||||
packets[i].ecb.FragmentCount = 1;
|
||||
packets[i].ecb.fAddress[0] = FP_OFF(&packets[i].ipx);
|
||||
packets[i].ecb.fAddress[1] = FP_SEG(&packets[i].ipx);
|
||||
packets[i].ecb.fSize = sizeof(packet_t)-sizeof(ECB);
|
||||
|
||||
ListenForPacket (&packets[i].ecb);
|
||||
}
|
||||
|
||||
//
|
||||
// set up a sending ECB
|
||||
//
|
||||
memset (&packets[0],0,sizeof(packets[0]));
|
||||
|
||||
packets[0].ecb.ECBSocket = socketid;
|
||||
packets[0].ecb.FragmentCount = 2;
|
||||
packets[0].ecb.fAddress[0] = FP_OFF(&packets[0].ipx);
|
||||
packets[0].ecb.fAddress[1] = FP_SEG(&packets[0].ipx);
|
||||
for (j=0 ; j<4 ; j++)
|
||||
packets[0].ipx.dNetwork[j] = localadr.network[j];
|
||||
packets[0].ipx.dSocket[0] = socketid&255;
|
||||
packets[0].ipx.dSocket[1] = socketid>>8;
|
||||
packets[0].ecb.f2Address[0] = FP_OFF(&doomcom.data);
|
||||
packets[0].ecb.f2Address[1] = FP_SEG(&doomcom.data);
|
||||
|
||||
// known local node at 0
|
||||
for (i=0 ; i<6 ; i++)
|
||||
nodeadr[0].node[i] = localadr.node[i];
|
||||
|
||||
// broadcast node at MAXNETNODES
|
||||
for (j=0 ; j<6 ; j++)
|
||||
nodeadr[MAXNETNODES].node[j] = 0xff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= ShutdownNetwork
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
void ShutdownNetwork (void)
|
||||
{
|
||||
if (IPX)
|
||||
CloseSocket (socketid);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= SendPacket
|
||||
=
|
||||
= A destination of MAXNETNODES is a broadcast
|
||||
==============
|
||||
*/
|
||||
|
||||
void SendPacket (int destination)
|
||||
{
|
||||
int j;
|
||||
|
||||
// set the time
|
||||
packets[0].time = localtime;
|
||||
|
||||
// set the address
|
||||
for (j=0 ; j<6 ; j++)
|
||||
packets[0].ipx.dNode[j] =
|
||||
packets[0].ecb.ImmediateAddress[j] =
|
||||
nodeadr[destination].node[j];
|
||||
|
||||
// set the length (ipx + time + datalength)
|
||||
packets[0].ecb.fSize = sizeof(IPXPacket) + 4;
|
||||
packets[0].ecb.f2Size = doomcom.datalength + 4;
|
||||
|
||||
// send the packet
|
||||
_SI = FP_OFF(&packets[0]);
|
||||
_ES = FP_SEG(&packets[0]);
|
||||
_BX = 3;
|
||||
IPX();
|
||||
if(_AL)
|
||||
Error("SendPacket: 0x%x", _AL);
|
||||
|
||||
while(packets[0].ecb.InUseFlag != 0)
|
||||
{
|
||||
// IPX Relinquish Control - polled drivers MUST have this here!
|
||||
_BX = 10;
|
||||
IPX();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned short ShortSwap (unsigned short i)
|
||||
{
|
||||
return ((i&255)<<8) + ((i>>8)&255);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= GetPacket
|
||||
=
|
||||
= Returns false if no packet is waiting
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
int GetPacket (void)
|
||||
{
|
||||
int packetnum;
|
||||
int i, j;
|
||||
long besttic;
|
||||
packet_t *packet;
|
||||
|
||||
// if multiple packets are waiting, return them in order by time
|
||||
|
||||
besttic = MAXLONG;
|
||||
packetnum = -1;
|
||||
doomcom.remotenode = -1;
|
||||
|
||||
for ( i = 1 ; i < NUMPACKETS ; i++)
|
||||
{
|
||||
if (packets[i].ecb.InUseFlag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (packets[i].time < besttic)
|
||||
{
|
||||
besttic = packets[i].time;
|
||||
packetnum = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (besttic == MAXLONG)
|
||||
return 0; // no packets
|
||||
|
||||
packet = &packets[packetnum];
|
||||
|
||||
if (besttic == -1 && localtime != -1)
|
||||
{
|
||||
ListenForPacket (&packet->ecb);
|
||||
return 0; // setup broadcast from other game
|
||||
}
|
||||
|
||||
remotetime = besttic;
|
||||
|
||||
//
|
||||
// got a good packet
|
||||
//
|
||||
if (packet->ecb.CompletionCode)
|
||||
Error ("GetPacket: ecb.ComletionCode = 0x%x",packet->ecb.CompletionCode);
|
||||
|
||||
// set remoteadr to the sender of the packet
|
||||
memcpy (&remoteadr, packet->ipx.sNode, sizeof(remoteadr));
|
||||
for (i=0 ; i<doomcom.numnodes ; i++)
|
||||
if (!memcmp(&remoteadr, &nodeadr[i], sizeof(remoteadr)))
|
||||
break;
|
||||
if (i < doomcom.numnodes)
|
||||
doomcom.remotenode = i;
|
||||
else
|
||||
{
|
||||
if (localtime != -1)
|
||||
{ // this really shouldn't happen
|
||||
ListenForPacket (&packet->ecb);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// copy out the data
|
||||
doomcom.datalength = ShortSwap(packet->ipx.PacketLength) - 38;
|
||||
memcpy (&doomcom.data, &packet->data, doomcom.datalength);
|
||||
|
||||
// repost the ECB
|
||||
ListenForPacket (&packet->ecb);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
117
ipx/IPXNET.H
Normal file
117
ipx/IPXNET.H
Normal file
@ -0,0 +1,117 @@
|
||||
// ipxnet.h
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char private[512];
|
||||
} doomdata_t;
|
||||
|
||||
|
||||
#include "DoomNet.h"
|
||||
|
||||
//===========================================================================
|
||||
|
||||
#define NUMPACKETS 10 // max outstanding packets before loss
|
||||
|
||||
// setupdata_t is used as doomdata_t during setup
|
||||
typedef struct
|
||||
{
|
||||
short gameid; // so multiple games can setup at once
|
||||
short drone;
|
||||
short nodesfound;
|
||||
short nodeswanted;
|
||||
} setupdata_t;
|
||||
|
||||
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long LONG;
|
||||
|
||||
typedef struct IPXPacketStructure
|
||||
{
|
||||
WORD PacketCheckSum; /* high-low */
|
||||
WORD PacketLength; /* high-low */
|
||||
BYTE PacketTransportControl;
|
||||
BYTE PacketType;
|
||||
|
||||
BYTE dNetwork[4]; /* high-low */
|
||||
BYTE dNode[6]; /* high-low */
|
||||
BYTE dSocket[2]; /* high-low */
|
||||
|
||||
BYTE sNetwork[4]; /* high-low */
|
||||
BYTE sNode[6]; /* high-low */
|
||||
BYTE sSocket[2]; /* high-low */
|
||||
} IPXPacket;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE network[4]; /* high-low */
|
||||
BYTE node[6]; /* high-low */
|
||||
} localadr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE node[6]; /* high-low */
|
||||
} nodeadr_t;
|
||||
|
||||
typedef struct ECBStructure
|
||||
{
|
||||
WORD Link[2]; /* offset-segment */
|
||||
WORD ESRAddress[2]; /* offset-segment */
|
||||
BYTE InUseFlag;
|
||||
BYTE CompletionCode;
|
||||
WORD ECBSocket; /* high-low */
|
||||
BYTE IPXWorkspace[4]; /* N/A */
|
||||
BYTE DriverWorkspace[12]; /* N/A */
|
||||
BYTE ImmediateAddress[6]; /* high-low */
|
||||
WORD FragmentCount; /* low-high */
|
||||
|
||||
WORD fAddress[2]; /* offset-segment */
|
||||
WORD fSize; /* low-high */
|
||||
|
||||
WORD f2Address[2]; /* offset-segment */
|
||||
WORD f2Size; /* low-high */
|
||||
} ECB;
|
||||
|
||||
|
||||
// time is used by the communication driver to sequence packets returned
|
||||
// to DOOM when more than one is waiting
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ECB ecb;
|
||||
IPXPacket ipx;
|
||||
|
||||
long time;
|
||||
doomdata_t data;
|
||||
} packet_t;
|
||||
|
||||
|
||||
extern doomcom_t doomcom;
|
||||
extern int gameid;
|
||||
|
||||
extern nodeadr_t nodeadr[MAXNETNODES+1];
|
||||
extern int localnodenum;
|
||||
|
||||
extern long localtime; // for time stamp in packets
|
||||
extern long remotetime; // timestamp of last packet gotten
|
||||
|
||||
extern nodeadr_t remoteadr;
|
||||
|
||||
extern int myargc;
|
||||
|
||||
extern char **myargv;
|
||||
|
||||
void Error (char *error, ...);
|
||||
|
||||
|
||||
void InitNetwork (void);
|
||||
void ShutdownNetwork (void);
|
||||
void SendPacket (int destination);
|
||||
int GetPacket (void);
|
||||
int CheckParm (char *check);
|
||||
|
||||
void PrintAddress (nodeadr_t *adr, char *str);
|
||||
|
420
ipx/IPXSETUP.C
Normal file
420
ipx/IPXSETUP.C
Normal file
@ -0,0 +1,420 @@
|
||||
// ipxsetup.c
|
||||
|
||||
#define DOOM2
|
||||
|
||||
#include <conio.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
#include <stdarg.h>
|
||||
#include <bios.h>
|
||||
|
||||
#include "ipxnet.h"
|
||||
//#include "ipxstr.h"
|
||||
#include "ipx_frch.h" // FRENCH VERSION
|
||||
|
||||
int gameid;
|
||||
int numnetnodes;
|
||||
int socketid = 0x869c; // 0x869c is the official DOOM socket
|
||||
int myargc;
|
||||
char **myargv;
|
||||
|
||||
setupdata_t nodesetup[MAXNETNODES];
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= Error
|
||||
=
|
||||
= For abnormal program terminations
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void Error (char *error, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
if (vectorishooked)
|
||||
setvect (doomcom.intnum,olddoomvect);
|
||||
|
||||
va_start (argptr,error);
|
||||
vprintf (error,argptr);
|
||||
va_end (argptr);
|
||||
printf ("\n");
|
||||
ShutdownNetwork ();
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= CheckParm
|
||||
=
|
||||
= Checks for the given parameter in the program's command line arguments
|
||||
=
|
||||
= Returns the argument number (1 to argc-1) or 0 if not present
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
int CheckParm(char *parm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 1; i < myargc; i++)
|
||||
if(stricmp(parm, myargv[i]) == 0)
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
=
|
||||
= NetISR
|
||||
=
|
||||
=============
|
||||
*/
|
||||
|
||||
void interrupt NetISR (void)
|
||||
{
|
||||
if (doomcom.command == CMD_SEND)
|
||||
{
|
||||
localtime++;
|
||||
SendPacket (doomcom.remotenode);
|
||||
}
|
||||
else if (doomcom.command == CMD_GET)
|
||||
{
|
||||
GetPacket ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= LookForNodes
|
||||
=
|
||||
= Finds all the nodes for the game and works out player numbers among
|
||||
them
|
||||
=
|
||||
= Exits with nodesetup[0..numnodes] and nodeadr[0..numnodes] filled in
|
||||
===================
|
||||
*/
|
||||
|
||||
void LookForNodes (void)
|
||||
{
|
||||
int i,j,k;
|
||||
int netids[MAXNETNODES];
|
||||
int netplayer[MAXNETNODES];
|
||||
struct time time;
|
||||
int oldsec;
|
||||
setupdata_t *setup, *dest;
|
||||
char str[80];
|
||||
int total, console;
|
||||
|
||||
//
|
||||
// wait until we get [numnetnodes] packets, then start playing
|
||||
// the playernumbers are assigned by netid
|
||||
//
|
||||
printf(STR_ATTEMPT, numnetnodes);
|
||||
|
||||
printf (STR_LOOKING);
|
||||
|
||||
oldsec = -1;
|
||||
setup = (setupdata_t *)&doomcom.data;
|
||||
localtime = -1; // in setup time, not game time
|
||||
|
||||
//
|
||||
// build local setup info
|
||||
//
|
||||
nodesetup[0].nodesfound = 1;
|
||||
nodesetup[0].nodeswanted = numnetnodes;
|
||||
doomcom.numnodes = 1;
|
||||
|
||||
do
|
||||
{
|
||||
//
|
||||
// check for aborting
|
||||
//
|
||||
while ( bioskey(1) )
|
||||
{
|
||||
if ( (bioskey (0) & 0xff) == 27)
|
||||
Error ("\n\n"STR_NETABORT);
|
||||
}
|
||||
|
||||
//
|
||||
// listen to the network
|
||||
//
|
||||
while (GetPacket ())
|
||||
{
|
||||
if (doomcom.remotenode == -1)
|
||||
dest = &nodesetup[doomcom.numnodes];
|
||||
else
|
||||
dest = &nodesetup[doomcom.remotenode];
|
||||
|
||||
if (remotetime != -1)
|
||||
{ // an early game packet, not a setup packet
|
||||
if (doomcom.remotenode == -1)
|
||||
Error (STR_UNKNOWN);
|
||||
// if it allready started, it must have found all nodes
|
||||
dest->nodesfound = dest->nodeswanted;
|
||||
continue;
|
||||
}
|
||||
|
||||
// update setup ingo
|
||||
memcpy (dest, setup, sizeof(*dest) );
|
||||
|
||||
if (doomcom.remotenode != -1)
|
||||
continue; // allready know that node address
|
||||
|
||||
//
|
||||
// this is a new node
|
||||
//
|
||||
memcpy (&nodeadr[doomcom.numnodes], &remoteadr
|
||||
, sizeof(nodeadr[doomcom.numnodes]) );
|
||||
|
||||
//
|
||||
// if this node has a lower address, take all startup info
|
||||
//
|
||||
if ( memcmp (&remoteadr, &nodeadr[0], sizeof(&remoteadr) )
|
||||
< 0 )
|
||||
{
|
||||
}
|
||||
|
||||
doomcom.numnodes++;
|
||||
|
||||
printf ("\n"STR_FOUND"\n");
|
||||
|
||||
if (doomcom.numnodes < numnetnodes)
|
||||
printf (STR_LOOKING);
|
||||
}
|
||||
//
|
||||
// we are done if all nodes have found all other nodes
|
||||
//
|
||||
for (i=0 ; i<doomcom.numnodes ; i++)
|
||||
if (nodesetup[i].nodesfound != nodesetup[i].nodeswanted)
|
||||
break;
|
||||
|
||||
if (i == nodesetup[0].nodeswanted)
|
||||
break; // got them all
|
||||
|
||||
//
|
||||
// send out a broadcast packet every second
|
||||
//
|
||||
gettime (&time);
|
||||
if (time.ti_sec == oldsec)
|
||||
continue;
|
||||
oldsec = time.ti_sec;
|
||||
|
||||
printf (".");
|
||||
doomcom.datalength = sizeof(*setup);
|
||||
|
||||
nodesetup[0].nodesfound = doomcom.numnodes;
|
||||
|
||||
memcpy (&doomcom.data, &nodesetup[0], sizeof(*setup));
|
||||
|
||||
SendPacket (MAXNETNODES); // send to all
|
||||
|
||||
} while (1);
|
||||
|
||||
//
|
||||
// count players
|
||||
//
|
||||
total = 0;
|
||||
console = 0;
|
||||
|
||||
for (i=0 ; i<numnetnodes ; i++)
|
||||
{
|
||||
if (nodesetup[i].drone)
|
||||
continue;
|
||||
total++;
|
||||
if (total > MAXPLAYERS)
|
||||
Error (STR_MORETHAN,MAXPLAYERS);
|
||||
if (memcmp (&nodeadr[i], &nodeadr[0], sizeof(nodeadr[0])) < 0)
|
||||
console++;
|
||||
}
|
||||
|
||||
|
||||
if (!total)
|
||||
Error (STR_NONESPEC);
|
||||
|
||||
doomcom.consoleplayer = console;
|
||||
doomcom.numplayers = total;
|
||||
|
||||
printf (STR_CONSOLEIS"\n", console+1, total);
|
||||
}
|
||||
|
||||
|
||||
//========================================================
|
||||
//
|
||||
// Find a Response File
|
||||
//
|
||||
//========================================================
|
||||
void FindResponseFile (void)
|
||||
{
|
||||
int i;
|
||||
#define MAXARGVS 100
|
||||
|
||||
for (i = 1;i < myargc;i++)
|
||||
if (myargv[i][0] == '@')
|
||||
{
|
||||
FILE * handle;
|
||||
int size;
|
||||
int k;
|
||||
int index;
|
||||
int indexinfile;
|
||||
char *infile;
|
||||
char *file;
|
||||
char *moreargs[20];
|
||||
char *firstargv;
|
||||
|
||||
// READ THE RESPONSE FILE INTO MEMORY
|
||||
handle = fopen (&myargv[i][1],"rb");
|
||||
if (!handle)
|
||||
Error (STR_NORESP);
|
||||
printf(STR_FOUNDRESP" \"%s\"!\n",strupr(&myargv[i][1]));
|
||||
fseek (handle,0,SEEK_END);
|
||||
size = ftell(handle);
|
||||
fseek (handle,0,SEEK_SET);
|
||||
file = malloc (size);
|
||||
fread (file,size,1,handle);
|
||||
fclose (handle);
|
||||
|
||||
// KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
|
||||
for (index = 0,k = i+1; k < myargc; k++)
|
||||
moreargs[index++] = myargv[k];
|
||||
|
||||
firstargv = myargv[0];
|
||||
myargv = malloc(sizeof(char *)*MAXARGVS);
|
||||
memset(myargv,0,sizeof(char *)*MAXARGVS);
|
||||
myargv[0] = firstargv;
|
||||
|
||||
infile = file;
|
||||
indexinfile = k = 0;
|
||||
indexinfile++; // SKIP PAST ARGV[0] (KEEP IT)
|
||||
do
|
||||
{
|
||||
myargv[indexinfile++] = infile+k;
|
||||
while(k < size &&
|
||||
((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
|
||||
k++;
|
||||
*(infile+k) = 0;
|
||||
while(k < size &&
|
||||
((*(infile+k)<= ' ') || (*(infile+k)>'z')))
|
||||
k++;
|
||||
} while(k < size);
|
||||
|
||||
for (k = 0;k < index;k++)
|
||||
myargv[indexinfile++] = moreargs[k];
|
||||
myargc = indexinfile;
|
||||
|
||||
// DISPLAY ARGS
|
||||
// printf("%d command-line args:\n",myargc);
|
||||
// for (k=1;k<myargc;k++)
|
||||
// printf("%s\n",myargv[k]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
=
|
||||
= main
|
||||
=
|
||||
=============
|
||||
*/
|
||||
|
||||
void main (void)
|
||||
{
|
||||
int i;
|
||||
unsigned char far *vector;
|
||||
|
||||
//
|
||||
// determine game parameters
|
||||
//
|
||||
gameid = 0;
|
||||
numnetnodes = 2;
|
||||
doomcom.ticdup = 1;
|
||||
doomcom.extratics = 1;
|
||||
doomcom.episode = 1;
|
||||
doomcom.map = 1;
|
||||
doomcom.skill = 2;
|
||||
doomcom.deathmatch = 0;
|
||||
|
||||
printf("\n"
|
||||
"-----------------------------\n"
|
||||
#ifdef DOOM2
|
||||
STR_DOOMNETDRV"\n"
|
||||
#else
|
||||
"DOOM NETWORK DEVICE DRIVER\n"
|
||||
#endif
|
||||
"v1.22\n"
|
||||
"-----------------------------\n");
|
||||
|
||||
myargc = _argc;
|
||||
myargv = _argv;
|
||||
FindResponseFile();
|
||||
|
||||
if((i = CheckParm("-nodes")) != 0)
|
||||
numnetnodes = atoi(myargv[i+1]);
|
||||
|
||||
if((i = CheckParm("-vector")) != 0)
|
||||
{
|
||||
doomcom.intnum = sscanf ("0x%x",myargv[i+1]);
|
||||
vector = *(char far * far *)(doomcom.intnum*4);
|
||||
if(vector != NULL && *vector != 0xcf)
|
||||
{
|
||||
printf(STR_VECTSPEC"\n", doomcom.intnum);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(doomcom.intnum = 0x60 ; doomcom.intnum <= 0x66 ;
|
||||
doomcom.intnum++)
|
||||
{
|
||||
vector = *(char far * far *)(doomcom.intnum*4);
|
||||
if(vector == NULL || *vector == 0xcf)
|
||||
break;
|
||||
}
|
||||
if(doomcom.intnum == 0x67)
|
||||
{
|
||||
printf(STR_NONULL"\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
printf(STR_COMMVECT"\n",doomcom.intnum);
|
||||
|
||||
if((i = CheckParm("-port")) != 0)
|
||||
{
|
||||
socketid = atoi (myargv[i+1]);
|
||||
printf (STR_USEALT"\n", socketid);
|
||||
}
|
||||
|
||||
InitNetwork ();
|
||||
|
||||
LookForNodes ();
|
||||
|
||||
localtime = 0;
|
||||
|
||||
LaunchDOOM ();
|
||||
|
||||
ShutdownNetwork ();
|
||||
|
||||
if (vectorishooked)
|
||||
setvect (doomcom.intnum,olddoomvect);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
19
ipx/IPXSTR.H
Normal file
19
ipx/IPXSTR.H
Normal file
@ -0,0 +1,19 @@
|
||||
#define STR_NETABORT "Network game synchronization aborted."
|
||||
#define STR_UNKNOWN "Got an unknown game packet during setup"
|
||||
#define STR_FOUND "Found a node!"
|
||||
#define STR_LOOKING "Looking for a node"
|
||||
#define STR_MORETHAN "More than %i players specified!"
|
||||
#define STR_NONESPEC "No players specified for game!"
|
||||
#define STR_CONSOLEIS "Console is player %i of %i"
|
||||
#define STR_NORESP "No such response file!"
|
||||
#define STR_FOUNDRESP "Found response file"
|
||||
#define STR_DOOMNETDRV "DOOM II NETWORK DEVICE DRIVER"
|
||||
#define STR_VECTSPEC "The specified vector (0x%02x) was already hooked."
|
||||
#define STR_NONULL \
|
||||
"Warning: no NULL or iret interrupt vectors were found in the 0x60 to 0x66\n"\
|
||||
"range. You can specify a vector with the -vector 0x<num> parameter."
|
||||
#define STR_COMMVECT "Communicating with interrupt vector 0x%x"
|
||||
#define STR_USEALT "Using alternate port %i for network"
|
||||
#define STR_RETURNED "Returned from DOOM II"
|
||||
#define STR_ATTEMPT "Attempting to find all players for %i player net play. "\
|
||||
"Press ESC to exit.\n"
|
21
ipx/IPX_FRCH.H
Normal file
21
ipx/IPX_FRCH.H
Normal file
@ -0,0 +1,21 @@
|
||||
#define STR_NETABORT "Synchronisation du jeu sur r‚seau annul‚e."
|
||||
#define STR_UNKNOWN "Paquet de jeu inconnu durant la configuration"
|
||||
#define STR_FOUND "Noeud d‚tect‚!"
|
||||
#define STR_LOOKING "Recherche d'un noeud"
|
||||
#define STR_MORETHAN "Plus de %i joueurs sp‚cifi‚s!"
|
||||
#define STR_NONESPEC "Pas de joueurs sp‚cifi‚s pour le jeu!"
|
||||
#define STR_CONSOLEIS "Console: joueur %i sur %i"
|
||||
#define STR_NORESP "Ce fichier de r‚ponse n'existe pas!"
|
||||
#define STR_FOUNDRESP "Fichier de r‚ponse trouv‚"
|
||||
#define STR_DOOMNETDRV "GESTIONNAIRE DE RESEAU DOOM II"
|
||||
#define STR_VECTSPEC "Le vecteur sp‚cifi‚ (0x%02x) ‚tait d‚j… connect‚."
|
||||
#define STR_NONULL \
|
||||
"Attention: pas de vecteurs d'interruption NULL ou iret trouv‚s entre 0x60 et 0x66.\n"\
|
||||
"Vous pouvez sp‚cifier un vecteur avec le paramŠtre -vector 0x<num‚ro>."
|
||||
#define STR_COMMVECT "Communication avec le vecteur d'interruption 0x%x"
|
||||
#define STR_USEALT "Utilisation du port alternatif %i pour le r‚seau"
|
||||
#define STR_RETURNED "Retour de DOOM II"
|
||||
#define STR_ATTEMPT \
|
||||
"Tentatative de recherche de tous les joueurs pour le jeu en riseau `%i jouers\n" \
|
||||
"Appuyez sur ECHAP pour quitter.\n"
|
||||
|
1
ipx/README
Normal file
1
ipx/README
Normal file
@ -0,0 +1 @@
|
||||
This is the source for the DOOM ipx network driver.
|
Loading…
x
Reference in New Issue
Block a user