/*
 *  Middleware Library
 *  Copyright (c) 1998 SEGA
 *  
 *		Middleware Wave Player Sample
 *
 *  Module  : Sample Program
 *  File    : test.c
 *  Create  : 1998-09-16
 *  Modify  : 1998-10-27
 *  Version : 1.02
 *  Note    : トレイオープンチェックルーチンを追加。
 */

#include	<machine.h>
#include	<shinobi.h>
#include	<sg_mw.h>


/*	サウンドライブラリ初期化			*/
void initSnd(void *ptr)
{
	SDMEMBLK	memblk = NULL;

	/*	サウンドライブラリ初期化				*/
	/*	実引数はダミー							*/
	sdLibInit(NULL, 0, 0);
	/*	メモリブロックハンドル生成				*/
	sdMemBlkCreate(&memblk);
	/*	メモリブロックハンドル設定				*/
	sdMemBlkSetPrm(memblk, ptr, 0, SDD_MEMBLK_SYNC_FUNC, NULL);
	/*	サウンドドライバ初期化					*/
	sdDrvInit(memblk);
	/*	メモリブロック解放						*/
	sdMemBlkDestroy(memblk);
}

/* ファイルロード */
void *load_file(char *fname, long *len)
{
	GDFS gdfs;
	long fsize, nsct;
	void *dat=NULL;

	if ( (gdfs=gdFsOpen(fname, NULL)) == NULL )
		for (;;);
	gdFsGetFileSize(gdfs, &fsize);
	nsct = (fsize+2047)/2048;
	if ( (dat=syMalloc(nsct*2048)) != NULL ) {
		gdFsRead(gdfs, nsct, dat);
	}
	gdFsClose(gdfs);
	if ( len != NULL )
		*len = fsize;

	return dat;
}

/* サウンドライブラリ・ドライバのバージョン取得 */
void getVer(Sint32 *drvver, Sint32 *libver)
{
	Sint32	tmp;
	SDS_VER drv_ver, lib_ver;

	sdDrvGetVer(&drv_ver);
	sdLibGetVer(&lib_ver);

	tmp = (Sint32)(drv_ver.m_MajorVer);
	*drvver = tmp << 16;
	tmp = (Sint32)drv_ver.m_MinorVer;
	*drvver |= tmp << 8;
	*drvver |= (Sint32)drv_ver.m_DebugVer;

	tmp = (Sint32)(lib_ver.m_MajorVer);
	*libver = tmp << 16;
	tmp = (Sint32)lib_ver.m_MinorVer;
	*libver |= tmp << 8;
	*libver |= (Sint32)lib_ver.m_DebugVer;
	return;
}

/*	サンプルプログラムの情報表示		*/
void showSmpInfo(Uint32 cnt, Sint32 drvver, Sint32 libver)
{
	njPrint(NJM_LOCATION( 5,  2), "[Wave Decoder]");
	njPrint(NJM_LOCATION( 5,  4), "Snd Drv   : %06x", drvver);
	njPrint(NJM_LOCATION( 5,  5), "Snd Lib   : %06x", libver);
	njPrint(NJM_LOCATION( 5,  6), "Prg Cnt   : %d", cnt);
	njPrint(NJM_LOCATION( 5,  8), "File Name : SAMPLE.WAV");
	return;
}

void sfcnt2time(long sf, long ncnt, long *hh, long *mm, long *ss, long *ff)
{
	register long nf = (long)((double)ncnt/(double)sf*100.0);

	*hh = nf/(60*60*100);
	*mm = nf/(60*100) - *hh*60;
	*ss = nf/100 - *hh*60*60 - *mm*60;
	*ff = nf%100;
}

/*	再生状態の表示						*/
void showStat(MWPLY ply)
{
	Sint32	stat, tscl, cnt;
	Sint32	hh, mm, ss, ff;
	Sint8	*strstat[5] = {"STOP","PREP","EXEC","END ","ERROR"};

	hh = mm = ss = ff = 0;
	stat = mwPlyGetStat(ply);
	mwPlyGetTime(ply, &cnt, &tscl);
	sfcnt2time(tscl, cnt, &hh, &mm, &ss, &ff);
	njPrint(NJM_LOCATION( 5,  9), "Frequency : %d", tscl);
	njPrint(NJM_LOCATION( 5, 10), "Status    : %s", strstat[stat]);
	njPrint(NJM_LOCATION( 5, 11), "Time      : %02d:%02d.%02d", mm, ss, ff);
	return;
}

