greed/IPX/IPXSETUP.C
2014-12-12 00:00:00 +00:00

238 lines
6.6 KiB
C
Raw Blame History

/***************************************************************************/
/* */
/* */
/* IPX Network Communication Driver for Greed */
/* Copyright (C) 1995 by Channel 7 */
/* */
/* written by Robert Morgan */
/* */
/***************************************************************************/
#include <STDIO.H>
#include <DOS.H>
#include <STRING.H>
#include <STDARG.H>
#include <BIOS.H>
#include <CONIO.H>
#include <STDLIB.H>
#include <TIME.H>
#include "ipx.h"
/**** CONSTANTS ****/
#define VERSION "1.026"
#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); \
}
/**** VARIABLES ****/
int numnetnodes;
setupdata_t nodesetup[MAXPLAYERS];
/**** FUNCTIONS ****/
void MS_Error(char *error, ...)
{
va_list argptr;
if (vectorhooked)
_dos_setvect(greedcom.intnum,oldgreedvect);
IPX_ShutdownNetwork();
va_start(argptr,error);
vprintf(error,argptr);
va_end(argptr);
printf("\n");
exit(1);
}
void interrupt IPX_NetISR(void)
{
if (greedcom.command==CMD_GET)
IPX_GetPacket(); // get called more often
else if (greedcom.command==CMD_SEND)
{
localt++;
IPX_SendPacket(greedcom.remotenode);
}
}
/*
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)
{
time_t curtime, oldsec;
setupdata_t *setup, *dest;
int i, total, console;
// wait until we get [numnetnodes] packets, then start playing
// the playernumbers are assigned by netid
printf("\nNeed %i players.\nLooking",numnetnodes-1);
oldsec=-1;
setup=(setupdata_t *)&greedcom.data;
localt=-1; // in setup time, not game time
// build local setup info
nodesetup[0].nodesfound=1;
nodesetup[0].nodeswanted=numnetnodes;
greedcom.numnodes=1;
while (1)
{
// check for aborting
while (_bios_keybrd(1))
{
if ((_bios_keybrd(0) & 0xff)==27)
{
printf("\n");
MS_Error("\nCancel multiplayer game.");
}
}
// listen to the network
while (IPX_GetPacket())
{
if (greedcom.remotenode==-1)
dest=&nodesetup[greedcom.numnodes];
else
dest=&nodesetup[greedcom.remotenode];
if (remotet!=-1)
{
// an early game packet, not a setup packet
if (greedcom.remotenode==-1)
{
printf("\n");
MS_Error("\nAnother game is in progress on this socket or unknown game packet");
}
// if it allready started, it must have found all nodes
dest->nodesfound=dest->nodeswanted;
continue;
}
// update setup ingo
memcpy(dest,setup,sizeof(*dest));
if (greedcom.remotenode!=-1)
continue; // already know that node address
// this is a new node
memcpy(&nodeadr[greedcom.numnodes],&remoteadr,sizeof(nodeadr[greedcom.numnodes]));
// if this node has a lower address, take all startup info
if (memcmp(&remoteadr,&nodeadr[0],sizeof(&remoteadr))<0) ;
greedcom.numnodes++;
printf("\nFound a player!\n");
if (greedcom.numnodes<numnetnodes)
printf("Need %i players.\nLooking",numnetnodes-greedcom.numnodes);
}
// we are done if all nodes have found all other nodes
for (i=0;i<greedcom.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
curtime=time(NULL);
if (curtime==oldsec)
continue;
oldsec=curtime;
if (greedcom.numnodes<numnetnodes)
printf(".",curtime);
nodesetup[0].nodesfound=greedcom.numnodes;
greedcom.datalength=sizeof(*setup);
memcpy(&greedcom.data,&nodesetup[0],sizeof(*setup));
IPX_SendPacket(MAXPLAYERS); // send to all
}
// count players
total=0;
console=0;
for (i=0;i<numnetnodes;i++)
{
total++;
if (total>MAXPLAYERS)
MS_Error("Too many players! (players>%i)",MAXPLAYERS);
if (memcmp(&nodeadr[i],&nodeadr[0],sizeof(nodeadr[0]))<0)
console++;
}
if (!total)
MS_Error("Must have at least 1 player!");
greedcom.consoleplayer=console;
greedcom.numplayers=total;
printf("\nYou are player %i of %i.\n",console+1,total);
}
void cdecl main(void)
{
int i, p, sid;
char far *vector;
// determine game parameters
numnetnodes=2;
greedcom.nettype=NETIPX;
printf("\n\n"
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ\n"
"<EFBFBD> Greed IPX Network Setup (v%s) <20>\n"
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ\n\n",VERSION);
if (MS_CheckParm("help"))
{
printf("Command Line Parameters:\n"
" /players n = number of players\n"
" /socket n = socket number\n"
" /vector n = interrupt vector (in hex)\n"
" /socketh n = socket number (in hex)\n\n");
exit(0);
}
i=MS_CheckParm("players");
if (i && i<_argc-1)
numnetnodes=atoi(_argv[i+1]);
printf("Players: %i\n",numnetnodes);
numpackets=MAXPACKETS;
i=MS_CheckParm("socket");
if (i>0 && i<_argc-1)
{
sid=atoi(_argv[i+1]);
if (sid>0) socketid=sid;
}
i=MS_CheckParm("socketh");
if (i>0 && i<_argc-1)
{
sscanf(_argv[i+1],"%x",&sid);
if (sid>0) socketid=sid;
}
printf("Socket: 0x%X (%i)\n",socketid,socketid);
// hook an interrupt vector
p=MS_CheckParm("vector");
if (p)
sscanf(_argv[p+1],"0x%x",&greedcom.intnum);
else
{
for (greedcom.intnum=0x60;greedcom.intnum<=0x66;greedcom.intnum++)
{
vector=*(char far * far *)(greedcom.intnum*4);
if (!vector || (byte)*vector==0xCF)
break;
}
if (greedcom.intnum==0x67)
MS_Error("No NULL or IRET interrupts were found between 0x60 and 0x66.\n");
}
printf("Interrupt: 0x%X\n",greedcom.intnum);
// make sure the network exists and create a bunch of buffers
IPX_InitNetwork();
// get addresses of all nodes
LookForNodes();
localt=0; // no longer in setup
LaunchGreed(); // spawn the program and pass it the net info
MS_Error("");
}