// doomnet.c
// Created by Id Software for SERSETUP.EXE, 1993, 1994.
// Hacked by Russell Gilbert and others SER4.EXE, SER5.EXE, and SER6.EXE 1994.
// Hacked by Paul T. Hermann for SER5.EXE, SER6.EXE 1994.
//
// Compiled under Borland C++ 3.1 using the Compact Memory module
// Using 80386 instruction set and 80387 emualation support
// Optimizations for speed enabled
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <dos.h>
#include <conio.h>
#include "doomnet.h"

doomcom_t	doomcom;
int 			vectorishooked=0;
void interrupt (*olddoomvect) ();

extern int loadgame;
extern char config [80+1];
extern char devparm [256+1];
extern char doomexe [12+1];
extern int nomonsters;
extern int respawn;
extern int episode;
extern int map;
extern int skill;
extern int deathmatch;
extern int altdeath;
extern int doom2;


/*
=============
=
= 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 LaunchDOOM1_2 (void)
{
	char	*newargs[99];
	char	adrstring[10];
	long  flatadr;
	char epstr [2];
	char mapstr [2];
	char skstr [2];
	char lostr [2];
	int argnum = 0;
	int i;
	int prev;
	char devstr [256+1];


	/* LaunchDOOM specifically for Doom v1.2 and below (no response files) */
// prepare for DOOM
	if ( !vectorishooked )            //check if vector is already hooked
	{
		olddoomvect = getvect (doomcom.intnum);
		setvect (doomcom.intnum,NetISR);
		vectorishooked = 1;
	}

// build the argument list for DOOM, adding "-net" and the address of doomcom.

/* Copy our program name first - isn't necessary, but doom relies on it */
	newargs [argnum++] = _argv [0];

	newargs [argnum++] = "-devparm";
	if (deathmatch)
		newargs [argnum++] = "-deathmatch";
	if (altdeath)
		newargs [argnum++] = "-altdeath";
	if (nomonsters)
		newargs [argnum++] = "-nomonsters";
	if (respawn)
		newargs [argnum++] = "-respawn";
	if (map != -1)
	{
//		if (devparm [0] == EOS)
//			newargs [argnum++] = "-devparm";
		newargs [argnum++] = "-warp";
		sprintf (epstr, "%d", episode == -1 ? 1 : episode);
		if (!doom2)
			newargs [argnum++] = epstr;
		sprintf (mapstr, "%d", map);
		newargs [argnum++] = mapstr;
	}
	else if( (episode != -1) && (!doom2) )
	{
			newargs [argnum++] = "-episode";
			sprintf (epstr, "%d", episode);
			newargs [argnum++] = epstr;
	}
	if (skill != -1)
	{
		newargs [argnum++] = "-skill";
		sprintf (skstr, "%d", skill);
		newargs [argnum++] = skstr;
	}
	if (loadgame != -1)
	{
		newargs [argnum++] = "-loadgame";
		sprintf (lostr, "%d", loadgame);
		newargs [argnum++] = lostr;
	}
	if (config [0] != EOS)
	{
		newargs [argnum++] = "-config";
		newargs [argnum++] = config;
	}

	if (devparm [0] != EOS)
	{
//		newargs [argnum++] = "-devparm";
		/* Copy all devparm args */
		strcpy (devstr, devparm);
		prev = 0;
		i = -1;
		while (devstr [++i] != EOS)
		{
			if (devstr [i] == ' ')
			{
				devstr [i] = EOS;
				newargs [argnum++] = &devstr [prev];
				prev = i+1;
			}
		}
		newargs [argnum++] = &devstr [prev];
	}
	newargs [argnum++] = "-net";

	/* Add address of doomcom structure */
	flatadr = (long)_DS*16 + (unsigned)&doomcom;
	sprintf (adrstring,"%lu",flatadr);
	newargs [argnum++] = adrstring;

	newargs [argnum] = NULL;

	printf ("About to launch doom.exe -- Passing these arguments:\n");
	for (i = 0; i < argnum; i++)
		printf ("  arg %d = %s\n", i, newargs [i]);
	printf ("  player = %d\n", doomcom.consoleplayer);
	printf ("  extratics = %d\n", doomcom.extratics);
	printf ("\nPress ESC to abort, or any other key to continue...");
	if (getch () == ESC)
	{
		printf ("\n\n");
		return;
	}
	if (spawnv  (P_WAIT, doomexe, newargs) == -1)
	{
		textcolor(YELLOW);
		cprintf("\a\r\nAn error occured trying to execute DOOM!!\r\n"
				  "This can be due to a large number of arguments.\r\n"
				  "If this is the case simply shorten the number of options\r\n"
				  "you are passing Doom\r\n");
		textcolor(LIGHTGRAY);
		return;
	}
	printf ("\nReturned from DOOM\n\n");
}

