// ------------------------------------------------------------------------------------------------
// main.c
//
// This has the main function for the multi stream testbed.
//
// COPYRIGHT (C) SEGA OF AMERICA, INC. 1998
// All rights reserved.
//
// Author: Ralph "Cooksey" Thomas
//
// Tabs: 4
//
// Rev:			04/05/99	File Originated
// ------------------------------------------------------------------------------------------------



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


#define STREAM_FILE_NAME					"8Hip101A.str"						// 4:1 Compressed ADPCM

#define STREAM_TEST_PLAY_BUFFER_SIZE		(32768) 							// 

#define STREAM_TEST_TRANSFER_BUFFER_SIZE	(STREAM_TEST_PLAY_BUFFER_SIZE * 8) 	// 8 track asset

#define TRACK_VOLUME_X						BASE_X
#define TRACK_VOLUME_Y						BASE_Y+8
#define TRACK_PAN_X							BASE_X
#define TRACK_PAN_Y							BASE_Y+10

// ------------------------------------------------------------------------------------------------
// The scene mix objects
// ------------------------------------------------------------------------------------------------

// track map for the 8 track asset
// 	Drums
// 	Bass
// 	SynBass
//	Clear Guitar
//	Fuzz Guitar
// 	WahWah Guitar
//	Rhodes Piano
// 	Vocals


AM_STREAM_MIX fullMix	=	{
							127,64,				// 	Drums
							127,64,				// 	Bass
							127,64,				// 	SynBass
							127,74,				//	Clear Guitar
							100,50,				//	Fuzz Guitar
							100,96,				// 	WahWah Guitar
							100,32,				//	Rhodes Piano
							127,64,				// 	Vocals
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							};


AM_STREAM_MIX drumsBassAndGuitars	=	{
							127,64,				// 	Drums
							127,64,				// 	Bass
							127,64,				// 	SynBass
							127,74,				//	Clear Guitar
							100,50,				//	Fuzz Guitar
							100,96,				// 	WahWah Guitar
							0,32,				//	Rhodes Piano
							0,64,				// 	Vocals
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							};



AM_STREAM_MIX drumsOnly	=	{
							127,64,				// 	Drums
							0,64,				// 	Bass
							0,64,				// 	SynBass
							0,74,				//	Clear Guitar
							0,50,				//	Fuzz Guitar
							0,96,				// 	WahWah Guitar
							0,32,				//	Rhodes Piano
							0,64,				// 	Vocals
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							};


AM_STREAM_MIX drumsAndBass	=	{
							127,64,				// 	Drums
							127,64,				// 	Bass
							127,64,				// 	SynBass
							0,74,				//	Clear Guitar
							0,50,				//	Fuzz Guitar
							0,96,				// 	WahWah Guitar
							0,32,				//	Rhodes Piano
							0,64,				// 	Vocals
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							};


AM_STREAM_MIX drumsAndBassAndFuzz	=	{
							127,64,				// 	Drums
							127,64,				// 	Bass
							127,64,				// 	SynBass
							0,74,				//	Clear Guitar
							100,50,				//	Fuzz Guitar
							0,96,				// 	WahWah Guitar
							0,32,				//	Rhodes Piano
							0,64,				// 	Vocals
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							};

AM_STREAM_MIX drumsAndBassAndFuzzAndRhodes	=	{
							127,64,				// 	Drums
							127,64,				// 	Bass
							127,64,				// 	SynBass
							0,74,				//	Clear Guitar
							100,50,				//	Fuzz Guitar
							0,96,				// 	WahWah Guitar
							100,32,				//	Rhodes Piano
							0,64,				// 	Vocals
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							0,64,
							};



#define MAX_AUDIO_INSTANCES					64
#define MAX_ONE_SHOTS						4


KTBOOL StreamSetup(void);

