Adding the release of the DOOM IPX driver.
authorTravis Bradshaw <travis.bradshaw@idsoftware.com>
Tue, 31 Jan 2012 21:32:25 +0000 (15:32 -0600)
committerTravis Bradshaw <travis.bradshaw@idsoftware.com>
Tue, 31 Jan 2012 21:32:25 +0000 (15:32 -0600)
ipx/DOOMNET.C [new file with mode: 0644]
ipx/DOOMNET.H [new file with mode: 0644]
ipx/IPXNET.C [new file with mode: 0644]
ipx/IPXNET.H [new file with mode: 0644]
ipx/IPXSETUP.C [new file with mode: 0644]
ipx/IPXSTR.H [new file with mode: 0644]
ipx/IPX_FRCH.H [new file with mode: 0644]
ipx/README [new file with mode: 0644]

diff --git a/ipx/DOOMNET.C b/ipx/DOOMNET.C
new file mode 100644 (file)
index 0000000..0f9c55b
--- /dev/null
@@ -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
+}
diff --git a/ipx/DOOMNET.H b/ipx/DOOMNET.H
new file mode 100644 (file)
index 0000000..f0319d9
--- /dev/null
@@ -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);
+
diff --git a/ipx/IPXNET.C b/ipx/IPXNET.C
new file mode 100644 (file)
index 0000000..f2fa935
--- /dev/null
@@ -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;
+}
+
diff --git a/ipx/IPXNET.H b/ipx/IPXNET.H
new file mode 100644 (file)
index 0000000..2c5e14d
--- /dev/null
@@ -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);
+
diff --git a/ipx/IPXSETUP.C b/ipx/IPXSETUP.C
new file mode 100644 (file)
index 0000000..c5f3099
--- /dev/null
@@ -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);
+        }
+
+
diff --git a/ipx/IPXSTR.H b/ipx/IPXSTR.H
new file mode 100644 (file)
index 0000000..ac2995a
--- /dev/null
@@ -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"
diff --git a/ipx/IPX_FRCH.H b/ipx/IPX_FRCH.H
new file mode 100644 (file)
index 0000000..6178eea
--- /dev/null
@@ -0,0 +1,21 @@
+#define STR_NETABORT   "Synchronisation du jeu sur r\82seau annul\82e."
+#define STR_UNKNOWN    "Paquet de jeu inconnu durant la configuration"
+#define STR_FOUND              "Noeud d\82tect\82!"
+#define STR_LOOKING            "Recherche d'un noeud"
+#define STR_MORETHAN   "Plus de %i joueurs sp\82cifi\82s!"
+#define STR_NONESPEC   "Pas de joueurs sp\82cifi\82s pour le jeu!"
+#define STR_CONSOLEIS  "Console: joueur %i sur %i"
+#define STR_NORESP             "Ce fichier de r\82ponse n'existe pas!"
+#define STR_FOUNDRESP   "Fichier de r\82ponse trouv\82"
+#define STR_DOOMNETDRV "GESTIONNAIRE DE RESEAU DOOM II"
+#define STR_VECTSPEC   "Le vecteur sp\82cifi\82 (0x%02x) \82tait d\82j\85 connect\82."
+#define STR_NONULL     \
+"Attention: pas de vecteurs d'interruption NULL ou iret trouv\82s entre 0x60 et 0x66.\n"\
+"Vous pouvez sp\82cifier un vecteur avec le param\8atre -vector 0x<num\82ro>."
+#define STR_COMMVECT   "Communication avec le vecteur d'interruption 0x%x"
+#define STR_USEALT             "Utilisation du port alternatif %i pour le r\82seau"
+#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"
+
diff --git a/ipx/README b/ipx/README
new file mode 100644 (file)
index 0000000..d96a75b
--- /dev/null
@@ -0,0 +1 @@
+This is the source for the DOOM ipx network driver.