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

#include <Shinobi.h>
#include <nindows.h>

#include <sg_mw.h>

/*	ミドルウェア再生ハンドル	*/
MWPLY ply=NULL;
/*	Teapot 表示スイッチ	*/
Sint32 disp_flag=1;

extern Uint16 T009[];

#define OBJECT  object_tea_Teapot1_Teapot1
extern NJS_OBJECT OBJECT[];

NJS_TEXNAME texname[1];
NJS_TEXLIST tlist1 = {texname,1};
NJS_TEXINFO info;

extern NJS_MATRIX   matrix[8];
extern NJS_VERTEX_BUF   vbuf[4096];

NJS_TEXMEMLIST  tex[10];

NJS_VIEW    view;
NJS_LIGHT   light;

Sint32  xx,yy,zz = 0;

Uint32 count = 0;

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

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

/*	データの読み込み	*/
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;
}

#include	<stdarg.h>

/*	メッセージ出力	*/
long njPrintf(long lx, long ly, char *fmt,...)
{
    va_list args;
    static char buf[256];
    long ret, pos;

	memset(buf, 0, sizeof(buf));
    va_start(args, fmt);
    ret = vsprintf(buf, fmt, args);
    va_end(args);
    pos = NJM_LOCATION(lx, ly);
	njPrintC(pos, buf);

    return ret;
}

/* サウンドドライバの転送・初期化 */
Void SoundInit(Void *ptr)
{
	SDMEMBLK	memblk = NULL;

	/*	Initialize Sound library	 */
	sdLibInit(NULL, 0, 0);		/*	This api's argument is dummy now.  */

	/* 	Download and Initialize Sound driver.	 */
	/*	Create Memory block handle  */
	sdMemBlkCreate(&memblk);
	/*  Setting Memoby block handle  */
	sdMemBlkSetPrm(memblk, ptr, 0, SDD_MEMBLK_SYNC_FUNC, NULL);
	/*	Initialize Sound driver  */
	sdDrvInit(memblk);
	sdMemBlkDestroy(memblk);
}

/* 再生するSFDファイル */
char *fname[] = {
	"SAMPLE.SFD",
};
long file_no=0;								/* ファイル番号					*/
long nfiles=sizeof(fname)/sizeof(char *);	/* ファイル数					*/
MWS_PLY_CPRM_SFD cprm;						/* ハンドル生成パラメータ構造体 */

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

void njUserInit(void)
{
	void *snddrv;

	/*	ミドルウェアのためのシステム初期化 (sbInitSystemの前に置く)　*/
	mwPlyPreInitSofdec();

	/*	忍ライブラリの初期化				*/
    njSetBorderColor( 0x00000000 ) ;
    sbInitSystem( NJD_RESOLUTION_640x480_NTSCI, NJD_FRAMEBUFFER_MODE_RGB555,1);
    njInitVertexBuffer( 800000, 0, 200000, 0 ,0);
    njInitPrint(NULL, 0, 0);
    njInitMatrix( matrix, 8 , 0);
    njInit3D( vbuf, 4096 );
    njInitView( &view );
    njCreateLight( &light, NJD_PHONG_DIR );
    njSetLightIntensity( &light, 1.5f, 1.0f, 0.7f );
    njSetLightAngle( &light, NJM_RAD_ANG(NJD_PI / 30.f),
    											NJM_RAD_ANG(NJD_PI / 4.f) );
    njSetLightDirection( &light, 0, 0.707f, -0.707f );
    njSetView( &view );
    njInitTexture( tex, 10 );
    nwInitSystem(10,NJD_PORT_A0);
    njSetTextureInfo(&info,
    					T009,NJD_TEXFMT_RGB_565|NJD_TEXFMT_TWIDDLED,128,128);
    njSetTextureName(&texname[0],&info, 0, 
    						NJD_TEXATTR_TYPE_MEMORY|NJD_TEXATTR_GLOBALINDEX);
    njLoadTexture( &tlist1 );
    njSetTexture( &tlist1 );
    njControl3D( NJD_CONTROL_3D_CONSTANT_ATTR );
    njSetConstantAttr( 0xffffffff,
    			NJD_FLAG_USE_TEXTURE | NJD_FLAG_USE_ENV|NJD_FILTER_BILINEAR);
    njSetBackColor(0x00000000,0x00000000,0x000000FF);
    njPrintSize(16);
	njSetVSyncFunction(usrVsyncFunc);

	/*	サウンドライブラリの準備 */
	snddrv = load_file("manatee.drv", NULL);
	SoundInit(snddrv);

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

	/*	ミドルウェアの初期化	*/
	mwPlyInitSofdec(NULL);
    /*	ハンドルの生成	*/
    cprm.ftype	= MWD_PLY_FTYPE_SFD;
    cprm.dtype	= MWD_PLY_DTYPE_FULL;
    cprm.work   = syMalloc(MWD_SFD_SIZE_WORK);
    cprm.wksize = MWD_SFD_SIZE_WORK;
	ply = mwPlyCreateSofdec(&cprm);
	/*	高速処理の指定	*/
	mwPlySetFastHalfpel(ply, 1);
	/*	再生開始	*/
	mwPlyStartFname(ply, fname[file_no]);
}

Sint32 njUserMain(void)
{
	const NJS_PERIPHERAL	*per;
    MWE_PLY_STAT			stat;

	mwPlyStartFrame();
   	per = njGetPeripheral(NJD_PORT_A0);
   	/*	次のムービーへ		*/
	if (per->press & NJD_DGT_ST) {
		file_no = (file_no+1) % nfiles;
		mwPlyStop(ply);
		mwPlyDestroy(ply);
		ply = mwPlyCreateSofdec(&cprm);
		mwPlyStartFname(ply, fname[file_no]);
	}
	/*	Teapotの表示　ON/OFF	*/
	if (per->press & NJD_DGT_TX)
		disp_flag = (disp_flag == 0) ? 1 : 0;

	/*	再生終了	*/
	stat = mwPlyGetStat(ply);
	if ( (stat == MWE_PLY_STAT_PLAYEND) || (stat == MWE_PLY_STAT_ERROR) ) {
		file_no = (file_no+1) % nfiles;
		mwPlyStop(ply);
		mwPlyDestroy(ply);
		ply = mwPlyCreateSofdec(&cprm);
		mwPlyStartFname(ply, fname[file_no]);
	}

	/* Teapotの表示処理 */
    njClearMatrix();
    njTranslate( NULL, 0.f, 0.f, -12.f );
    njRotateXYZ( NULL, xx,yy,zz );
    if ( disp_flag )
	    njDrawObject( OBJECT );
    xx += 257;
    yy += 179;
    zz += 193;
    njPrintD(NJM_LOCATION(2,3),count,8);

	/* ミドルウェアのサーバ関数 */
	mwPlyExecServer();

	return nwExecute();
}
    

void njUserExit(void)
{
	mwPlyFinishSofdec();
    nwExitSystem();
    njExitPrint();
    njExitTexture();
    sbExitSystem();
	syBtExit();
}

