/*	
 *	clipvgm.c
 *
 *	P/ECE VGM Driver
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Mon Jan 12 18:00:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#include "clip.h"

/****************************************************************************
 *	VGMドライバ内部関数
 ****************************************************************************/

int
vgm_init(VGMDRIVER* vgm, const char* fname)
{
	int retval;
	VGMHEADER* header = &vgm->header;
	SN76489* sn76489 = &vgm->sn76489;

	/* まずクリア。 */
	memset(vgm, 0, sizeof(VGMDRIVER));

	/* VGM/VGZファイルを開きます。
	 * 非圧縮VGM形式の場合はgzio関数群が透過してくれるので、区別不要です。
	 */
	vgm->file = gzopen(fname, "rb");
	if(!vgm->file) goto L_ERR;

	/* VGMファイルヘッダを読み込みます。 */
	retval = gzread(vgm->file, header, sizeof(VGMHEADER));
	if(retval != sizeof(VGMHEADER)) goto L_ERR;

	/* シグネチャ検査。 */
	if(memcmp(header->signature, "Vgm ", 4) != 0) goto L_ERR;

	/* SN76489リセット。 */
	if(!header->psg_clock) goto L_ERR; /* PSGサウンドなし? */
	sn76489_reset(sn76489, header->psg_clock);

	/* 進行カウンタリセット。 */
	vgm->progress = -VGMSAMPLERATE;

	return 0; /* 成功 */
L_ERR:
	vgm_free(vgm);
	return -1; /* 失敗 */
}

void
vgm_free(VGMDRIVER* vgm)
{
	/* 確実にgzipストリームを閉じます。 */
	if(vgm->file) {
		gzclose(vgm->file);
		vgm->file = NULL;
	}
}

int
vgm_stream_callback(short* wbuff, int param)
{
	return vgm_mix((VGMDRIVER*)param, wbuff);
}

/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/

static VGMDRIVER g_vgm; /* STATICです! */

int
vgm_play(const char* fname)
{
	/* まず確実に停止します。 */
	vgm_stop();

	/* VGMドライバを初期化します。 */
	if(vgm_init(&g_vgm, fname) != 0) return -1;

	/* ストリーム再生を開始します。 */
	stream_play(VGMBUFLEN, vgm_stream_callback, (int)&g_vgm, 0);

	return 0;
}

void
vgm_stop()
{
	/* ストリーム再生を停止します。 */
	stream_stop();

	/* VGMドライバをクリーンアップします。(必要!!) */
	vgm_free(&g_vgm);
}

