// ------------------------------------------------------------------------------------------------
// main.c
//
// This has the main function for the amDsp testbed.
//
// COPYRIGHT (C) SEGA OF AMERICA, INC. 1998
// All rights reserved.
//
// Information and source code samples contained herein are 
// provided "as-is", without representations or warranties, and 
// are subject to change without notice.
//
// SEGA OF AMERICA, INC. cannot support modifications or 
// derivative works created from the sample source code provided. 
// Developers may use, reproduce, and modify portions or entire 
// sections of the sample source code for the purposes of creating
// Dreamcast applications.  
//
// Sample source code contained herein may not be appropriate 
// for use under all circumstances.  Please consult Developer 
// documentation provided along with your Dreamcast unit for
// additional information and suggestions.
//
//
// Author: Ralph "Cooksey" Thomas
//
// Tabs: 4
//
// Rev:			04/05/99	File Originated
// ------------------------------------------------------------------------------------------------



#include <shinobi.h>
#include <sg_chain.h>
#include <am.h>
#include "amDsp.h"
#include "MyButton.h"
#include "MySfx.h"
#include "MyStream.h"
#include "MyFile.h"
#include "MyPrintf.h"
#include "MyInt.h"
#include "MyMalloc.h"
#include "MyAmSetup.h"

#define MAX_AUDIO_INSTANCES					64
#define MAX_ONE_SHOTS						4
#define FIRST_Q_CHANNEL						12
#define	NUMBER_OF_Q_CHANNELS				4
	

AM_BANK_PTR		gMyBank							=	KTNULL;
AM_SOUND_PTR	gOneShot;

