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