/*
      PCM Stream TEST
*/

/*                 */
/* Include headers */
/*                 */
#include <shinobi.h>

#include "..\include\sndutls.h"

/* Global Variables */
Uint32 play_start = 0;
Uint32 *src_adr;
Sint32 src_size;

/*                   */
/* Declare Prototype */
/*                   */
void UserVBlankIn( SDPSTM * );
void SoundInit( void );
void SoundMain( PDS_PERIPHERAL *, SDPSTM * );
void main( void );

/*                 */
/* Function Define */
/*                 */
void dummy_(){}

void UserVBlankIn( SDPSTM *hndl ) {
  Bool          flg;
  SDMEMBLK      mem_blk = NULL;
  static Uint32 i = 0;
  SDE_ERR       ret;
  Sint32        *addr;

  /* Call Sound Server */
  sdSysServer();

  /*  Can I transfer pcm data? */
  ret = sdPstmIsTransferWaveData( *hndl, 0, 0x1000, &flg);

  if ( play_start == 1 ) {
    if ( flg == true ) {
      sdMemBlkCreate( &mem_blk );
      if ( ( src_size - i * 0x1000 ) < 0x1000 ) {
        /*  Transfer  */
        sdMemBlkSetPrm( mem_blk, ( void *)( src_adr + ( src_size - i * 0x400 ) ), 0x1000, SDD_MEMBLK_SYNC_FUNC, NULL);
        if ( sdPstmTransferWaveData( *hndl, 0, mem_blk) != SDE_ERR_NOTHING ) PrgStop();
        /* ホントは再生終了を待たなきゃなんない。 */
        sdPstmStop( *hndl);
        sdPstmClosePort( *hndl );
        play_start = 0;
        i = 0;
      } else {
        /*  Transfer  */
        sdMemBlkSetPrm( mem_blk, ( void *)( src_adr + i++ * 0x400 ), 0x1000, dummy_, NULL);
        if ( sdPstmTransferWaveData( *hndl, 0, mem_blk) != SDE_ERR_NOTHING ) PrgStop();
      }
      sdMemBlkDestroy( mem_blk );
    }
  } else i = 0;
}

void SoundInit() {
  GDFS    fd;
  Uint32  size;
  Uint32  *addr;

  SoundInitialize( "MANATEE.DRV", "STREAM.MLT" );

  /* Load Stream data to memory */
  fd = gdFsOpen( "STREAM.DAT", NULL );
  {
    gdFsGetFileSize( fd, &src_size );
    size = AttachSector( src_size );
    src_adr = ( Uint32 * )syMalloc( size * sizeof( char ) );

    /* Read file after cenvert filesize to sector size */
    gdFsRead( fd, size / 2048, src_adr );
  }
  gdFsClose( fd );
}

void SoundMain( PDS_PERIPHERAL *pad, SDPSTM  *pcm_stm_handle ) {
  char *mes[] = { "STOP", "PLAY" };

  if ( pad->press & PDD_DGT_ST ) {
    if ( play_start == 0 ) {
      /* Open PCM Stream Port */
      if ( sdPstmOpenPort( pcm_stm_handle, 1, 0) != SDE_ERR_NOTHING ) PrgStop();
      sdPstmSetBaseVol( *pcm_stm_handle, 0x7F);
     if ( sdPstmPlay( *pcm_stm_handle, SDE_PCM_TYPE_16BIT_PCM, SDD_PSTM_FREQ_22050, 0) != SDE_ERR_NOTHING ) PrgStop();
      play_start = 1;
    } else {
      sdPstmStop( *pcm_stm_handle);
      sdPstmClosePort( *pcm_stm_handle );
      njWaitVSync();
      play_start = 0;
    }
  }
  njPrintC( NJM_LOCATION( 10, 7 ), mes[ play_start ] );
}

void main(void)
{
  Int            y = 0, x = 0;
  static Sint32  i = 0;
  PDS_PERIPHERAL *pad;
  SDPSTM         pcm_stm_handle;

  /* Initialize System */
  njSetBorderColor( 0x00000000 );
#ifdef VGA
  sbInitSystem( NJD_RESOLUTION_VGA, NJD_FRAMEBUFFER_MODE_RGB565, 1 );
#else
  sbInitSystem( NJD_RESOLUTION_320x240_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1 );
#endif

  njInitVertexBuffer( 10000, 0, 10000, 0, 0 );
  njInitPrint( NULL, 0, NJD_TEXFMT_ARGB_1555 );
  njSetBackColor( 0x00000000, 0x00000000, 0x000000FF );

  SoundInit();

  while ( 1 ) {
    pad = pdGetPeripheral( PDD_PORT_A0 );
    njPrintC( NJM_LOCATION( 10, 3 ), "PCM Stream Test" );
    njPrintH( NJM_LOCATION( 0, 5 ), i++, 8 );
    SoundLibVer( 4, 11 );
    SoundDrvVer( 4, 12 );
    SoundDrvStat( 4, 13 );

    SoundMain( pad, &pcm_stm_handle );

    UserVBlankIn( &pcm_stm_handle );
    njWaitVSync();
  }
}

/******************************* end of file *******************************/