#ifdef __GNUC__
int main(void)
#else
void main(void)
#endif
{
	SYE_CBL_CABLE Cable;
	PDS_PERIPHERAL *	pad;
	KTU32				oneShotSounds[MAX_ONE_SHOTS] 	= 	{AMDSP_ELEVATOR_WAV,AMDSP_GLASS_WAV,AMDSP_HONK_WAV,AMDSP_PING_WAV};
	KTU32				oneShotIndex					=	0;
	char 				message[80]						= 	{" "};
	KTU32 				effectSourceMix					=	75;
	KTU32 				firstQChannel					=	FIRST_Q_CHANNEL;
	KTU32 				numberOfQChannels				=	NUMBER_OF_Q_CHANNELS;
	KTU32 				volume							=	127;
	KTU32 				pan								=	0;

#ifdef __GNUC__
	shinobi_workaround();
#endif

	njSetBorderColor(0x00000000);

	// Check the cable for NTSC or VGA 
	Cable = syCblCheckCable();

	switch( Cable )
		{
		case SYE_CBL_CABLE_VGA:
			sbInitSystem(NJD_RESOLUTION_VGA, NJD_FRAMEBUFFER_MODE_RGB565, 1);
			break;
	
		case SYE_CBL_CABLE_NTSC:
			sbInitSystem(NJD_RESOLUTION_640x480_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1);
			break;
		}
	
	njInitVertexBuffer( 20000, 0, 20000, 0, 0 );
	njInitPrint( NULL, 0, NJD_TEXFMT_ARGB_1555 );
	njSetBackColor( 0x00000000, 0x00000000, 0x000000FF );
	njPrintSize(12);	//	legible on NTSC
	
	// ----------------------------------------------------------------------------------------------
	// Initialize the am library
	// ----------------------------------------------------------------------------------------------

	if(MyAmSetup(KTFALSE)==KTFALSE)
		return;
	
	// ----------------------------------------------------------------------------------------------
	// Load a bank
	// ----------------------------------------------------------------------------------------------
	
	if((gMyBank=MyLoadBank(AMDSP_FILENAME))==KTNULL)
		{
		MyDebugf("MyLoadBank(0x%x,%s) FAIL",gMyBank,AMDSP_FILENAME);
		return;
		}
	else
		{
		MyDebugf("MyLoadBank(0x%x,%s) // load a bank of sounds into sound memory",gMyBank,AMDSP_FILENAME);
		}

	// ----------------------------------------------------------------------------------------------
	// Install the effects patch (both a .fpb and a .fob asset)
	// ----------------------------------------------------------------------------------------------

	if(MyInstallEffectsPatch(gMyBank,AMDSP_RVBQSND_FPB,AMDSP_RVBQSND_FOB)==KTFALSE)
		{
		MyDebugf("MyInstallEffectsPatch(0x%x,%u,%u) FAIL",gMyBank,AMDSP_RVBQSND_FPB,AMDSP_RVBQSND_FOB);
		return;
		}
	else
		{
		MyDebugf("MyInstallEffectsPatch(0x%x,%u,%u) // install the two effects patch data objects (.fpb and .fob)",gMyBank,AMDSP_RVBQSND_FPB,AMDSP_RVBQSND_FOB);
		}
	
	// ----------------------------------------------------------------------------------------------
	// Set up the Q Sound channels as per this effects output bank
	// ----------------------------------------------------------------------------------------------

	if(amSoundSetQSoundChannels	(firstQChannel,numberOfQChannels)==KTFALSE)
		{
		MyDebugf("amSoundSetQSoundChannels(%u,%u) FAIL",firstQChannel,numberOfQChannels);
		return;
		}
	else
		{
		MyDebugf("amSoundSetQSoundChannels(%u,%u) // set up the Q-Sound configuration",firstQChannel,numberOfQChannels);
		}
	
	// ----------------------------------------------------------------------------------------------
	// Get any error messages
	// ----------------------------------------------------------------------------------------------

	gMyAmError	=	amErrorGetLast();
	gMyAcError	=	acErrorGetLast();

	// ----------------------------------------------------------------------------------------------
	// Main loop
	// ----------------------------------------------------------------------------------------------
		
	while(1)
		{
		pad = (PDS_PERIPHERAL *)pdGetPeripheral(PDD_PORT_A0);
	
/*
	
		MyDcPrintf(STR_VOL_X,STR_VOL_Y,"Stream Volume: %u",myStreamVolume);
*/	
		MyDcPrintf(INFO_1_X,INFO_1_Y,"Press the right trigger to play reverb sounds");
		MyDcPrintf(INFO_2_X,INFO_2_Y,"Press the left trigger to play Q-Sound sounds");
		MyDcPrintf(INFO_3_X,INFO_3_Y,"D-Pad Up and Down control reverb source mix");
		MyDcPrintf(INFO_4_X,INFO_4_Y,"Current Pan: %u Reverb Source Mix: %u",pan,effectSourceMix);

//		MyDcPrintf(INFO_4_X,INFO_4_Y,"Q-Sound mixer channel: %u",gQSoundChannel);

		MyDcPrintf(STR_STATUS_X,STR_STATUS_Y,"Message: %s",message);
	
		MyDcPrintf(AM_ERROR_X,AM_ERROR_Y,"Am Error Number: %d",gMyAmError->number);
		MyDcPrintf(AC_ERROR_X,AC_ERROR_Y,"Ac Error Number: %d",gMyAcError->number);
		
		if(amErrorExists()==KTTRUE)
			{
			gMyAmError	=	amErrorGetLast();
			}
	
		if(acErrorExists()==KTTRUE)
			{
			gMyAcError	=	acErrorGetLast();
			}
	

		if(pad->press & PAD_R_TRIGGER)
			{
			gOneShot=MyPlaySoundEffectFx(gMyBank,oneShotSounds[oneShotIndex++],volume,pan,effectSourceMix,KTFALSE);

			if(oneShotIndex >= MAX_ONE_SHOTS) oneShotIndex	=	0;

			strcpy(message,"Playing sound with reverb");
			}
		else if(pad->press & PAD_L_TRIGGER)
			{
			pan 	+=		16;
			
			if(pan == 128)
				pan		=	127;	
			
			if(pan > 128)
				pan		=	0;

			gOneShot=MyPlaySoundEffectFx(gMyBank,AMDSP_PING_WAV,volume,pan,effectSourceMix,KTTRUE);

			if(oneShotIndex >= MAX_ONE_SHOTS) oneShotIndex	=	0;

			strcpy(message,"Playing sound with Q-Sound");
			}
		else if(pad->press & PAD_MOVE_UP)
			{
			effectSourceMix += 10;
			
			if(effectSourceMix > 100)
				effectSourceMix = 100;
			}
		else if(pad->press & PAD_MOVE_DOWN)
			{
			effectSourceMix -= 10;
			
			if(effectSourceMix > 100)
				effectSourceMix = 0;
			}
/*	
		else if(pad->press & PAD_Y_BUTTON)
			{
			MyPlaySoundEffect(gMyBank,&gSound[instanceNumber++],oneShotSounds[oneShotIndex++]);
	
			if(oneShotIndex >= MAX_ONE_SHOTS) oneShotIndex	=	0;
			}
		else if(pad->press & PAD_A_BUTTON)
			{
			if(heliLoopFlag==KTFALSE)
				{
				MyPlaySoundEffect(gMyBank,&heliLoop,STR_SFX_HELILOOP_WAV);
				heliLoopFlag	=	KTTRUE;
				}
			else
				{
				MyStopSoundEffect(&heliLoop);
				heliLoopFlag	=	KTFALSE;
				}
			}
		else if(pad->press & PAD_B_BUTTON)
			{
			if(humLoopFlag==KTFALSE)
				{
				MyPlaySoundEffect(gMyBank,&humLoop,STR_SFX_MHUMLOOP_WAV);
				humLoopFlag	=	KTTRUE;
				}
			else
				{
				MyStopSoundEffect(&humLoop);
				humLoopFlag	=	KTFALSE;
				}
			}
		else if(pad->press & PAD_X_BUTTON)
			{
			if(spaceLoopFlag==KTFALSE)
				{
				MyPlaySoundEffect(gMyBank,&spaceLoop,STR_SFX_MHUMLOOP_WAV);
				spaceLoopFlag	=	KTTRUE;
				}
			else
				{
				MyStopSoundEffect(&spaceLoop);
				spaceLoopFlag	=	KTFALSE;
				}
			}
		else if(pad->press & PAD_MOVE_LEFT)
			{
			MyStreamStop(&myStream);
			strcpy(message,"Stopped");
			}
		else if(pad->press & PAD_MOVE_RIGHT)
			{
			if(amStreamPlaying(&myStream)==KTFALSE)
				{
				MyStreamClearCallbackFlag();
				MyStreamRestart(&myStream);
				strcpy(message,"Playing");
				}
			}
			
*/	


		njWaitVSync();
		}
	
	
	// ----------------------------------------------------------------------------------------------
	// Shutdown the am library
	// ----------------------------------------------------------------------------------------------
	
	amShutdown();
}

