rott/rottcom/ROTTIPX/IPXSETUP.C
2002-12-25 00:00:00 +00:00

616 lines
17 KiB
C

/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// ipxsetup.c
#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 <time.h>
#include "..\rottnet.h"
#include "ipxnet.h"
#define VERSION "1.3"
int numnetnodes;
unsigned socketid = 0x882a; // 0x882a is the official ROTT socket
int myargc;
char **myargv;
boolean server;
boolean standalone;
boolean master;
setupdata_t nodesetup;
#define MAXNETMESSAGES 25
static int messagesused;
static boolean StringUsed[MAXNETMESSAGES];
static char * NetStrings[MAXNETMESSAGES]=
{
{"\nUm, I'm sure Player %d will join us soon.\n"},
{"\nPlayer %d is starting to tick me off.\n"},
{"\nIt seems Player %d has gone for a Moon Pie.\n"},
{"\nHow long can Player %d take setting the dang thing up?\n"},
{"\nPlayer %d...where are you?\n"},
{"\nSigh. Player %d is a toadie.\n"},
{"\nGo give Player %d a good swift kick in the...head.\n"},
{"\nIs Player %d running off a removable drive or something?\n"},
{"\nPlayer %d is a popo-head.\n"},
{"\nPlayer %d is attempting to escape off the map.\n"},
{"\nPLAYER %d!!!! GOON!\n"},
{"\nYou know, waiting for Player %d reminds me of a story....\n"},
{"\nTwo Player %d's walk into a bar....\n"},
{"\nHow many Player %d's does it take to change a lightbulb?\n"
"None, 'cause they don't DO anything. They just SIT there.\n"},
{"\nANY TIME NOW PLAYER %d!!!\n"},
{"\nI hear Player %d sucks dog's toes.\n"},
{"\nWho votes that Player %d gets left outta this game (y/n)?\n"},
{"\nLunch break's over, Player %d!\n"},
{"\nWe're all waiting, Player %d.... Hello, McFly!!!\n"},
{"\nNumber %d Player, our Number 1 delayer....\n"},
{"\nINSTRUCTIONS: Player %d runs the setup program....\n"},
{"\nOnce Player %d deigns to join us, let's toast 'em.\n"},
{"\nPssst...If you go wake up Player %d, I'll put you in God mode.\n"},
{"\nOkay, when we start, I'm giving Player %d only 5 hit points.\n"},
{"\nIs Player %d in Shrooms Mode or what?\n"}
};
/*
=============
=
= NetISR
=
=============
*/
void NetISR (void)
{
if (rottcom.command == CMD_SEND)
{
ipxlocaltime++;
SendPacket (rottcom.remotenode);
}
else if (rottcom.command == CMD_GET)
{
GetPacket ();
}
}
/*
=================
=
= Shutdown
=
=================
*/
void Shutdown ( void )
{
ShutdownROTTCOM ();
ShutdownNetwork();
}
/*
===================
=
= SetupRandomMessages
=
===================
*/
void SetupRandomMessages ( void )
{
messagesused=0;
memset(StringUsed,0,sizeof(StringUsed));
randomize();
}
/*
===================
=
= PrintRandomMessage
=
===================
*/
void PrintRandomMessage (int message, int player)
{
printf(NetStrings[message],player);
}
/*
===================
=
= GetRandomMessage
=
===================
*/
int GetRandomMessage ( void )
{
boolean found=false;
int num;
if (messagesused==MAXNETMESSAGES)
SetupRandomMessages();
while (found==false)
{
num = random(MAXNETMESSAGES);
if (StringUsed[num]==false)
{
StringUsed[num]=true;
found=true;
messagesused++;
}
}
return num;
}
#define client_NoResponse 0
#define client_Echoed 1
#define client_Done 2
int playernumber;
int clientstate[MAXNETNODES+1];
/*
===================
=
= ResetNodeAddresses
=
= Finds all the nodes for the game and works out player numbers among them
=
===================
*/
void ResetNodeAddresses ( void )
{
int i;
// Zero out client state structure
playernumber=1;
memset(clientstate,0,sizeof(clientstate));
for (i=1 ; i<MAXNETNODES ; i++)
memset (&nodeadr[i],0,sizeof(&nodeadr[i]));
clientstate[0]=client_Done;
if (standalone==false)
{
clientstate[playernumber]=client_Done;
rottcom.consoleplayer=playernumber;
memcpy (&nodeadr[playernumber], &nodeadr[0], //copy in local address
sizeof(nodeadr[playernumber]) );
printf ("\nServer is Player %d\n",playernumber);
playernumber++;
}
}
/*
===================
=
= LookForNodes
=
= Finds all the nodes for the game and works out player numbers among them
=
===================
*/
#define cmd_FindClient 1
#define cmd_HereIAm 2
#define cmd_YouAre 3
#define cmd_IAm 4
#define cmd_AllDone 5
#define cmd_Info 6
#define MAXWAIT 10
void LookForNodes (void)
{
int i;
struct time time;
int oldsec;
setupdata_t *setup;
boolean done;
short numplayers,extra;
boolean showednum;
short secondsleft;
boolean masterset=false;
done=false;
oldsec = -1;
secondsleft = MAXWAIT;
setup = (setupdata_t *)&rottcom.data;
ipxlocaltime = -1; // in setup time, not game time
showednum = false;
SetupRandomMessages ();
if (server==true)
{
printf("SERVER MODE:\n");
printf("============\n");
printf("Attempting to find all clients for %i player NETROTT\n",
numnetnodes);
nodesetup.client=0;
rottcom.client=0;
rottcom.numplayers=numnetnodes;
ResetNodeAddresses ();
if (standalone==false)
{
masterset=true;
}
}
else
{
printf("CLIENT MODE:\n");
printf("============\n");
printf("Attempting to find server\n");
rottcom.numplayers=MAXPLAYERS;
nodesetup.client=1;
rottcom.client=1;
}
//
// build local setup info
//
nodesetup.playernumber = 0;
gettime (&time);
oldsec = time.ti_sec;
do
{
//
// check for aborting
//
while ( bioskey(1) )
{
if ( (bioskey (0) & 0xff) == 27)
Error ("\n\nNetwork game synchronization aborted.");
}
if (server==false) // Client code
{
//
// listen to the network
//
while (GetPacket ())
{
extra = setup->extra;
numplayers = setup->numplayers;
if (remotetime != -1)
{ // an early game packet, not a setup packet
if (rottcom.remotenode == -1)
Error ("\n\nUnkown game packet: Other ROTT server present");
}
if (setup->client==0) // It's a server packet
{
switch (setup->command)
{
case cmd_FindClient:
// copy the server's address
if (rottcom.remotenode==-1) // only set if it is an unknown pkt
{
memcpy (&nodeadr[1], &remoteadr,
sizeof(nodeadr[1]) );
}
nodesetup.command=cmd_HereIAm;
if (master==true)
nodesetup.extra=1;
else
nodesetup.extra=0;
memcpy (&rottcom.data,
&nodesetup,sizeof(*setup));
rottcom.datalength = sizeof(*setup);
SendPacket (1); // send to server
printf (".");
break;
case cmd_Info:
if (showednum==false)
{
printf("\nServer is looking for %d players\n",numplayers);
showednum = true;
}
if ((extra>>8)!=0)
{
if ((extra>>8)==100)
printf("\nServer found player %d\n",extra&0xff);
else
PrintRandomMessage((extra>>8)-1,extra&0xff);
}
break;
case cmd_YouAre:
rottcom.consoleplayer=setup->playernumber;
nodesetup.command=cmd_IAm;
nodesetup.playernumber=setup->playernumber;
memcpy (&rottcom.data,
&nodesetup,sizeof(*setup));
rottcom.datalength = sizeof(*setup);
SendPacket (1); // send to server
printf (".");
printf ("\nI am player %d\n",setup->playernumber);
break;
case cmd_AllDone:
rottcom.numplayers=setup->playernumber;
done=true;
printf ("!");
break;
}
}
}
}
else // It's the server
{
//
// listen to the network
//
while (GetPacket ())
{
extra = setup->extra;
if (remotetime != -1)
{ // an early game packet, not a setup packet
if (rottcom.remotenode == -1)
Error ("\n\nUnkown game packet: Other clients still in game.");
}
if (setup->client==1) // It's a client packet
{
switch (setup->command)
{
case cmd_HereIAm:
{
int pnum;
if ((masterset==false) && (extra==1)) // some client is using the 'master' param
{
ResetNodeAddresses ();
masterset=true;
rottcom.remotenode=-1;
}
pnum=playernumber;
if (rottcom.remotenode==-1) // only set if it is an unknown pkt
{
// copy the client's address
printf ("\nFound Player %d\n",pnum);
memcpy (&nodeadr[playernumber], &remoteadr,
sizeof(nodeadr[playernumber]) );
nodesetup.extra=(short)(100<<8);
nodesetup.extra |= playernumber;
nodesetup.command=cmd_Info;
nodesetup.numplayers=numnetnodes;
rottcom.datalength = sizeof(*setup);
memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
SendPacket (MAXNETNODES); // send to all
}
else
pnum=rottcom.remotenode;
if (clientstate[pnum]>client_Echoed)
continue;
nodesetup.command=cmd_YouAre;
nodesetup.playernumber=pnum;
memcpy (&rottcom.data,
&nodesetup,sizeof(*setup));
SendPacket (pnum); // send back to client
clientstate[pnum]=client_Echoed;
playernumber++;
}
break;
case cmd_IAm:
if (rottcom.remotenode==-1) // Shouldn't happen
continue;
// Error("\n\nReceived Identity packet before identification\n");
if (rottcom.remotenode!=setup->playernumber)
Error("\n\nReceived Incorrect player number\n");
printf ("Finished Player %d\n",rottcom.remotenode);
clientstate[rottcom.remotenode]=client_Done;
break;
}
}
else
{
if (rottcom.remotenode!=0)
Error("\n\nMultiple ROTT Servers!\n");
switch (setup->command)
{
case cmd_Info:
if (((extra>>8)!=0) && (standalone==false))
{
if ((extra>>8)==100)
printf("\nServer found player %d\n",extra&0xff);
else
PrintRandomMessage((extra>>8)-1,extra&0xff);
}
break;
}
}
}
// Check to see if we are indeed done
done=true; // set it to true
if (playernumber > numnetnodes+1)
Error("\n\nFound too many players=%d\n",playernumber);
if (playernumber <= numnetnodes)
done=false;
else
{
for (i=0;i<playernumber;i++)
if (clientstate[i]!=client_Done)
done=false;
}
gettime (&time);
if (time.ti_sec == oldsec)
continue;
secondsleft--;
if (secondsleft==0)
{
secondsleft=MAXWAIT;
nodesetup.extra=(GetRandomMessage())+1;
nodesetup.extra<<=8;
nodesetup.extra|=playernumber;
nodesetup.command=cmd_Info;
nodesetup.numplayers=numnetnodes;
rottcom.datalength = sizeof(*setup);
memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
SendPacket (MAXNETNODES); // send to all
}
oldsec = time.ti_sec;
printf (".");
// Make a general inquiry for any potential ROTT players
nodesetup.extra=0;
nodesetup.command=cmd_FindClient;
nodesetup.numplayers=numnetnodes;
rottcom.datalength = sizeof(*setup);
memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
SendPacket (MAXNETNODES); // send to all
}
} while (done==false);
// Done with finding players send out startup info
if (server==true)
{
int otime;
gettime (&time);
oldsec = time.ti_sec+1;
if (oldsec>59)
oldsec-=60;
otime = time.ti_sec-1;
while (oldsec!=time.ti_sec)
{
gettime (&time);
if (time.ti_sec == otime)
continue;
otime = time.ti_sec;
nodesetup.command=cmd_AllDone;
nodesetup.playernumber=playernumber-1;
rottcom.datalength = sizeof(*setup);
memcpy (&rottcom.data, &nodesetup,sizeof(*setup));
SendPacket (MAXNETNODES); // send to all
}
}
if (server==true)
{
if (standalone == false)
printf ("Server is player %i of %i\n", rottcom.consoleplayer, rottcom.numplayers);
else
printf ("Server is standalone\n");
}
else
printf ("\nConsole is player %i of %i\n", rottcom.consoleplayer, rottcom.numplayers);
while (GetPacket ()) {}
}
/*
=============
=
= main
=
=============
*/
void main (void)
{
int i;
//
// determine game parameters
//
numnetnodes = 2;
rottcom.gametype=NETWORK_GAME;
rottcom.remoteridicule = 0;
printf("\n\n -----------------------------------\n");
printf(" ROTT NETWORK DEVICE DRIVER V%s \n",VERSION);
printf(" -----------------------------------\n");
i = CheckParm ("-nodes");
if (i && i < _argc-1)
{
numnetnodes = atoi(_argv[i+1]);
}
i = CheckParm ("-socket");
if (i && i < _argc-1)
{
socketid = atoi(_argv[i+1]);
}
server=false;
standalone=false;
pause=false;
master=false;
if (CheckParm ("-server"))
server=true;
if (CheckParm ("-standalone"))
standalone=true;
if (CheckParm ("-pause"))
pause=true;
if (CheckParm ("-master"))
master=true;
if (CheckParm ("-remoteridicule"))
rottcom.remoteridicule = 1;
InitNetwork ();
LookForNodes ();
ipxlocaltime = 0; // no longer in setup
LaunchROTT ();
Shutdown ();
exit(0);
}