/*****************************************************************************/
/* PEND.C -> Plays a digital sound effect using the PostAudioPending calls.  */
/* Written by John W. Ratcliff, September 1992, needs to link to						 */
/* DIGPLAY.OBJ, DOSCALLS.OBJ. 																							 */
/*****************************************************************************/
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "loader.h"
#include "support.h"
#include "digplay.h"    // Include DIGPLAY header.
#include "doscalls.h"   // Include DOS tools header.
#include "video.h"      // Include header for VGA graphics tools.

int  PendingStatus(void);
void PostPending(SNDSTRUC *snd);

#define SWID 320	 // Width of sound data.

char *save;
char *buffer;
char *currentbuffer;
int AUTOINITDMA;
int DMALOAD;

void main(int argc,char **argv)
{
	char *effect;
	char *sound;
  long int siz;
	int soundsize;
	int xcon=0;
	SNDSTRUC *snd;

	if ( argc != 2 )
	{
		printf("Usage: PEND <filename>\n");
		exit(1);
	}

	snd = RealAlloc(sizeof(SNDSTRUC));
	buffer = realalloc(SWID*2);
	save = realalloc(SWID);

	effect = floadlow(argv[1], &siz);
	if ( !effect )
	{
		printf("File '%s' not found, or too large to play.\n",argv[1]);
		exit(1);
	}

	if ( !LoadDigPak("SOUNDRV.COM") )
	{
		printf("Failed to load sound driver.\n");
		exit(1);
	}

	if ( !InitDigPak() )
	{
		UnLoadDigPak();
		printf("Failed to initialize sound driver.\n");
		exit(1);
	}


	AUTOINITDMA = 0; // off by default.
	sound = effect;
	currentbuffer = buffer;
	snd->sndlen = SWID;
	snd->frequency = 11025;
	soundsize = siz;

	if ( AudioCapabilities()&DMABACKFILL )
	{
		if ( VerifyDMA(buffer,SWID*2) )
		{
			AUTOINITDMA = 1;
			DMALOAD = SWID; // First load time.
			NullSound(buffer,SWID*2,0x80);
			memorymove(buffer,sound,SWID*2);
			snd->sound = RealPtr(buffer);
			snd->sndlen = SWID*2;
			snd->frequency = 11025;
			SetBackFillMode(1);
			sound += SWID*2;
			siz -= SWID*2;
			DigPlay(snd);  // Start auto-init dma backfill...
		}
		else
		{
			printf("DMA buffer crosses segment boundary\n");
			exit(1);
		}
	}

	VidOn();

	do
	{
		if (PendingStatus() != PENDINGSOUND)
		{
			memorymove(currentbuffer,sound,SWID); // Move into buffer area the audio data.
			snd->sound = RealPtr(currentbuffer); // Set address of play sound location.
			MassageAudio(snd);
			PostPending(snd);

			DrawSound(save,320,0); // Erase previous.
			DrawSound(currentbuffer,320,15); // draw the new one.
			memorymove(save,currentbuffer,320);

			if ( currentbuffer == buffer ) // Perform flip-flop
				currentbuffer = buffer+SWID;
			else
				currentbuffer = buffer;
			sound+=SWID;	// Advance source sound effect address.
			siz-=SWID;	// Decrement size left to processs.
			if (siz < SWID)
				xcon = 1;
		}
		if (keystat())
			xcon = 1;
	} while (!xcon);

	if (AUTOINITDMA)
	{
		SetBackFillMode(0);  // Turn DMA back fill mode off!
	}

	VidOff();

	if ( AUTOINITDMA )
		printf("The current driver played this effect IN DMABACKFILL mode.\n");
	else
		printf("Current sound driver NOT in DMABACKFILL mode.\n");
	printf("Now playing sound effect one more time, NOT in DMA mode.\n");
	snd->sndlen = soundsize;
	snd->sound = RealPtr(effect);
	DigPlay(snd); // Replay sound effect.

	WaitSound();
	UnloadDigPak();


}


void PostPending(SNDSTRUC *snd)
{
	if ( AUTOINITDMA==0 ) PostAudioPending(snd);
}

int PendingStatus(void)
{
	int pend;
	int count;

	if (AUTOINITDMA)
	{
		pend = PENDINGSOUND;
		count = ReportDMAC();
		if ( DMALOAD && count < DMALOAD)
		{
			pend = PLAYINGNOTPENDING;
			DMALOAD = 0;
		}
		else
		{
			if (!DMALOAD && count >= SWID )
			{
				pend = PLAYINGNOTPENDING;
				DMALOAD = SWID;
			}
		}
	}
	else
		pend = AudioPendingStatus();

	return(pend);
}