void LaunchDOOM (void)
{
	char	adrstring[10];
	long  flatadr;
	int argnum = 0;
	int i;
	int prev;
	char devstr [256+1];
	char  *newargs[5];
	FILE *outfile;
	struct time t;
	char response[9];
	int len;

	/* LaunchDOOM for Doom v1.6 and above (uses response files for args) */
// prepare for DOOM
	if ( !vectorishooked )    //check if vector is already hooked
	{
		olddoomvect = getvect (doomcom.intnum);
		setvect (doomcom.intnum,NetISR);
		vectorishooked = 1;
	}

// build the argument list for DOOM, adding "-net" and the address of doomcom.
	gettime (&t);
	sprintf(response,"ID%02d%02d%02d", t.ti_hour, t.ti_min, t.ti_sec);

	if ( (outfile=fopen( response, "w+t" )) == NULL)
	{
		printf("There is a Major Problem opening a response file./n"
				 "Press any key to return to the main menu.");
		getch();
		return;
	}

	/* Copy our program name first - isn't necessary, but doom relies on it */
	newargs [argnum++] = _argv [0];

	fprintf(outfile,"-devparm\n");
	if (deathmatch)
		fprintf(outfile,"-deathmatch\n");
	if (altdeath)
		fprintf(outfile,"-altdeath\n");
	if (nomonsters)
		fprintf(outfile,"-nomonsters\n");
	if (respawn)
		fprintf(outfile,"-respawn\n");
	if (map != -1)
	{
//		if (devparm [0] == EOS)
//			fprintf(outfile,"-devparm\n");
		fprintf(outfile,"-warp\n");
		if (!doom2)   // Doom ][ does not have episode
			fprintf(outfile,"%d\n", episode == -1 ? 1 : episode);
		fprintf(outfile,"%d\n", map);
	}
	else if( (episode != -1) && (!doom2) )
	{
			fprintf(outfile,"-episode\n");
			fprintf(outfile,"%d\n", episode);
	}
	if (skill != -1)
	{
		fprintf(outfile,"-skill\n");
		fprintf(outfile,"%d\n",skill);
	}
	if (loadgame != -1)
	{
		fprintf(outfile,"-loadgame\n");
		fprintf(outfile,"%d\n", loadgame);
	}
	if (config [0] != EOS)
	{
		fprintf(outfile,"-config\n");
		fprintf(outfile,"%s\n",config);
	}

	if (devparm [0] != EOS)
	{
//		fprintf(outfile,"-devparm\n");
		/* Copy all devparm args */
		strcpy (devstr, devparm);
		prev = 0;
		i = -1;
		while (devstr [++i] != EOS)
		{
			if (devstr [i] == ' ')
			{
				devstr [i] = EOS;
				fprintf(outfile,"%s\n", &devstr [prev]);
				prev = i+1;
			}
		}
		fprintf(outfile,"%s\n", &devstr [prev]);
	}
	fclose(outfile);
	sprintf(newargs [argnum],"@%s",response);
	argnum++;
	newargs [argnum++] = "-net";

	/* Add address of doomcom structure */
	flatadr = (long)_DS*16 + (unsigned)&doomcom;
	sprintf (adrstring,"%lu",flatadr);
	newargs [argnum++] = adrstring;

	newargs [argnum] = NULL;

	if ( (outfile=fopen( response, "rt" )) == NULL)
	{
		printf("There is a Major Problem opening a response file./n"
				 "Press any key to return to the main menu.");
		getch();
		return;
	}

	printf ("About to launch doom.exe -- Passing these arguments:\n");
	for (i = 0; i < argnum; i++)
		printf ("arg %d = %s\n", i, newargs [i]);
	printf ("player = %d\n", doomcom.consoleplayer);
	printf ("extratics = %d\n", doomcom.extratics);
	printf ("Response file contents:\n");
	while (fgets (devstr, 81, outfile) != NULL)
	{
		if (devstr [(len = strlen (devstr))-1] == '\n')	/* Get rid of cr at end */
			devstr [len-1] = EOS;
		if (wherex()+len > 80)
			printf("\n");
		printf(" %s",devstr);
	}
	fclose(outfile);
	printf ("\nPress ESC to abort, or any other key to continue...");
	if (getch () == ESC)
	{
		printf ("\n\n");
		remove(response);
		return;
	}
	spawnv(P_WAIT, doomexe, newargs);
	remove( response );
	printf ("\nReturned from DOOM\n\n");
}