AM_STREAM_PTR		gStream;
volatile KTU32 *	gPlayBuffer				=	KTNULL;
KTU32 				gPlayBufferSize			=	0;
volatile KTU32 *	gTransferBuffer			=	KTNULL;
KTU32 				gTransferBufferSize		=	0;
KTU8				gStreamVolume			=	AM_MAX_VOLUME; // AM_MAX_VOLUME = 127

#ifdef __GNUC__
int main(void)
#else
void main(void)
#endif
{
	SYE_CBL_CABLE Cable;
	PDS_PERIPHERAL *	pad;
	KTU32 				instanceNumber					=	0;	
	AM_BANK_PTR			myBank							=	KTNULL;
	KTU32				j								=	0;
	char 				mixMessage[80]					= {"allTracks"};

#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)
		{
		MyDebugf("MyAmSetup(KTFALSE)");
		return;
		}
	
	// ----------------------------------------------------------------------------------------------
	// Setup the stream
	// ----------------------------------------------------------------------------------------------

	if(StreamSetup()==KTFALSE)
		{
		MyDebugf("StreamSetup()");
		return;
		}

	// ----------------------------------------------------------------------------------------------
	// Start the stream
	// ----------------------------------------------------------------------------------------------

	MyStreamStart(gStream);

	// ----------------------------------------------------------------------------------------------
	// Main loop
	// ----------------------------------------------------------------------------------------------
			
	while(1)
		{
		pad = (PDS_PERIPHERAL *)pdGetPeripheral(PDD_PORT_A0);
	
		MyDcPrintf(INFO_1_X,INFO_1_Y,"Press the triggers or buttons to select mix");
		MyDcPrintf(INFO_2_X,INFO_2_Y,"Press the D-Pad left/right to start/stop stream");
		MyDcPrintf(STR_STATUS_X,STR_STATUS_Y,"Mix-Status: %s",mixMessage);
		MyDcPrintf(TRACK_VOLUME_X,TRACK_VOLUME_Y,"Track Volumes: %.3u,%.3u,%.3u,%.3u,%.3u,%.3u,%.3u,%.3u",gStream->track[0].volume,gStream->track[1].volume,gStream->track[2].volume,gStream->track[3].volume,gStream->track[4].volume,gStream->track[5].volume,gStream->track[6].volume,gStream->track[7].volume);
		MyDcPrintf(TRACK_PAN_X,TRACK_PAN_Y,      "Track Pans:    %.3u,%.3u,%.3u,%.3u,%.3u,%.3u,%.3u,%.3u",gStream->track[0].pan,gStream->track[1].pan,gStream->track[2].pan,gStream->track[3].pan,gStream->track[4].pan,gStream->track[5].pan,gStream->track[6].pan,gStream->track[7].pan);
		
	
	
		MyDcPrintf(AM_ERROR_X,AM_ERROR_Y,"Am Error #: %u",gMyAmError->number);
		MyDcPrintf(AC_ERROR_X,AC_ERROR_Y,"Ac Error #: %u",gMyAcError->number);
	
		MyStreamServer();
	
	
		if(MyStreamIsPlaying(gStream)==KTFALSE)
			{
			strcpy(mixMessage,"The Stream is Done...");
			}
	
	
		if(pad->press & PAD_Y_BUTTON)
			{
			MyStreamSetMix(gStream,&drumsOnly);
			strcpy(mixMessage,"drumsOnly");
			}
		else if(pad->press & PAD_A_BUTTON)
			{
			MyStreamSetMix(gStream,&drumsAndBass);
			strcpy(mixMessage,"drumsAndBass");
			}
		else if(pad->press & PAD_B_BUTTON)
			{
			MyStreamSetMix(gStream,&drumsBassAndGuitars);
			strcpy(mixMessage,"drumsBassAndGuitars");
			}
		else if(pad->press & PAD_X_BUTTON)
			{
			MyStreamSetMix(gStream,&fullMix);
			strcpy(mixMessage,"fullMix");
			}
		if(pad->press & PAD_R_TRIGGER)
			{
			MyStreamSetMix(gStream,&drumsAndBassAndFuzz);
			strcpy(mixMessage,"drumsAndBassAndFuzz");
			}
		if(pad->press & PAD_L_TRIGGER)
			{
			MyStreamSetMix(gStream,&drumsAndBassAndFuzzAndRhodes);
			strcpy(mixMessage,"drumsAndBassAndFuzzAndRhodes");
			}
		else if(pad->press & PAD_MOVE_LEFT)
			{
			MyStreamStop(gStream);
			strcpy(mixMessage,"Stopped");
			}
		else if(pad->press & PAD_MOVE_RIGHT)
			{
			if(MyStreamIsPlaying(gStream)==KTFALSE)
				{
				MyStreamDestroy(gStream);
	
				if((gStream=MyStreamPrepareFile(STREAM_FILE_NAME,gStreamVolume,64,gTransferBuffer,gPlayBuffer,KTNULL,AM_STREAM_NON_DMA))==KTNULL)
					return;
	
				MyStreamStart(gStream);

				strcpy(mixMessage,"Playing");
				}
			}
	
		njWaitVSync();
		}


// ----------------------------------------------------------------------------------------------
// Shutdown the am library
// ----------------------------------------------------------------------------------------------

MyAmShutdown();
}





