/********************** paroxysm.c ********************************
*
* Filename:	 paroxysm.c
*
* Target Host:	 x86, MS DOS, WIN95, WINNT
*
* Portability:	 uses MS RTL DOS routines to draw on the screen,
*		 and ascertain file system attributes.
*
* Usage info:	 PAROXYSM -RESPONSE -HELP
*
*		 where: -RESPONSE = use external response file.
*			-HELP	  = page PAROXYSM.TXT.
*
* Build info:
*
* Overview:
*
* This program installs the sprites of PAROXYSM.WAD after checking
* that all required files are present in the install directory.
* It installs the sprites using DEUSF.	If the sprites have been
* previously installed, (this is determined by the presence of the
* DEUSF output, "PAROX_FX.WAD") the install portion is disabled.
*
* In both cases, the program launches DOOM ][ with the required
* command line to invoke the Paroxysm extensions.
*
* If you should encounter any problems with the installation, this
* source is provided to facilitate debugging.
*
* Please enjoy The paroxysm, and direct comments to me at:
* jmartin@soundcom.net
*
* Sincerely,
*
* -Jeff.
*
* HISTORY
* -------
*
* Version:	v0.1
* Date: 	27-May-1997 - jjm.
* Title:	Original
* Description:	See above overview.
*
********************************************************************/

/* include some ms C header files		     */

#include <stdio.h>
#include <dos.h>
#include <errno.h>
#include <graph.h>
#include <conio.h>
#include <ctype.h>
#include <process.h>

/* handle for file i/o				    */

FILE *fptr;

/* some global varibles and symbols		    */

#define MAX_PER_PAGE	30

int counter  = 0,
    RESPONSE = 0,
    HELP     = 0,
    HEIGHT   = 20;

char stdout_buf[80],
     stderr_buf[80];

/***************************** main ************************************/

void main(int argc, char *argv[] )
{
      decode_args( argv[1] );	/* decode comand line arguments        */
      build_banner();		/* build_banner only returns here if
				   file "PAROX_FX.WAD" is not present
				   in the current directory, implying
				   that the installation is required.
									*/

      verify_distribution();	/* check for required files, install	*/
      install_sprites();	/* the sprites, then start The paroxysm */
      spawn_paroxysm();
      shut_down();		/* restore the text screen first	*/

}/*********************** end of main ******************************/


/********************** decode_args *******************************
*
* decodes arguments then sets appropriate global flags
*
******************************************************************/

decode_args( char *Arg )

{
if( stricmp(Arg, "-RESPONSE" ) == 0 )

   {

    RESPONSE = 1;
   }

if( stricmp(Arg, "-help" ) == 0 ||
    stricmp(Arg, "?"	 ) == 0	   )

   {
    HELP = 1;
   }

return(0);

}/******************** end of decode_args ************************/


/********************** build_banner *******************************
*
*  builds a text window using ms-dos C runtime library routines.
*
*  checks if installation is neccessary by confirming the existence
*  of file 'PAROX_FX.WAD' in the current directory. If this is
*  required, the routine returns to the main loop where installation
*  occurs.  If 'PAROX_FX.WAD' is present in the current directory,
*  the routine calls 'spawn_paroxysm'.
*
********************************************************************/

build_banner()

