doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

commit 73424b6129f1c3ca9fc22aedcfe1f5330db137a9
parent 4eb368a960647c8cc82d721d0183629ae10759d1
Author: Travis Bradshaw <travis.bradshaw@idsoftware.com>
Date:   Tue, 31 Jan 2012 15:32:25 -0600

Adding the release of the DOOM IPX driver.

Diffstat:
Aipx/DOOMNET.C | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aipx/DOOMNET.H | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aipx/IPXNET.C | 294+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aipx/IPXNET.H | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aipx/IPXSETUP.C | 420+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aipx/IPXSTR.H | 19+++++++++++++++++++
Aipx/IPX_FRCH.H | 21+++++++++++++++++++++
Aipx/README | 1+
8 files changed, 1003 insertions(+), 0 deletions(-)

diff --git a/ipx/DOOMNET.C b/ipx/DOOMNET.C @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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" + diff --git a/ipx/README b/ipx/README @@ -0,0 +1 @@ +This is the source for the DOOM ipx network driver.