KTBOOL StreamSetup(void)
{
// ----------------------------------------------------------------------------------------------
// Set the default play buffer size for the stream
// ----------------------------------------------------------------------------------------------

MyStreamSetPlayBufferSize(STREAM_TEST_PLAY_BUFFER_SIZE);

// ----------------------------------------------------------------------------------------------
// Get the memory requirements
// ----------------------------------------------------------------------------------------------

if(MyStreamGetBufferSpecs(STREAM_FILE_NAME,&gTransferBufferSize,&gPlayBufferSize,AM_STREAM_NON_DMA)==KTFALSE)
	return KTFALSE;

// ----------------------------------------------------------------------------------------------
// get the necessary buffers lined up for the stream
//
// allocate memory for the play buffers.
//
// transfer buffer MUST! be in sh4 memory and 32 byte aligned or file reads will fail with the 
// GDFS file system.
// ----------------------------------------------------------------------------------------------

if(amHeapAlloc(&gPlayBuffer,gPlayBufferSize,32,AM_PURGABLE_MEMORY,KTNULL)==KTFALSE)
	{
	MyDebugf("amHeapAlloc(0x%x,%u,%u,AM_PURGABLE_MEMORY,KTNULL) FAIL\n",gPlayBuffer,gPlayBufferSize,32);
	return KTFALSE;
	}
else
	MyDebugf("amHeapAlloc(0x%x,%u,%u,AM_PURGABLE_MEMORY,KTNULL)\n",gPlayBuffer,gPlayBufferSize,32);

// ----------------------------------------------------------------------------------------------
// allocate memory for the transfer buffers.
//
// transfer buffer MUST! be in sh4 memory and 32 byte aligned or file reads will fail with the 
// GDFS file system.
// ----------------------------------------------------------------------------------------------

if((gTransferBuffer=(volatile KTU32 *)syMalloc(gTransferBufferSize))==KTNULL)
	{
	MyDebugf("syMalloc(gTransferBufferSize) FAIL\n");
	return KTFALSE;
	}
else
	MyDebugf("syMalloc(gTransferBufferSize)\n");

// ----------------------------------------------------------------------------------------------
// prepare the stream
// ----------------------------------------------------------------------------------------------

if((gStream=MyStreamPrepareFile(STREAM_FILE_NAME,gStreamVolume,64,gTransferBuffer,gPlayBuffer,KTNULL,AM_STREAM_NON_DMA))==KTNULL)
	return KTFALSE;

return KTTRUE;
}