/* エラー発生回数 */
Sint32	errcnt;

/* エラー発生時に起動する関数 */
static void errFunc(void *obj, Sint32 ecode)
{
    /* エラーコードのチェック */
    if (ecode != MWD_PLY_ERR_OK) {
		errcnt++;
    }
}

/* GDファイルシステムのエラー発生時に起動する関数 */
void usrGdErrFunc(void *obj, Sint32 errcode)
{
	if (errcode == GDD_ERR_TRAYOPEND || errcode == GDD_ERR_UNITATTENT) {
		/*	ライブラリ終了処理					*/
		mwPlyFinishWav();
		/*	忍ライブラリの終了処理				*/
		sbExitSystem();
		/*	シンプルプレイヤへジャンプ			*/
		syBtExit();
 	}
 	return;
}

/* ユーザのVSYNC割り込み登録関数 */
static void usrVsyncFunc(void)
{
	Sint32 dstat;

    /* サウンドライブラリのサーバ */
    sdSysServer();
	/* GDドライブの状態チェック */
	dstat = gdFsGetDrvStat();
	if (dstat == GDD_DRVSTAT_OPEN || dstat == GDD_DRVSTAT_BUSY) {
		gdFsReqDrvStat();
	}
	return;
}

void	main(void)
{
	MWPLY				mwply;
	MWS_PLY_CPRM_WAV	cprm;
	void				*snddrv;
	Sint32				stat;
	Uint32				cnt;
	Sint32				drvver, libver;

	/*	忍ライブラリの初期化				*/
    njSetBorderColor(0x00000000) ;
	sbInitSystem(NJD_RESOLUTION_320x240_NTSCNI,NJD_FRAMEBUFFER_MODE_RGB565,1);
	njInitVertexBuffer(10000, 0, 10000, 0, 0);
    njInitPrint(NULL, 0, 0);
	njSetBackColor(0x00000000, 0x00000000, 0x000000FF);

	/*	サウンドドライバの読み込み			*/
	snddrv = load_file("MANATEE.DRV", NULL);
	/*	サウンドライブラリ初期化			*/
	initSnd(snddrv);
	getVer(&drvver, &libver);
	/*	サウンドのサーバ処理登録			*/
	njSetVSyncFunction((void *)usrVsyncFunc);
	sdMemBlkSetTransferMode(SDE_MEMBLK_TRANSFER_MODE_DMA);

	/* GDファイルシステムエラーコールバック関数の登録	*/
	gdFsEntryErrFuncAll((void *)usrGdErrFunc, NULL);

	/*	ミドルウェアライブラリ初期化		*/
	mwPlyInitWav(MWD_PLY_MN_EXEC_VSYNC);
	/*	エラー関数登録						*/
	mwPlyEntryErrFunc((void *)errFunc, NULL);
	/*	ハンドル生成						*/
	cprm.size  = MWD_PLY_ALLOC_SJBUF(MWD_PLY_ALLOC_LIMIT);
	cprm.buf = syMalloc(cprm.size);
	mwply = mwPlyCreateWav(&cprm);
	if (mwply == NULL)
		for (;;) ;

	/*	再生開始							*/
	mwPlyStartFname(mwply, "SAMPLE.WAV");
	for (cnt=0;;cnt++) {
		/*	サンプルプログラムの情報表示		*/
		showSmpInfo(cnt, drvver, libver);
		/*	再生状態の表示						*/
		showStat(mwply);
		/*	再生状態の確認						*/
		stat = mwPlyGetStat(mwply);
		if ((stat == MWE_PLY_STAT_PLAYEND) || (stat == MWE_PLY_STAT_ERROR)) {
			mwPlyStartFname(mwply, "SAMPLE.WAV");
		}
		/*	ミドルウェアのサーバ関数			*/
		mwPlyExecServer();

		njWaitVSync();
	}
	/*	再生停止							*/
	mwPlyStop(mwply);
	/*	ハンドル消去						*/
	mwPlyDestroy(mwply);
	syFree(cprm.buf);
	/*	ライブラリ終了処理					*/
	mwPlyFinishWav();
	njWaitVSync();
	njWaitVSync();
	njWaitVSync();
	/*	忍ライブラリの終了処理				*/
	sbExitSystem();
	syBtExit();
}