{

if( HELP )
   {
    HEIGHT = 40;
   }
      _clearscreen( _GCLEARSCREEN );
      _settextrows(50);
      text_box(10,5,70,HEIGHT,3,11);
      _settextposition(5,27);
      sprintf(stdout_buf," The PAROXYSM for DOOM ][ ");
      _outtext(stdout_buf);
      _settextcolor( 0 );

      _settextwindow(6,12,(HEIGHT-1),68);
      sprintf(stdout_buf,"\n");
      _outtext(stdout_buf);

if( HELP )

   {
    help_them();
   }

sprintf(stdout_buf,"Checking for prior installations..\n");
_outtext(stdout_buf);

if( access("PAROX_FX.WAD",0) )
      {
       sprintf(stdout_buf,"Can't find PAROX_FX.WAD in current \n");
       _outtext(stdout_buf);

       sprintf(stdout_buf,"directory.  Attempting installation..\n");
      _outtext(stdout_buf);

       return(1);
      }

sprintf(stdout_buf,"\nPAROX_FX.WAD in current directory.\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"\nAttempting to start the Paroxysm...\n");
_outtext(stdout_buf);


spawn_paroxysm();


}/********************* end of build_banner **************************/


/********************* verify_distribution ***************************
*
* checks to see if files in distrubution are present in current
* directory, displays an error specifing what file is missing if
* any and exits.
*
*********************************************************************/

verify_distribution()
{

check_file("PAROXYSM.WAD");

check_file("PSPRITE.WAD");

check_file("DEUSF.EXE");

check_file("DOOM2.EXE");

check_file("DOOM2.WAD");

return(1);

}/******************* end of verify_distribution *********************/


/************************  check_file ********************************
*
* checks for the presence of the named file, displays an error and
* exits if absent.
*
*********************************************************************/

check_file( file_name )

char file_name[80];

{

if( access(file_name,0) )
      {
	switch(errno)
	{
	case ENOENT:
	    {
	      sprintf(stderr_buf,
	      "   !! Can't find %s \n      in the current directory !!",
	      file_name);
	      report_error();
	      break;
	    }

	 default:
	    {
	      sprintf(stderr_buf,
	      "   !! DOS error %d while \n      accessing %s !!",errno,
	      file_name);
	      report_error();
	      break;
	    }

	 } /* end switch */

       } /* end access if */

return(1);
}/************************* end of check_file **********************/


/************************ install_sprites **************************
*
* installs sprites using deusf
*
*******************************************************************/

install_sprites()

{
/* verfiy enough space for sprites install ( at least 4.5 meg ) */

CHECK_SPACE();

sprintf(stdout_buf,
"DeuSF V3.1 Copyright (c)1994 \nOlivier Montanuy (montanuy@dmi.ens.fr)");
_outtext(stdout_buf);

sprintf(stdout_buf,"\n\nInstalling ");
_outtext(stdout_buf);

_settextcolor( 0x1f );

sprintf(stdout_buf,"SPRITES " );
_outtext(stdout_buf);

_settextcolor( 0 );

sprintf(stdout_buf,"patience please... " );
_outtext(stdout_buf);

system("deusf -sprite -add PSPRITE.WAD PAROX_fx.wad > paroxysm.log ");

_settextcolor( 15 );
sprintf(stdout_buf,"\n\nAddition of sprites & flats complete.\n\n");
_outtext(stdout_buf);
_settextcolor( 0	);

sprintf(stdout_buf,"     To play Paroxysm in the future,\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"     simply run this program.\n\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"     PAROXYSM -RESPONSE \n");
_outtext(stdout_buf);

sprintf(stdout_buf,"              -HELP or ?\n\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"     Where:   -RESPONSE = Use external response file\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"                          `PAROX.RSP' if it exists\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"                          in the current directory.\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"              -HELP     = Page `PAROXYSM.TXT'.\n");
_outtext(stdout_buf);

sprintf(stdout_buf,"\n      Press almost any key to try it !!");
_outtext(stdout_buf);

getch();

return(1);
}/************************** end of install_sprites() ***************/


/******************** spawn_paroxysm *****************************
*
* launches DOOM ][ with the appropriate command line in order
* to modify game play to conform to paroxysm protocols.
*
******************************************************************/

spawn_paroxysm()

{

      int Sstatus;

      check_file("DOOM2.EXE");
      check_file("DOOM2.WAD");
      check_file("PAROX_FX.WAD");
      check_file("PAROXYSM.WAD");

_settextcolor(15);



      _settextwindow(1,1,25,80);
      _settextposition(1,1);

      _settextcolor( 7 );
      _setbkcolor( 0 );

if( RESPONSE )

{

check_file("PAROX.RSP");

Sstatus = _spawnl( _P_WAIT,
		   "DOOM2.EXE",
		   "DOOM2.EXE",
		   "@PAROX.RSP",
		   "-FILE PAROX_FX.WAD PAROXYSM.WAD",
		   NULL );

}

else

{

Sstatus = _spawnl( _P_WAIT,
		   "DOOM2.EXE",
		   "DOOM2.EXE",
		   "-FILE PAROX_FX.WAD PAROXYSM.WAD",
		   NULL );

}


if( Sstatus == -1 )
   {
    sprintf(stderr_buf,
    "DOS error %d while attempting to spawn.",
     errno);
    report_error();
   }


shut_down();

}/************************* end of spawn_paroxysm ****************/


/**************************** CHECK_SPACE **********************************
*
* calculates the number of free bytes on the current drive and reports
* an error before exiting if that value is less than 5 meg.
*
***************************************************************************/

CHECK_SPACE(outfile_arg)

{
    struct diskfree_t drvinfo;

    unsigned drive;
    long space;

   sprintf(stdout_buf,"Checking for enough disk space to \n");
   _outtext(stdout_buf);

   sprintf(stdout_buf,"complete the installation.\n");
   _outtext(stdout_buf);

/* get the current drive */

    _dos_getdrive( &drive );

/* calculate available free space from _dos_getdiskfree info		*/

    _dos_getdiskfree( drive, &drvinfo );

    space = (long)drvinfo.avail_clusters * drvinfo.sectors_per_cluster *
	    drvinfo.bytes_per_sector;

   sprintf(stdout_buf,"Current drive has %ld free.\n\n",space);
   _outtext(stdout_buf);

   if( space < 4500000.00 )
      {
      sprintf(stderr_buf,"    !! FREE DISK SPACE < 4.5 MEG !!");
      report_error();
      }

return(1);

}/******************** END OF CHECK_SPACE **********************************/


/************************ report_error *********************************
*
* displays an error msg then exits
*
************************************************************************/

report_error()

{
      _settextwindow(1,1,25,80);
      text_box(22,17,63,21,4,15);

      _settextcolor( 0x1f );
      _settextposition(17,35);
      sprintf(stdout_buf," The problem is: ");
      _outtext(stdout_buf);
      _settextcolor( 15 );

      _settextwindow(18,24,20,65);

      _outtext(stderr_buf);

      shut_down();

}/*********************** end of report_error *****************/


/*********************** shut_down ***************************
*
* exits the program after restoring the text screen
*
*************************************************************/

shut_down()

{
      HEIGHT = 24;

      if( HELP )
	{
	    HEIGHT = 43;
	}

      _settextwindow(1,1,HEIGHT,80);
      _settextposition(HEIGHT,10);

      _settextcolor( 7 );
      _setbkcolor( 0 );
      printf("PAROXYSM for DOOM ][ exiting.....\n");

exit(0);

}/******************** end of shut_down ************************/


/******************************* text_box ********************************
*   draws a box on the text screen starting at the upper left row/column
*   and ending at the lower right row/column specified.  Also sets
*   the fg/bg text colors provided.
**************************************************************************/

text_box(ulx,uly,lrx,lry,bg,fg)
   int ulx,uly,lrx,lry,bg,fg;
{

int hor,vert,loopy, minor_loop;

/* go to upper left of box  */

    _settextposition(uly,ulx);

/* set background and foreground video	*/

_setbkcolor( bg );
_settextcolor( fg );

/* draw an upper left corner there */

   sprintf(stdout_buf,"\xC9");
   _outtext(stdout_buf);

/* figure out how far to go across and draw horizontal line that long */

  hor = lrx - ulx;
  for ( loopy=1; loopy<=hor; loopy++)
       {
	sprintf(stdout_buf,"\xCD");
	_outtext(stdout_buf);

       }

/* put an upper right corner there. */

	sprintf(stdout_buf,"\xBB");
	_outtext(stdout_buf);

/* figure out how far to go down and draw vertical lines that long */

  vert = (lry - uly);
  hor = lrx - ulx;

  for (loopy=1; loopy<=vert; loopy++)
      {
	uly++;
	_settextposition(uly,ulx);
	sprintf(stdout_buf,"\xBA");
	_outtext(stdout_buf);

	for( minor_loop=1; minor_loop <= hor; minor_loop++ )
	    {
	     sprintf(stdout_buf," ");
	     _outtext(stdout_buf);
	    }

	_settextposition(uly,lrx + 1);
	sprintf(stdout_buf,"\xBA");
	_outtext(stdout_buf);
      }

/* draw a lower left corner, a hor line and then a lower right corner */

      _settextposition(uly,ulx);
      uly++;

      sprintf(stdout_buf,"\xC8");
      _outtext(stdout_buf);

      for ( loopy=1; loopy<=hor; loopy++)
	   {
	    sprintf(stdout_buf,"\xCD");
	    _outtext(stdout_buf);
	   }

	  sprintf(stdout_buf,"\xBC");
	  _outtext(stdout_buf);

return(1);

}/************************** END OF text_box *****************************/


/*********************** help_them **************************************
*
* pages in 'more' fashion, contents of paroxysm.txt if it exists.
*
*************************************************************************/

help_them()

{

char help_string[79];
char key;

int  lines = 0;

    check_file( "paroxysm.txt" );

    if( (fptr = fopen( "paroxysm.txt", "rt" )) == NULL )
       {
	sprintf(stderr_buf,"Can`t open PAROXYSM.TXT for read.");
	report_error();
       }

    while( !feof(fptr) )
	  {

	if( fgets( help_string, 78, fptr) == NULL )

	   {
	    shut_down();
	   }

	if( lines >= MAX_PER_PAGE )
	   {

	    lines = 0;

	    _settextcolor( 15 );
	    sprintf(stdout_buf,
	    "\n           -MORE-   Press SPACE to continue.  \r");
	    _outtext(stdout_buf);

	    _settextcolor( 0 );

	    key = getch();

	    sprintf(stdout_buf,
	    "                                                \n");
	    _outtext(stdout_buf);

		if( stricmp( key, ' ') != 0 )

		   {
		    shut_down();
		   }

	    } /* if lines */

	    sprintf(stdout_buf, "%s", help_string);
	    _outtext(stdout_buf);

	    lines++;

	}/* while	*/

shut_down();
}/******************************** end of help_them ***********************/
